diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-03-21 15:00:37 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-09-14 16:48:23 +0300 |
commit | f0c82ae608ad98183f07c7ae04aa2a40ae119207 (patch) | |
tree | fd87617bc65e5c69f8e452506de5f293657370ca | |
parent | 143dc4d896fbaa02e79052a9ae0d73166d13dbf9 (diff) |
vkd3d: Separate compilation to SPIR-V and creation of VkShaderModule.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
-rw-r--r-- | libs/vkd3d/state.c | 141 |
1 files changed, 77 insertions, 64 deletions
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 415b60f4..eb4e7e9a 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1908,24 +1908,20 @@ static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_AddRef(ID3D12PipelineState * } static HRESULT d3d12_pipeline_state_create_shader_module(struct d3d12_device *device, - VkPipelineShaderStageCreateInfo *stage_desc, const struct vkd3d_shader_code *code) + VkShaderModule *vk_module, const struct vkd3d_shader_code *code) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; VkShaderModuleCreateInfo shader_desc; char hash_str[16 + 1]; VkResult vr; - /* If we kept the module around, no need to create it again. */ - if (stage_desc->module != VK_NULL_HANDLE) - return S_OK; - shader_desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shader_desc.pNext = NULL; shader_desc.flags = 0; shader_desc.codeSize = code->size; shader_desc.pCode = code->code; - vr = VK_CALL(vkCreateShaderModule(device->vk_device, &shader_desc, NULL, &stage_desc->module)); + vr = VK_CALL(vkCreateShaderModule(device->vk_device, &shader_desc, NULL, vk_module)); if (vr < 0) { WARN("Failed to create Vulkan shader module, vr %d.\n", vr); @@ -1934,7 +1930,7 @@ static HRESULT d3d12_pipeline_state_create_shader_module(struct d3d12_device *de /* Helpful for tooling like RenderDoc. */ sprintf(hash_str, "%016"PRIx64, code->meta.hash); - vkd3d_set_vk_object_name(device, (uint64_t)stage_desc->module, VK_OBJECT_TYPE_SHADER_MODULE, hash_str); + vkd3d_set_vk_object_name(device, (uint64_t)*vk_module, VK_OBJECT_TYPE_SHADER_MODULE, hash_str); return S_OK; } @@ -2308,62 +2304,18 @@ static void d3d12_pipeline_state_init_compile_arguments(struct d3d12_pipeline_st } } -static HRESULT vkd3d_create_shader_stage(struct d3d12_pipeline_state *state, struct d3d12_device *device, +static HRESULT vkd3d_setup_shader_stage(struct d3d12_pipeline_state *state, struct d3d12_device *device, VkPipelineShaderStageCreateInfo *stage_desc, VkShaderStageFlagBits stage, VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *required_subgroup_size_info, - const D3D12_SHADER_BYTECODE *code, struct vkd3d_shader_code *spirv_code) + const struct vkd3d_shader_code *spirv_code) { - struct vkd3d_shader_code dxbc = {code->pShaderBytecode, code->BytecodeLength}; - struct vkd3d_shader_interface_info shader_interface; - struct vkd3d_shader_compile_arguments compile_args; - vkd3d_shader_hash_t recovered_hash = 0; - vkd3d_shader_hash_t compiled_hash = 0; - int ret; - stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage_desc->pNext = NULL; stage_desc->flags = 0; stage_desc->stage = stage; stage_desc->pName = "main"; stage_desc->pSpecializationInfo = NULL; - - if (spirv_code->code && (vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_SANITIZE_SPIRV)) - { - recovered_hash = vkd3d_shader_hash(spirv_code); - vkd3d_shader_free_shader_code(spirv_code); - memset(spirv_code, 0, sizeof(*spirv_code)); - } - - if (!spirv_code->code) - { - TRACE("Calling vkd3d_shader_compile_dxbc.\n"); - - d3d12_pipeline_state_init_shader_interface(state, device, stage, &shader_interface); - d3d12_pipeline_state_init_compile_arguments(state, device, stage, &compile_args); - - if ((ret = vkd3d_shader_compile_dxbc(&dxbc, spirv_code, 0, &shader_interface, &compile_args)) < 0) - { - WARN("Failed to compile shader, vkd3d result %d.\n", ret); - return hresult_from_vkd3d_result(ret); - } - TRACE("Called vkd3d_shader_compile_dxbc.\n"); - - if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) - { - /* At this point we don't need the map anymore. */ - vkd3d_shader_stage_io_map_free(&state->graphics.cached_desc.stage_io_map_ms_ps); - } - } - - /* Debug compare SPIR-V we got from cache, and SPIR-V we got from compilation. */ - if (recovered_hash) - { - compiled_hash = vkd3d_shader_hash(spirv_code); - if (compiled_hash == recovered_hash) - INFO("SPIR-V match for cache reference OK!\n"); - else - INFO("SPIR-V mismatch for cache reference!\n"); - } + stage_desc->module = VK_NULL_HANDLE; if (!d3d12_device_validate_shader_meta(device, &spirv_code->meta)) return E_INVALIDARG; @@ -2411,8 +2363,58 @@ static HRESULT vkd3d_create_shader_stage(struct d3d12_pipeline_state *state, str } } - stage_desc->module = VK_NULL_HANDLE; - return d3d12_pipeline_state_create_shader_module(device, stage_desc, spirv_code); + return d3d12_pipeline_state_create_shader_module(device, &stage_desc->module, spirv_code); +} + +static HRESULT vkd3d_compile_shader_stage(struct d3d12_pipeline_state *state, struct d3d12_device *device, + VkShaderStageFlagBits stage, const D3D12_SHADER_BYTECODE *code, struct vkd3d_shader_code *spirv_code) +{ + struct vkd3d_shader_code dxbc = {code->pShaderBytecode, code->BytecodeLength}; + struct vkd3d_shader_interface_info shader_interface; + struct vkd3d_shader_compile_arguments compile_args; + vkd3d_shader_hash_t recovered_hash = 0; + vkd3d_shader_hash_t compiled_hash = 0; + int ret; + + if (spirv_code->code && (vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_SANITIZE_SPIRV)) + { + recovered_hash = vkd3d_shader_hash(spirv_code); + vkd3d_shader_free_shader_code(spirv_code); + memset(spirv_code, 0, sizeof(*spirv_code)); + } + + if (!spirv_code->code) + { + TRACE("Calling vkd3d_shader_compile_dxbc.\n"); + + d3d12_pipeline_state_init_shader_interface(state, device, stage, &shader_interface); + d3d12_pipeline_state_init_compile_arguments(state, device, stage, &compile_args); + + if ((ret = vkd3d_shader_compile_dxbc(&dxbc, spirv_code, 0, &shader_interface, &compile_args)) < 0) + { + WARN("Failed to compile shader, vkd3d result %d.\n", ret); + return hresult_from_vkd3d_result(ret); + } + TRACE("Called vkd3d_shader_compile_dxbc.\n"); + + if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) + { + /* At this point we don't need the map anymore. */ + vkd3d_shader_stage_io_map_free(&state->graphics.cached_desc.stage_io_map_ms_ps); + } + } + + /* Debug compare SPIR-V we got from cache, and SPIR-V we got from compilation. */ + if (recovered_hash) + { + compiled_hash = vkd3d_shader_hash(spirv_code); + if (compiled_hash == recovered_hash) + INFO("SPIR-V match for cache reference OK!\n"); + else + INFO("SPIR-V mismatch for cache reference!\n"); + } + + return S_OK; } static void vkd3d_report_pipeline_creation_feedback_results(const VkPipelineCreationFeedbackCreateInfoEXT *feedback) @@ -2478,11 +2480,16 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_pipeline_state *state, pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pipeline_info.pNext = NULL; pipeline_info.flags = 0; - if (FAILED(hr = vkd3d_create_shader_stage(state, device, - &pipeline_info.stage, - VK_SHADER_STAGE_COMPUTE_BIT, &required_subgroup_size_info, - code, spirv_code))) + + if (FAILED(hr = vkd3d_compile_shader_stage(state, device, + VK_SHADER_STAGE_COMPUTE_BIT, code, spirv_code))) return hr; + + if (FAILED(hr = vkd3d_setup_shader_stage(state, device, + &pipeline_info.stage, VK_SHADER_STAGE_COMPUTE_BIT, &required_subgroup_size_info, + spirv_code))) + return hr; + pipeline_info.layout = state->root_signature->compute.vk_pipeline_layout; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; @@ -3224,7 +3231,7 @@ static void d3d12_pipeline_state_graphics_load_spirv_from_cached_state( for (j = 0; j < i; j++) { if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_LOG) - INFO("Discarding cached SPIR-V for stage #%x.\n", graphics->cached_desc.bytecode_stages[i]); + INFO("Discarding cached SPIR-V for stage #%x.\n", graphics->cached_desc.bytecode_stages[j]); vkd3d_shader_free_shader_code(&graphics->code[j]); memset(&graphics->code[j], 0, sizeof(graphics->code[j])); } @@ -3244,10 +3251,15 @@ static HRESULT d3d12_pipeline_state_graphics_create_shader_stages( /* Now create the actual shader modules. If we managed to load SPIR-V from cache, use that directly. */ for (i = 0; i < graphics->stage_count; i++) { - if (FAILED(hr = vkd3d_create_shader_stage(state, device, + if (FAILED(hr = vkd3d_compile_shader_stage(state, device, + graphics->cached_desc.bytecode_stages[i], + &graphics->cached_desc.bytecode[i], &graphics->code[i]))) + return hr; + + if (FAILED(hr = vkd3d_setup_shader_stage(state, device, &graphics->stages[i], graphics->cached_desc.bytecode_stages[i], NULL, - &graphics->cached_desc.bytecode[i], &graphics->code[i]))) + &graphics->code[i]))) return hr; } @@ -4377,7 +4389,8 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st { if (stages[i].module == VK_NULL_HANDLE && graphics->code[i].code) { - if (FAILED(hr = d3d12_pipeline_state_create_shader_module(device, &stages[i], &graphics->code[i]))) + if (FAILED(hr = d3d12_pipeline_state_create_shader_module(device, + &stages[i].module, &graphics->code[i]))) { /* This is kind of fatal and should only happen for out-of-memory. */ ERR("Unexpected failure (hr %x) in creating fallback SPIR-V module.\n", hr); |