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 16:26:25 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-09-16 23:25:44 +0300
commit2505510d13137afa1858305f03d377a734c1dced (patch)
treed894ec26d46637a8c8f01e8219e97d26993a83cf
parentf689188f2651d68eedff2ac2ce413e35f738e4ba (diff)
vkd3d: Add helper for late compilation of DXBC -> SPIR-V.
To be used by EXT_shader_module_identifier implementation. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
-rw-r--r--libs/vkd3d/state.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 8ba87770..317b6a62 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -2418,6 +2418,90 @@ static HRESULT vkd3d_compile_shader_stage(struct d3d12_pipeline_state *state, st
return S_OK;
}
+static bool vkd3d_shader_stages_require_work_locked(struct d3d12_pipeline_state *state)
+{
+ struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
+ unsigned int i;
+
+ for (i = 0; i < graphics->stage_count; i++)
+ {
+ if (!graphics->code[i].size && graphics->stages[i].module == VK_NULL_HANDLE &&
+ graphics->cached_desc.bytecode[i].BytecodeLength)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static HRESULT vkd3d_late_compile_shader_stages(struct d3d12_pipeline_state *state)
+{
+ /* We are at risk of having to compile pipelines late if we return from CreatePipelineState without
+ * either code[i] or module being non-null. */
+ struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
+ bool need_compile;
+ unsigned int i;
+ HRESULT hr;
+
+ rwlock_lock_read(&state->lock);
+ need_compile = vkd3d_shader_stages_require_work_locked(state);
+ rwlock_unlock_read(&state->lock);
+
+ if (!need_compile)
+ return S_OK;
+
+ /* Taking a writer lock here is kinda horrible,
+ * but we really shouldn't hit this path except in extreme circumstances. */
+ hr = S_OK;
+ rwlock_lock_write(&state->lock);
+
+ /* Need to verify that need_compile did not change between unlocking reader and locking writer. */
+ need_compile = vkd3d_shader_stages_require_work_locked(state);
+ if (!need_compile)
+ goto early_out;
+
+ for (i = 0; i < graphics->stage_count; i++)
+ {
+ if (graphics->stages[i].module == VK_NULL_HANDLE && !graphics->code[i].size &&
+ graphics->cached_desc.bytecode[i].BytecodeLength)
+ {
+ if (FAILED(hr = vkd3d_compile_shader_stage(state, state->device, graphics->cached_desc.bytecode_stages[i],
+ &graphics->cached_desc.bytecode[i], &graphics->code[i])))
+ break;
+ }
+
+ if (graphics->stages[i].module == VK_NULL_HANDLE)
+ {
+ if (FAILED(hr = d3d12_pipeline_state_create_shader_module(state->device,
+ &graphics->stages[i].module,
+ &graphics->code[i])))
+ {
+ break;
+ }
+ }
+
+ /* We'll keep the module around here, no need to keep code/size pairs around for this.
+ * If we're in a situation where late compile is relevant, we're using PSO cached blobs,
+ * so we never expect to serialize out SPIR-V either way. */
+ vkd3d_shader_free_shader_code(&graphics->code[i]);
+ graphics->code[i].code = NULL;
+ graphics->code[i].size = 0;
+
+ /* Don't need the DXBC blob anymore either. */
+ if (graphics->cached_desc.bytecode_duped_mask & (1u << i))
+ {
+ vkd3d_free((void*)graphics->cached_desc.bytecode[i].pShaderBytecode);
+ memset(&graphics->cached_desc.bytecode[i], 0, sizeof(graphics->cached_desc.bytecode[i]));
+ graphics->cached_desc.bytecode_duped_mask &= ~(1u << i);
+ }
+ }
+
+early_out:
+ rwlock_unlock_write(&state->lock);
+ return hr;
+}
+
static void vkd3d_report_pipeline_creation_feedback_results(const VkPipelineCreationFeedbackCreateInfoEXT *feedback)
{
uint32_t i;