cache: Explicitly do not serialize SPIR-V code for cached PSOs.

With upcoming refactor, we might have to compile code on the fly.
To avoid any race conditions on fallback compile storing code[i] <-> StorePipeline reading code[i],
explicitly mark that code[] should be ignored.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2022-03-21 13:21:47 +01:00
parent 221c47d0fd
commit 191214899d
3 changed files with 42 additions and 28 deletions

View File

@ -764,18 +764,21 @@ static VkResult vkd3d_serialize_pipeline_state_inline(const struct d3d12_pipelin
chunk = finish_and_iterate_blob_chunk(chunk); chunk = finish_and_iterate_blob_chunk(chunk);
} }
if (d3d12_pipeline_state_is_graphics(state)) if (!state->pso_is_loaded_from_cached_blob)
{ {
for (i = 0; i < state->graphics.stage_count; i++) if (d3d12_pipeline_state_is_graphics(state))
{ {
vkd3d_shader_code_serialize_inline(&state->graphics.code[i], state->graphics.stages[i].stage, for (i = 0; i < state->graphics.stage_count; i++)
varint_size[i], &chunk); {
vkd3d_shader_code_serialize_inline(&state->graphics.code[i], state->graphics.stages[i].stage,
varint_size[i], &chunk);
}
}
else if (d3d12_pipeline_state_is_compute(state))
{
vkd3d_shader_code_serialize_inline(&state->compute.code, VK_SHADER_STAGE_COMPUTE_BIT,
varint_size[0], &chunk);
} }
}
else if (d3d12_pipeline_state_is_compute(state))
{
vkd3d_shader_code_serialize_inline(&state->compute.code, VK_SHADER_STAGE_COMPUTE_BIT,
varint_size[0], &chunk);
} }
return VK_SUCCESS; return VK_SUCCESS;
@ -843,21 +846,24 @@ static VkResult vkd3d_serialize_pipeline_state_referenced(struct d3d12_pipeline_
chunk = finish_and_iterate_blob_chunk(chunk); chunk = finish_and_iterate_blob_chunk(chunk);
} }
if (d3d12_pipeline_state_is_graphics(state)) if (!state->pso_is_loaded_from_cached_blob)
{ {
for (i = 0; i < state->graphics.stage_count; i++) if (d3d12_pipeline_state_is_graphics(state))
{
for (i = 0; i < state->graphics.stage_count; i++)
{
vkd3d_shader_code_serialize_referenced(pipeline_library,
&state->graphics.code[i], state->graphics.stages[i].stage,
varint_size[i], &chunk);
}
}
else if (d3d12_pipeline_state_is_compute(state))
{ {
vkd3d_shader_code_serialize_referenced(pipeline_library, vkd3d_shader_code_serialize_referenced(pipeline_library,
&state->graphics.code[i], state->graphics.stages[i].stage, &state->compute.code, VK_SHADER_STAGE_COMPUTE_BIT,
varint_size[i], &chunk); varint_size[0], &chunk);
} }
} }
else if (d3d12_pipeline_state_is_compute(state))
{
vkd3d_shader_code_serialize_referenced(pipeline_library,
&state->compute.code, VK_SHADER_STAGE_COMPUTE_BIT,
varint_size[0], &chunk);
}
return VK_SUCCESS; return VK_SUCCESS;
} }
@ -900,18 +906,21 @@ VkResult vkd3d_serialize_pipeline_state(struct d3d12_pipeline_library *pipeline_
vk_blob_size += VKD3D_PIPELINE_BLOB_CHUNK_SIZE_RAW(vk_blob_size_pipeline_cache); vk_blob_size += VKD3D_PIPELINE_BLOB_CHUNK_SIZE_RAW(vk_blob_size_pipeline_cache);
} }
if (d3d12_pipeline_state_is_graphics(state)) if (!state->pso_is_loaded_from_cached_blob)
{ {
for (i = 0; i < state->graphics.stage_count; i++) if (d3d12_pipeline_state_is_graphics(state))
{ {
vk_blob_size += vkd3d_shader_code_compute_serialized_size(&state->graphics.code[i], for (i = 0; i < state->graphics.stage_count; i++)
need_blob_sizes ? &varint_size[i] : NULL, !pipeline_library); {
vk_blob_size += vkd3d_shader_code_compute_serialized_size(&state->graphics.code[i],
need_blob_sizes ? &varint_size[i] : NULL, !pipeline_library);
}
}
else if (d3d12_pipeline_state_is_compute(state))
{
vk_blob_size += vkd3d_shader_code_compute_serialized_size(&state->compute.code,
need_blob_sizes ? &varint_size[0] : NULL, !pipeline_library);
} }
}
else if (d3d12_pipeline_state_is_compute(state))
{
vk_blob_size += vkd3d_shader_code_compute_serialized_size(&state->compute.code,
need_blob_sizes ? &varint_size[0] : NULL, !pipeline_library);
} }
total_size += vk_blob_size; total_size += vk_blob_size;

View File

@ -3863,6 +3863,10 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
{ {
VK_CALL(vkDestroyPipelineCache(device->vk_device, object->vk_pso_cache, NULL)); VK_CALL(vkDestroyPipelineCache(device->vk_device, object->vk_pso_cache, NULL));
object->vk_pso_cache = VK_NULL_HANDLE; object->vk_pso_cache = VK_NULL_HANDLE;
/* Set this explicitly so we avoid attempting to touch code[i] when serializing the PSO blob.
* We are at risk of compiling code on the fly in some upcoming situations. */
object->pso_is_loaded_from_cached_blob = true;
} }
TRACE("Created pipeline state %p.\n", object); TRACE("Created pipeline state %p.\n", object);

View File

@ -1560,6 +1560,7 @@ struct d3d12_pipeline_state
struct d3d12_root_signature *root_signature; struct d3d12_root_signature *root_signature;
struct d3d12_device *device; struct d3d12_device *device;
bool root_signature_compat_hash_is_dxbc_derived; bool root_signature_compat_hash_is_dxbc_derived;
bool pso_is_loaded_from_cached_blob;
struct vkd3d_private_store private_store; struct vkd3d_private_store private_store;
}; };