• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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