Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/vkd3d-proton.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-03-21 15:00:37 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-09-14 16:48:23 +0300
commitf0c82ae608ad98183f07c7ae04aa2a40ae119207 (patch)
treefd87617bc65e5c69f8e452506de5f293657370ca
parent143dc4d896fbaa02e79052a9ae0d73166d13dbf9 (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.c141
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);