1 /*
2 * Copyright © Microsoft Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "dzn_private.h"
25
26 #include "spirv_to_dxil.h"
27 #include "nir_to_dxil.h"
28
29 #include "dxil_nir.h"
30 #include "dxil_nir_lower_int_samplers.h"
31 #include "dxil_validator.h"
32
33 static void
dzn_meta_compile_shader(struct dzn_device * device,nir_shader * nir,D3D12_SHADER_BYTECODE * slot)34 dzn_meta_compile_shader(struct dzn_device *device, nir_shader *nir,
35 D3D12_SHADER_BYTECODE *slot)
36 {
37 struct dzn_instance *instance =
38 container_of(device->vk.physical->instance, struct dzn_instance, vk);
39
40 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
41
42 if ((instance->debug_flags & DZN_DEBUG_NIR) &&
43 (instance->debug_flags & DZN_DEBUG_INTERNAL))
44 nir_print_shader(nir, stderr);
45
46 struct nir_to_dxil_options opts = {
47 .environment = DXIL_ENVIRONMENT_VULKAN,
48 .shader_model_max = SHADER_MODEL_6_2,
49 #ifdef _WIN32
50 .validator_version_max = dxil_get_validator_version(instance->dxil_validator),
51 #endif
52 };
53 struct blob dxil_blob;
54 ASSERTED bool ret = nir_to_dxil(nir, &opts, &dxil_blob);
55 assert(ret);
56
57 #ifdef _WIN32
58 char *err = NULL;
59 bool res = dxil_validate_module(instance->dxil_validator,
60 dxil_blob.data,
61 dxil_blob.size, &err);
62
63 if ((instance->debug_flags & DZN_DEBUG_DXIL) &&
64 (instance->debug_flags & DZN_DEBUG_INTERNAL)) {
65 char *disasm = dxil_disasm_module(instance->dxil_validator,
66 dxil_blob.data,
67 dxil_blob.size);
68 if (disasm) {
69 fprintf(stderr,
70 "== BEGIN SHADER ============================================\n"
71 "%s\n"
72 "== END SHADER ==============================================\n",
73 disasm);
74 ralloc_free(disasm);
75 }
76 }
77
78 if ((instance->debug_flags & DZN_DEBUG_DXIL) &&
79 (instance->debug_flags & DZN_DEBUG_INTERNAL) &&
80 !res) {
81 fprintf(stderr,
82 "== VALIDATION ERROR =============================================\n"
83 "%s\n"
84 "== END ==========================================================\n",
85 err ? err : "unknown");
86 ralloc_free(err);
87 }
88 assert(res);
89 #endif
90
91 void *data;
92 size_t size;
93 blob_finish_get_buffer(&dxil_blob, &data, &size);
94 slot->pShaderBytecode = data;
95 slot->BytecodeLength = size;
96 }
97
98 #define DZN_META_INDIRECT_DRAW_MAX_PARAM_COUNT 5
99
100 static void
dzn_meta_indirect_draw_finish(struct dzn_device * device,enum dzn_indirect_draw_type type)101 dzn_meta_indirect_draw_finish(struct dzn_device *device, enum dzn_indirect_draw_type type)
102 {
103 struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type];
104
105 if (meta->root_sig)
106 ID3D12RootSignature_Release(meta->root_sig);
107
108 if (meta->pipeline_state)
109 ID3D12PipelineState_Release(meta->pipeline_state);
110 }
111
112 static VkResult
dzn_meta_indirect_draw_init(struct dzn_device * device,enum dzn_indirect_draw_type type)113 dzn_meta_indirect_draw_init(struct dzn_device *device,
114 enum dzn_indirect_draw_type type)
115 {
116 struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type];
117 struct dzn_instance *instance =
118 container_of(device->vk.physical->instance, struct dzn_instance, vk);
119 VkResult ret = VK_SUCCESS;
120
121 glsl_type_singleton_init_or_ref();
122
123 nir_shader *nir = dzn_nir_indirect_draw_shader(type);
124 bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN ||
125 type == DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN ||
126 type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN ||
127 type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
128 type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
129 type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
130 bool indirect_count = type == DZN_INDIRECT_DRAW_COUNT ||
131 type == DZN_INDIRECT_INDEXED_DRAW_COUNT ||
132 type == DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN ||
133 type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
134 type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
135 bool prim_restart = type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
136 type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
137 uint32_t shader_params_size =
138 triangle_fan && prim_restart ?
139 sizeof(struct dzn_indirect_draw_triangle_fan_prim_restart_rewrite_params) :
140 triangle_fan ?
141 sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params) :
142 sizeof(struct dzn_indirect_draw_rewrite_params);
143
144 uint32_t root_param_count = 0;
145 D3D12_ROOT_PARAMETER1 root_params[DZN_META_INDIRECT_DRAW_MAX_PARAM_COUNT];
146
147 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
148 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
149 .Constants = {
150 .ShaderRegister = 0,
151 .RegisterSpace = 0,
152 .Num32BitValues = shader_params_size / 4,
153 },
154 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
155 };
156
157 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
158 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
159 .Descriptor = {
160 .ShaderRegister = 1,
161 .RegisterSpace = 0,
162 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
163 },
164 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
165 };
166
167 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
168 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
169 .Descriptor = {
170 .ShaderRegister = 2,
171 .RegisterSpace = 0,
172 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
173 },
174 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
175 };
176
177 if (indirect_count) {
178 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
179 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
180 .Descriptor = {
181 .ShaderRegister = 3,
182 .RegisterSpace = 0,
183 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
184 },
185 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
186 };
187 }
188
189
190 if (triangle_fan) {
191 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
192 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
193 .Descriptor = {
194 .ShaderRegister = 4,
195 .RegisterSpace = 0,
196 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
197 },
198 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
199 };
200 }
201
202 assert(root_param_count <= ARRAY_SIZE(root_params));
203
204 D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
205 .Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
206 .Desc_1_1 = {
207 .NumParameters = root_param_count,
208 .pParameters = root_params,
209 .Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
210 },
211 };
212
213 D3D12_COMPUTE_PIPELINE_STATE_DESC desc = {
214 .Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
215 };
216
217 meta->root_sig =
218 dzn_device_create_root_sig(device, &root_sig_desc);
219 if (!meta->root_sig) {
220 ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
221 goto out;
222 }
223
224 desc.pRootSignature = meta->root_sig;
225 dzn_meta_compile_shader(device, nir, &desc.CS);
226 assert(desc.CS.pShaderBytecode);
227
228 if (FAILED(ID3D12Device1_CreateComputePipelineState(device->dev, &desc,
229 &IID_ID3D12PipelineState,
230 (void **)&meta->pipeline_state)))
231 ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
232
233 out:
234 if (ret != VK_SUCCESS)
235 dzn_meta_indirect_draw_finish(device, type);
236
237 free((void *)desc.CS.pShaderBytecode);
238 ralloc_free(nir);
239 glsl_type_singleton_decref();
240
241 return ret;
242 }
243
244 #define DZN_META_TRIANGLE_FAN_REWRITE_IDX_MAX_PARAM_COUNT 4
245
246 static void
dzn_meta_triangle_fan_rewrite_index_finish(struct dzn_device * device,enum dzn_index_type old_index_type)247 dzn_meta_triangle_fan_rewrite_index_finish(struct dzn_device *device,
248 enum dzn_index_type old_index_type)
249 {
250 struct dzn_meta_triangle_fan_rewrite_index *meta =
251 &device->triangle_fan[old_index_type];
252
253 if (meta->root_sig)
254 ID3D12RootSignature_Release(meta->root_sig);
255 if (meta->pipeline_state)
256 ID3D12PipelineState_Release(meta->pipeline_state);
257 if (meta->cmd_sig)
258 ID3D12CommandSignature_Release(meta->cmd_sig);
259 }
260
261 static VkResult
dzn_meta_triangle_fan_rewrite_index_init(struct dzn_device * device,enum dzn_index_type old_index_type)262 dzn_meta_triangle_fan_rewrite_index_init(struct dzn_device *device,
263 enum dzn_index_type old_index_type)
264 {
265 struct dzn_meta_triangle_fan_rewrite_index *meta =
266 &device->triangle_fan[old_index_type];
267 struct dzn_instance *instance =
268 container_of(device->vk.physical->instance, struct dzn_instance, vk);
269 VkResult ret = VK_SUCCESS;
270
271 glsl_type_singleton_init_or_ref();
272
273 uint8_t old_index_size = dzn_index_size(old_index_type);
274 bool prim_restart =
275 old_index_type == DZN_INDEX_2B_WITH_PRIM_RESTART ||
276 old_index_type == DZN_INDEX_4B_WITH_PRIM_RESTART;
277
278 nir_shader *nir =
279 prim_restart ?
280 dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(old_index_size) :
281 dzn_nir_triangle_fan_rewrite_index_shader(old_index_size);
282
283 uint32_t root_param_count = 0;
284 D3D12_ROOT_PARAMETER1 root_params[DZN_META_TRIANGLE_FAN_REWRITE_IDX_MAX_PARAM_COUNT];
285
286 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
287 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
288 .Descriptor = {
289 .ShaderRegister = 1,
290 .RegisterSpace = 0,
291 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
292 },
293 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
294 };
295
296 uint32_t params_size =
297 prim_restart ?
298 sizeof(struct dzn_triangle_fan_prim_restart_rewrite_index_params) :
299 sizeof(struct dzn_triangle_fan_rewrite_index_params);
300
301 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
302 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
303 .Constants = {
304 .ShaderRegister = 0,
305 .RegisterSpace = 0,
306 .Num32BitValues = params_size / 4,
307 },
308 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
309 };
310
311 if (old_index_type != DZN_NO_INDEX) {
312 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
313 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
314 .Descriptor = {
315 .ShaderRegister = 2,
316 .RegisterSpace = 0,
317 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
318 },
319 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
320 };
321 }
322
323 if (prim_restart) {
324 root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
325 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
326 .Descriptor = {
327 .ShaderRegister = 3,
328 .RegisterSpace = 0,
329 .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
330 },
331 .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
332 };
333 }
334
335 assert(root_param_count <= ARRAY_SIZE(root_params));
336
337 D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
338 .Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
339 .Desc_1_1 = {
340 .NumParameters = root_param_count,
341 .pParameters = root_params,
342 .Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
343 },
344 };
345
346 D3D12_COMPUTE_PIPELINE_STATE_DESC desc = {
347 .Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
348 };
349
350 uint32_t cmd_arg_count = 0;
351 D3D12_INDIRECT_ARGUMENT_DESC cmd_args[4];
352
353 cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
354 .Type = D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
355 .UnorderedAccessView = {
356 .RootParameterIndex = 0,
357 },
358 };
359
360 cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
361 .Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
362 .Constant = {
363 .RootParameterIndex = 1,
364 .DestOffsetIn32BitValues = 0,
365 .Num32BitValuesToSet = params_size / 4,
366 },
367 };
368
369 if (prim_restart) {
370 cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
371 .Type = D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
372 .UnorderedAccessView = {
373 .RootParameterIndex = 3,
374 },
375 };
376 }
377
378 cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
379 .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH,
380 };
381
382 assert(cmd_arg_count <= ARRAY_SIZE(cmd_args));
383
384 uint32_t exec_params_size =
385 prim_restart ?
386 sizeof(struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params) :
387 sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params);
388
389 D3D12_COMMAND_SIGNATURE_DESC cmd_sig_desc = {
390 .ByteStride = exec_params_size,
391 .NumArgumentDescs = cmd_arg_count,
392 .pArgumentDescs = cmd_args,
393 };
394
395 assert((cmd_sig_desc.ByteStride & 7) == 0);
396
397 meta->root_sig = dzn_device_create_root_sig(device, &root_sig_desc);
398 if (!meta->root_sig) {
399 ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
400 goto out;
401 }
402
403
404 desc.pRootSignature = meta->root_sig;
405 dzn_meta_compile_shader(device, nir, &desc.CS);
406
407 if (FAILED(ID3D12Device1_CreateComputePipelineState(device->dev, &desc,
408 &IID_ID3D12PipelineState,
409 (void **)&meta->pipeline_state))) {
410 ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
411 goto out;
412 }
413
414 if (FAILED(ID3D12Device1_CreateCommandSignature(device->dev, &cmd_sig_desc,
415 meta->root_sig,
416 &IID_ID3D12CommandSignature,
417 (void **)&meta->cmd_sig)))
418 ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
419
420 out:
421 if (ret != VK_SUCCESS)
422 dzn_meta_triangle_fan_rewrite_index_finish(device, old_index_type);
423
424 free((void *)desc.CS.pShaderBytecode);
425 ralloc_free(nir);
426 glsl_type_singleton_decref();
427
428 return ret;
429 }
430
431 static const D3D12_SHADER_BYTECODE *
dzn_meta_blits_get_vs(struct dzn_device * device)432 dzn_meta_blits_get_vs(struct dzn_device *device)
433 {
434 struct dzn_meta_blits *meta = &device->blits;
435
436 mtx_lock(&meta->shaders_lock);
437
438 if (meta->vs.pShaderBytecode == NULL) {
439 nir_shader *nir = dzn_nir_blit_vs();
440
441 NIR_PASS_V(nir, nir_lower_system_values);
442
443 gl_system_value system_values[] = {
444 SYSTEM_VALUE_FIRST_VERTEX,
445 SYSTEM_VALUE_BASE_VERTEX,
446 };
447
448 NIR_PASS_V(nir, dxil_nir_lower_system_values_to_zero, system_values,
449 ARRAY_SIZE(system_values));
450
451 D3D12_SHADER_BYTECODE bc;
452
453 dzn_meta_compile_shader(device, nir, &bc);
454 meta->vs.pShaderBytecode =
455 vk_alloc(&device->vk.alloc, bc.BytecodeLength, 8,
456 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
457 if (meta->vs.pShaderBytecode) {
458 meta->vs.BytecodeLength = bc.BytecodeLength;
459 memcpy((void *)meta->vs.pShaderBytecode, bc.pShaderBytecode, bc.BytecodeLength);
460 }
461 free((void *)bc.pShaderBytecode);
462 ralloc_free(nir);
463 }
464
465 mtx_unlock(&meta->shaders_lock);
466
467 return &meta->vs;
468 }
469
470 static const D3D12_SHADER_BYTECODE *
dzn_meta_blits_get_fs(struct dzn_device * device,const struct dzn_nir_blit_info * info)471 dzn_meta_blits_get_fs(struct dzn_device *device,
472 const struct dzn_nir_blit_info *info)
473 {
474 struct dzn_meta_blits *meta = &device->blits;
475 D3D12_SHADER_BYTECODE *out = NULL;
476
477 mtx_lock(&meta->shaders_lock);
478
479 STATIC_ASSERT(sizeof(struct dzn_nir_blit_info) == sizeof(uint32_t));
480
481 struct hash_entry *he =
482 _mesa_hash_table_search(meta->fs, (void *)(uintptr_t)info->hash_key);
483
484 if (!he) {
485 nir_shader *nir = dzn_nir_blit_fs(info);
486
487 if (info->out_type != GLSL_TYPE_FLOAT) {
488 dxil_wrap_sampler_state wrap_state = {
489 .is_int_sampler = 1,
490 .is_linear_filtering = 0,
491 .skip_boundary_conditions = 1,
492 };
493 dxil_lower_sample_to_txf_for_integer_tex(nir, &wrap_state, NULL, 0);
494 }
495
496 D3D12_SHADER_BYTECODE bc;
497
498 dzn_meta_compile_shader(device, nir, &bc);
499
500 out = vk_alloc(&device->vk.alloc,
501 sizeof(D3D12_SHADER_BYTECODE) + bc.BytecodeLength, 8,
502 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
503 if (out) {
504 out->pShaderBytecode = out + 1;
505 memcpy((void *)out->pShaderBytecode, bc.pShaderBytecode, bc.BytecodeLength);
506 out->BytecodeLength = bc.BytecodeLength;
507 _mesa_hash_table_insert(meta->fs, &info->hash_key, out);
508 }
509 free((void *)bc.pShaderBytecode);
510 ralloc_free(nir);
511 } else {
512 out = he->data;
513 }
514
515 mtx_unlock(&meta->shaders_lock);
516
517 return out;
518 }
519
520 static void
dzn_meta_blit_destroy(struct dzn_device * device,struct dzn_meta_blit * blit)521 dzn_meta_blit_destroy(struct dzn_device *device, struct dzn_meta_blit *blit)
522 {
523 if (!blit)
524 return;
525
526 if (blit->root_sig)
527 ID3D12RootSignature_Release(blit->root_sig);
528 if (blit->pipeline_state)
529 ID3D12PipelineState_Release(blit->pipeline_state);
530
531 vk_free(&device->vk.alloc, blit);
532 }
533
534 static struct dzn_meta_blit *
dzn_meta_blit_create(struct dzn_device * device,const struct dzn_meta_blit_key * key)535 dzn_meta_blit_create(struct dzn_device *device, const struct dzn_meta_blit_key *key)
536 {
537 struct dzn_meta_blit *blit =
538 vk_zalloc(&device->vk.alloc, sizeof(*blit), 8,
539 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
540
541 if (!blit)
542 return NULL;
543
544 D3D12_DESCRIPTOR_RANGE1 ranges[] = {
545 {
546 .RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
547 .NumDescriptors = 1,
548 .BaseShaderRegister = 0,
549 .RegisterSpace = 0,
550 .Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS,
551 .OffsetInDescriptorsFromTableStart = 0,
552 },
553 };
554
555 D3D12_STATIC_SAMPLER_DESC samplers[] = {
556 {
557 .Filter = key->linear_filter ?
558 D3D12_FILTER_MIN_MAG_MIP_LINEAR :
559 D3D12_FILTER_MIN_MAG_MIP_POINT,
560 .AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
561 .AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
562 .AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
563 .MipLODBias = 0,
564 .MaxAnisotropy = 0,
565 .MinLOD = 0,
566 .MaxLOD = D3D12_FLOAT32_MAX,
567 .ShaderRegister = 0,
568 .RegisterSpace = 0,
569 .ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
570 },
571 };
572
573 D3D12_ROOT_PARAMETER1 root_params[] = {
574 {
575 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
576 .DescriptorTable = {
577 .NumDescriptorRanges = ARRAY_SIZE(ranges),
578 .pDescriptorRanges = ranges,
579 },
580 .ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
581 },
582 {
583 .ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
584 .Constants = {
585 .ShaderRegister = 0,
586 .RegisterSpace = 0,
587 .Num32BitValues = 17,
588 },
589 .ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX,
590 },
591 };
592
593 D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
594 .Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
595 .Desc_1_1 = {
596 .NumParameters = ARRAY_SIZE(root_params),
597 .pParameters = root_params,
598 .NumStaticSamplers = ARRAY_SIZE(samplers),
599 .pStaticSamplers = samplers,
600 .Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
601 },
602 };
603
604 D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {
605 .SampleMask = key->resolve ? 1 : (1ULL << key->samples) - 1,
606 .RasterizerState = {
607 .FillMode = D3D12_FILL_MODE_SOLID,
608 .CullMode = D3D12_CULL_MODE_NONE,
609 .DepthClipEnable = TRUE,
610 },
611 .PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
612 .SampleDesc = {
613 .Count = key->resolve ? 1 : key->samples,
614 .Quality = 0,
615 },
616 .Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
617 };
618
619 struct dzn_nir_blit_info blit_fs_info = {
620 .src_samples = key->samples,
621 .loc = key->loc,
622 .out_type = key->out_type,
623 .sampler_dim = key->sampler_dim,
624 .src_is_array = key->src_is_array,
625 .resolve = key->resolve,
626 .padding = 0,
627 };
628
629 blit->root_sig = dzn_device_create_root_sig(device, &root_sig_desc);
630 if (!blit->root_sig) {
631 dzn_meta_blit_destroy(device, blit);
632 return NULL;
633 }
634
635 desc.pRootSignature = blit->root_sig;
636
637 const D3D12_SHADER_BYTECODE *vs, *fs;
638
639 vs = dzn_meta_blits_get_vs(device);
640 if (!vs) {
641 dzn_meta_blit_destroy(device, blit);
642 return NULL;
643 }
644
645 desc.VS = *vs;
646 assert(desc.VS.pShaderBytecode);
647
648 fs = dzn_meta_blits_get_fs(device, &blit_fs_info);
649 if (!fs) {
650 dzn_meta_blit_destroy(device, blit);
651 return NULL;
652 }
653
654 desc.PS = *fs;
655 assert(desc.PS.pShaderBytecode);
656
657 assert(key->loc == FRAG_RESULT_DATA0 ||
658 key->loc == FRAG_RESULT_DEPTH ||
659 key->loc == FRAG_RESULT_STENCIL);
660
661 if (key->loc == FRAG_RESULT_DATA0) {
662 desc.NumRenderTargets = 1;
663 desc.RTVFormats[0] = key->out_format;
664 desc.BlendState.RenderTarget[0].RenderTargetWriteMask = 0xf;
665 } else {
666 desc.DSVFormat = key->out_format;
667 if (key->loc == FRAG_RESULT_DEPTH) {
668 desc.DepthStencilState.DepthEnable = TRUE;
669 desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
670 desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
671 } else {
672 assert(key->loc == FRAG_RESULT_STENCIL);
673 desc.DepthStencilState.StencilEnable = TRUE;
674 desc.DepthStencilState.StencilWriteMask = 0xff;
675 desc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_REPLACE;
676 desc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_REPLACE;
677 desc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE;
678 desc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
679 desc.DepthStencilState.BackFace = desc.DepthStencilState.FrontFace;
680 }
681 }
682
683 if (FAILED(ID3D12Device1_CreateGraphicsPipelineState(device->dev, &desc,
684 &IID_ID3D12PipelineState,
685 (void **)&blit->pipeline_state))) {
686 dzn_meta_blit_destroy(device, blit);
687 return NULL;
688 }
689
690 return blit;
691 }
692
693 const struct dzn_meta_blit *
dzn_meta_blits_get_context(struct dzn_device * device,const struct dzn_meta_blit_key * key)694 dzn_meta_blits_get_context(struct dzn_device *device,
695 const struct dzn_meta_blit_key *key)
696 {
697 struct dzn_meta_blit *out = NULL;
698
699 STATIC_ASSERT(sizeof(*key) == sizeof(uint64_t));
700
701 mtx_lock(&device->blits.contexts_lock);
702
703 out =
704 _mesa_hash_table_u64_search(device->blits.contexts, key->u64);
705 if (!out) {
706 out = dzn_meta_blit_create(device, key);
707
708 if (out)
709 _mesa_hash_table_u64_insert(device->blits.contexts, key->u64, out);
710 }
711
712 mtx_unlock(&device->blits.contexts_lock);
713
714 return out;
715 }
716
717 static void
dzn_meta_blits_finish(struct dzn_device * device)718 dzn_meta_blits_finish(struct dzn_device *device)
719 {
720 struct dzn_meta_blits *meta = &device->blits;
721
722 vk_free(&device->vk.alloc, (void *)meta->vs.pShaderBytecode);
723
724 if (meta->fs) {
725 hash_table_foreach(meta->fs, he)
726 vk_free(&device->vk.alloc, he->data);
727 _mesa_hash_table_destroy(meta->fs, NULL);
728 }
729
730 if (meta->contexts) {
731 hash_table_foreach(meta->contexts->table, he)
732 dzn_meta_blit_destroy(device, he->data);
733 _mesa_hash_table_u64_destroy(meta->contexts);
734 }
735
736 mtx_destroy(&meta->shaders_lock);
737 mtx_destroy(&meta->contexts_lock);
738 }
739
740 static VkResult
dzn_meta_blits_init(struct dzn_device * device)741 dzn_meta_blits_init(struct dzn_device *device)
742 {
743 struct dzn_instance *instance =
744 container_of(device->vk.physical->instance, struct dzn_instance, vk);
745 struct dzn_meta_blits *meta = &device->blits;
746
747 mtx_init(&meta->shaders_lock, mtx_plain);
748 mtx_init(&meta->contexts_lock, mtx_plain);
749
750 meta->fs = _mesa_hash_table_create_u32_keys(NULL);
751 if (!meta->fs) {
752 dzn_meta_blits_finish(device);
753 return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
754 }
755
756 meta->contexts = _mesa_hash_table_u64_create(NULL);
757 if (!meta->contexts) {
758 dzn_meta_blits_finish(device);
759 return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
760 }
761
762 return VK_SUCCESS;
763 }
764
765 void
dzn_meta_finish(struct dzn_device * device)766 dzn_meta_finish(struct dzn_device *device)
767 {
768 for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++)
769 dzn_meta_triangle_fan_rewrite_index_finish(device, i);
770
771 for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++)
772 dzn_meta_indirect_draw_finish(device, i);
773
774 dzn_meta_blits_finish(device);
775 }
776
777 VkResult
dzn_meta_init(struct dzn_device * device)778 dzn_meta_init(struct dzn_device *device)
779 {
780 VkResult result = dzn_meta_blits_init(device);
781 if (result != VK_SUCCESS)
782 goto out;
783
784 for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++) {
785 VkResult result =
786 dzn_meta_indirect_draw_init(device, i);
787 if (result != VK_SUCCESS)
788 goto out;
789 }
790
791 for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++) {
792 VkResult result =
793 dzn_meta_triangle_fan_rewrite_index_init(device, i);
794 if (result != VK_SUCCESS)
795 goto out;
796 }
797
798 out:
799 if (result != VK_SUCCESS) {
800 dzn_meta_finish(device);
801 return result;
802 }
803
804 return VK_SUCCESS;
805 }
806