vkd3d: Make use of internal pipeline library if we're asked to.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
2dcb1e2efc
commit
6c8542f7d6
|
@ -2831,6 +2831,7 @@ static void d3d12_device_destroy(struct d3d12_device *device)
|
|||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS)
|
||||
vkd3d_breadcrumb_tracer_cleanup(&device->breadcrumb_tracer, device);
|
||||
#endif
|
||||
vkd3d_pipeline_library_flush_disk_cache(&device->disk_cache);
|
||||
d3d12_device_global_pipeline_cache_cleanup(device);
|
||||
vkd3d_sampler_state_cleanup(&device->sampler_state, device);
|
||||
vkd3d_view_map_destroy(&device->sampler_map, device);
|
||||
|
@ -4499,10 +4500,16 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(d3d12_device
|
|||
|
||||
flags = 0;
|
||||
|
||||
if (!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_NO_SERIALIZE_SPIRV))
|
||||
/* If we use a disk cache, it is somewhat meaningless to use application pipeline libraries
|
||||
* to store SPIR-V / blob.
|
||||
* We only need to store metadata so we can implement the API correctly w.r.t. return values, and
|
||||
* PSO reload. */
|
||||
if (!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_NO_SERIALIZE_SPIRV) &&
|
||||
!device->disk_cache.library)
|
||||
flags |= VKD3D_PIPELINE_LIBRARY_FLAG_SAVE_FULL_SPIRV;
|
||||
|
||||
/* If we're using global pipeline caches, these are irrelevant. */
|
||||
/* If we're using global pipeline caches, these are irrelevant.
|
||||
* Do not use pipeline library blobs at all. */
|
||||
if (!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_GLOBAL_PIPELINE_CACHE))
|
||||
{
|
||||
flags |= VKD3D_PIPELINE_LIBRARY_FLAG_SAVE_PSO_BLOB |
|
||||
|
@ -6167,6 +6174,10 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|||
vkd3d_init_shader_extensions(device);
|
||||
vkd3d_compute_shader_interface_key(device);
|
||||
|
||||
/* Make sure all extensions and shader interface keys are computed. */
|
||||
if (FAILED(hr = vkd3d_pipeline_library_init_disk_cache(&device->disk_cache, device)))
|
||||
goto out_cleanup_descriptor_qa_global_info;
|
||||
|
||||
#ifdef VKD3D_ENABLE_RENDERDOC
|
||||
if (vkd3d_renderdoc_active() && vkd3d_renderdoc_global_capture_enabled())
|
||||
vkd3d_renderdoc_begin_capture(device->vkd3d_instance->vk_instance);
|
||||
|
@ -6174,6 +6185,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|||
|
||||
return S_OK;
|
||||
|
||||
out_cleanup_descriptor_qa_global_info:
|
||||
vkd3d_descriptor_debug_free_global_info(device->descriptor_qa_global_info, device);
|
||||
out_cleanup_global_pipeline_cache:
|
||||
d3d12_device_global_pipeline_cache_cleanup(device);
|
||||
out_cleanup_breadcrumb_tracer:
|
||||
|
|
|
@ -2270,7 +2270,8 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
|
|||
}
|
||||
|
||||
static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state,
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc)
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc,
|
||||
const struct d3d12_cached_pipeline_state *cached_pso)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct vkd3d_shader_interface_info shader_interface;
|
||||
|
@ -2303,14 +2304,14 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
|
|||
|
||||
if (!device->global_pipeline_cache)
|
||||
{
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, &desc->cached_pso, &state->vk_pso_cache)) < 0)
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, cached_pso, &state->vk_pso_cache)) < 0)
|
||||
{
|
||||
ERR("Failed to create pipeline cache, hr %d.\n", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
vkd3d_load_spirv_from_cached_state(device, &desc->cached_pso,
|
||||
vkd3d_load_spirv_from_cached_state(device, cached_pso,
|
||||
VK_SHADER_STAGE_COMPUTE_BIT, &state->compute.code);
|
||||
|
||||
hr = vkd3d_create_compute_pipeline(device,
|
||||
|
@ -2980,7 +2981,8 @@ static HRESULT d3d12_pipeline_state_validate_blend_state(struct d3d12_pipeline_s
|
|||
}
|
||||
|
||||
static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *state,
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc)
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc,
|
||||
const struct d3d12_cached_pipeline_state *cached_pso)
|
||||
{
|
||||
const VkPhysicalDeviceFeatures *features = &device->device_info.features2.features;
|
||||
unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||
|
@ -3315,7 +3317,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
if (!b->pShaderBytecode)
|
||||
continue;
|
||||
|
||||
if (FAILED(vkd3d_load_spirv_from_cached_state(device, &desc->cached_pso,
|
||||
if (FAILED(vkd3d_load_spirv_from_cached_state(device, cached_pso,
|
||||
shader_stages[i].stage, &graphics->code[stage_count])))
|
||||
{
|
||||
for (j = 0; j < stage_count; j++)
|
||||
|
@ -3576,7 +3578,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
{
|
||||
if (!device->global_pipeline_cache)
|
||||
{
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, &desc->cached_pso, &state->vk_pso_cache)) < 0)
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, cached_pso, &state->vk_pso_cache)) < 0)
|
||||
{
|
||||
ERR("Failed to create pipeline cache, hr %d.\n", hr);
|
||||
goto fail;
|
||||
|
@ -3650,6 +3652,8 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
const struct d3d12_cached_pipeline_state *desc_cached_pso;
|
||||
struct d3d12_cached_pipeline_state cached_pso;
|
||||
struct d3d12_root_signature *root_signature;
|
||||
struct d3d12_pipeline_state *object;
|
||||
HRESULT hr;
|
||||
|
@ -3677,6 +3681,8 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
if (root_signature)
|
||||
object->pipeline_cache_compat.root_signature_compat_hash = root_signature->compatibility_hash;
|
||||
|
||||
desc_cached_pso = &desc->cached_pso;
|
||||
|
||||
if (desc->cached_pso.blob.CachedBlobSizeInBytes)
|
||||
{
|
||||
if (FAILED(hr = d3d12_cached_pipeline_state_validate(device, &desc->cached_pso,
|
||||
|
@ -3688,6 +3694,21 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
return hr;
|
||||
}
|
||||
}
|
||||
else if (device->disk_cache.library)
|
||||
{
|
||||
if (SUCCEEDED(vkd3d_pipeline_library_find_cached_blob_from_disk_cache(&device->disk_cache,
|
||||
&object->pipeline_cache_compat, &cached_pso)))
|
||||
{
|
||||
/* Validation is somewhat redundant, but we need to be very careful about potential corruption.
|
||||
* It should never fail in normal operation, but ...
|
||||
* 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)))
|
||||
desc_cached_pso = &cached_pso;
|
||||
else
|
||||
FIXME("Failed to validate internal pipeline which was fetched from disk cache. This should not happen.\n");
|
||||
}
|
||||
}
|
||||
|
||||
object->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
|
||||
object->refcount = 1;
|
||||
|
@ -3696,11 +3717,11 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
switch (bind_point)
|
||||
{
|
||||
case VK_PIPELINE_BIND_POINT_COMPUTE:
|
||||
hr = d3d12_pipeline_state_init_compute(object, device, desc);
|
||||
hr = d3d12_pipeline_state_init_compute(object, device, desc, desc_cached_pso);
|
||||
break;
|
||||
|
||||
case VK_PIPELINE_BIND_POINT_GRAPHICS:
|
||||
hr = d3d12_pipeline_state_init_graphics(object, device, desc);
|
||||
hr = d3d12_pipeline_state_init_graphics(object, device, desc, desc_cached_pso);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3729,7 +3750,7 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
* For graphics pipelines, we have to keep VkShaderModules around in case we need fallback pipelines.
|
||||
* If we keep the SPIR-V around in memory, we can always create shader modules on-demand in case we
|
||||
* need to actually create fallback pipelines. This avoids unnecessary memory bloat. */
|
||||
if (desc->cached_pso.blob.CachedBlobSizeInBytes ||
|
||||
if (desc_cached_pso->blob.CachedBlobSizeInBytes ||
|
||||
(vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_NO_SERIALIZE_SPIRV))
|
||||
d3d12_pipeline_state_free_spirv_code(object);
|
||||
else
|
||||
|
@ -3737,11 +3758,18 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
|
||||
/* We don't expect to serialize the PSO blob if we loaded it from cache.
|
||||
* Free the cache now to save on memory. */
|
||||
if (desc->cached_pso.blob.CachedBlobSizeInBytes)
|
||||
if (desc_cached_pso->blob.CachedBlobSizeInBytes)
|
||||
{
|
||||
VK_CALL(vkDestroyPipelineCache(device->vk_device, object->vk_pso_cache, NULL));
|
||||
object->vk_pso_cache = VK_NULL_HANDLE;
|
||||
}
|
||||
else if (device->disk_cache.library)
|
||||
{
|
||||
/* We compiled this PSO without any cache (internal or app-provided),
|
||||
* so we should serialize this to internal disk cache.
|
||||
* Pushes work to disk$ thread. */
|
||||
vkd3d_pipeline_library_store_pipeline_to_disk_cache(&device->disk_cache, object);
|
||||
}
|
||||
|
||||
TRACE("Created pipeline state %p.\n", object);
|
||||
|
||||
|
|
|
@ -3191,6 +3191,7 @@ struct d3d12_device
|
|||
struct vkd3d_view_map sampler_map;
|
||||
struct vkd3d_sampler_state sampler_state;
|
||||
struct vkd3d_shader_debug_ring debug_ring;
|
||||
struct vkd3d_pipeline_library_disk_cache disk_cache;
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
struct vkd3d_breadcrumb_tracer breadcrumb_tracer;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue