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;
|
return checksum == entry->checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk(const struct vkd3d_pipeline_blob_chunk *chunk,
|
static const struct vkd3d_pipeline_blob_chunk *find_blob_chunk_masked(const struct vkd3d_pipeline_blob_chunk *chunk,
|
||||||
size_t size, uint32_t type)
|
size_t size, uint32_t type, uint32_t mask)
|
||||||
{
|
{
|
||||||
uint32_t aligned_chunk_size;
|
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);
|
VKD3D_PIPELINE_BLOB_CHUNK_ALIGN);
|
||||||
if (aligned_chunk_size > size)
|
if (aligned_chunk_size > size)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (chunk->type == type)
|
if ((chunk->type & mask) == type)
|
||||||
return chunk;
|
return chunk;
|
||||||
|
|
||||||
chunk = (const struct vkd3d_pipeline_blob_chunk *)&chunk->data[align(chunk->size, VKD3D_PIPELINE_BLOB_CHUNK_ALIGN)];
|
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;
|
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)
|
static uint32_t d3d12_cached_pipeline_state_to_flags(const struct d3d12_cached_pipeline_state *state)
|
||||||
{
|
{
|
||||||
uint32_t pipeline_library_flags;
|
uint32_t pipeline_library_flags;
|
||||||
|
@ -435,6 +441,41 @@ HRESULT d3d12_cached_pipeline_state_validate(struct d3d12_device *device,
|
||||||
return S_OK;
|
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)
|
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);
|
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;
|
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,
|
if (SUCCEEDED(vkd3d_pipeline_library_find_cached_blob_from_disk_cache(&device->disk_cache,
|
||||||
&object->pipeline_cache_compat, &cached_pso)))
|
&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. */
|
* 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,
|
if (SUCCEEDED(hr = d3d12_cached_pipeline_state_validate(device, &cached_pso,
|
||||||
&object->pipeline_cache_compat)))
|
&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;
|
desc_cached_pso = &cached_pso;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
FIXME("Failed to validate internal pipeline which was fetched from disk cache. This should not happen.\n");
|
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,
|
HRESULT d3d12_cached_pipeline_state_validate(struct d3d12_device *device,
|
||||||
const struct d3d12_cached_pipeline_state *state,
|
const struct d3d12_cached_pipeline_state *state,
|
||||||
const struct vkd3d_pipeline_cache_compatibility *compat);
|
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,
|
void vkd3d_pipeline_cache_compat_from_state_desc(struct vkd3d_pipeline_cache_compatibility *compat,
|
||||||
const struct d3d12_pipeline_state_desc *desc);
|
const struct d3d12_pipeline_state_desc *desc);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue