cache: Attempt to use disk cache instead when appropriate.
When the disk cache is used, the cache we give back to applications is a dummy. Therefore, try to use the disk cache blob if we detect a useless application blob. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
6c8542f7d6
commit
ae0dafa3a1
|
@ -299,8 +299,8 @@ static bool vkd3d_serialized_pipeline_stream_entry_validate(const uint8_t *data,
|
|||
return checksum == entry->checksum;
|
||||
}
|
||||
|
||||
static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk(const struct vkd3d_pipeline_blob_chunk *chunk,
|
||||
size_t size, uint32_t type)
|
||||
static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk_masked(const struct vkd3d_pipeline_blob_chunk *chunk,
|
||||
size_t size, uint32_t type, uint32_t mask)
|
||||
{
|
||||
uint32_t aligned_chunk_size;
|
||||
|
||||
|
@ -310,7 +310,7 @@ static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk(const struct vkd3
|
|||
VKD3D_PIPELINE_BLOB_CHUNK_ALIGN);
|
||||
if (aligned_chunk_size > size)
|
||||
return NULL;
|
||||
if (chunk->type == type)
|
||||
if ((chunk->type & mask) == type)
|
||||
return chunk;
|
||||
|
||||
chunk = (const struct vkd3d_pipeline_blob_chunk *)&chunk->data[align(chunk->size, VKD3D_PIPELINE_BLOB_CHUNK_ALIGN)];
|
||||
|
@ -320,6 +320,12 @@ static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk(const struct vkd3
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk(const struct vkd3d_pipeline_blob_chunk *chunk,
|
||||
size_t size, uint32_t type)
|
||||
{
|
||||
return find_blob_chunk_masked(chunk, size, type, ~0u);
|
||||
}
|
||||
|
||||
static uint32_t d3d12_cached_pipeline_state_to_flags(const struct d3d12_cached_pipeline_state *state)
|
||||
{
|
||||
uint32_t pipeline_library_flags;
|
||||
|
@ -435,6 +441,41 @@ HRESULT d3d12_cached_pipeline_state_validate(struct d3d12_device *device,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
bool d3d12_cached_pipeline_state_is_dummy(const struct d3d12_cached_pipeline_state *state)
|
||||
{
|
||||
const struct vkd3d_pipeline_blob *blob = state->blob.pCachedBlob;
|
||||
const struct vkd3d_pipeline_blob_chunk *chunk;
|
||||
size_t payload_size;
|
||||
|
||||
if (!state->blob.CachedBlobSizeInBytes)
|
||||
return true;
|
||||
|
||||
if (state->blob.CachedBlobSizeInBytes < sizeof(*blob) || blob->version != VKD3D_CACHE_BLOB_VERSION)
|
||||
return true;
|
||||
payload_size = state->blob.CachedBlobSizeInBytes - offsetof(struct vkd3d_pipeline_blob, data);
|
||||
|
||||
chunk = CONST_CAST_CHUNK_BASE(blob);
|
||||
|
||||
/* Try to find any PSO cache or SPIR-V entry. If they exist, this is not a dummy blob. */
|
||||
if (find_blob_chunk(chunk, payload_size, VKD3D_PIPELINE_BLOB_CHUNK_TYPE_PIPELINE_CACHE))
|
||||
return false;
|
||||
|
||||
if (find_blob_chunk(chunk, payload_size, VKD3D_PIPELINE_BLOB_CHUNK_TYPE_PIPELINE_CACHE_LINK))
|
||||
return false;
|
||||
|
||||
if (find_blob_chunk_masked(chunk, payload_size,
|
||||
VKD3D_PIPELINE_BLOB_CHUNK_TYPE_VARINT_SPIRV,
|
||||
VKD3D_PIPELINE_BLOB_CHUNK_TYPE_MASK))
|
||||
return false;
|
||||
|
||||
if (find_blob_chunk_masked(chunk, payload_size,
|
||||
VKD3D_PIPELINE_BLOB_CHUNK_TYPE_VARINT_SPIRV_LINK,
|
||||
VKD3D_PIPELINE_BLOB_CHUNK_TYPE_MASK))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct vkd3d_pipeline_blob_chunk *finish_and_iterate_blob_chunk(struct vkd3d_pipeline_blob_chunk *chunk)
|
||||
{
|
||||
uint32_t aligned_size = align(chunk->size, VKD3D_PIPELINE_BLOB_CHUNK_ALIGN);
|
||||
|
|
|
@ -3694,7 +3694,17 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
return hr;
|
||||
}
|
||||
}
|
||||
else if (device->disk_cache.library)
|
||||
|
||||
/* If we rely on internal shader cache, the PSO blob app provides us might be a pure metadata blob,
|
||||
* and therefore kinda useless. Try to use disk cache blob instead.
|
||||
* Also, consider that we might have to serialize this pipeline if we don't find anything in disk cache. */
|
||||
if (d3d12_cached_pipeline_state_is_dummy(&desc->cached_pso))
|
||||
{
|
||||
memset(&cached_pso, 0, sizeof(cached_pso));
|
||||
desc_cached_pso = &cached_pso;
|
||||
}
|
||||
|
||||
if (desc_cached_pso->blob.CachedBlobSizeInBytes == 0 && device->disk_cache.library)
|
||||
{
|
||||
if (SUCCEEDED(vkd3d_pipeline_library_find_cached_blob_from_disk_cache(&device->disk_cache,
|
||||
&object->pipeline_cache_compat, &cached_pso)))
|
||||
|
@ -3704,7 +3714,14 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
* However, unlike app-proved blob, it's not fatal if we fail, so just fall back. */
|
||||
if (SUCCEEDED(hr = d3d12_cached_pipeline_state_validate(device, &cached_pso,
|
||||
&object->pipeline_cache_compat)))
|
||||
{
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_LOG) &&
|
||||
desc->cached_pso.blob.CachedBlobSizeInBytes)
|
||||
{
|
||||
INFO("Application provided cached PSO blob, but we opted for disk cache blob instead.\n");
|
||||
}
|
||||
desc_cached_pso = &cached_pso;
|
||||
}
|
||||
else
|
||||
FIXME("Failed to validate internal pipeline which was fetched from disk cache. This should not happen.\n");
|
||||
}
|
||||
|
|
|
@ -1755,6 +1755,7 @@ VkResult vkd3d_serialize_pipeline_state(struct d3d12_pipeline_library *pipeline_
|
|||
HRESULT d3d12_cached_pipeline_state_validate(struct d3d12_device *device,
|
||||
const struct d3d12_cached_pipeline_state *state,
|
||||
const struct vkd3d_pipeline_cache_compatibility *compat);
|
||||
bool d3d12_cached_pipeline_state_is_dummy(const struct d3d12_cached_pipeline_state *state);
|
||||
void vkd3d_pipeline_cache_compat_from_state_desc(struct vkd3d_pipeline_cache_compatibility *compat,
|
||||
const struct d3d12_pipeline_state_desc *desc);
|
||||
|
||||
|
|
Loading…
Reference in New Issue