diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-03-18 18:54:42 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-09-14 13:52:31 +0300 |
commit | 1ca812b56185036caf09ef0a6e329b8c30ca4da7 (patch) | |
tree | 6828f007237a9e917498f596cf21103187145156 | |
parent | 070e4a78ac1befc6d702490e88b513dd36dd902a (diff) |
vkd3d: Refactor out how XFB info is stored.
For deferred compilation, we need to dupe the structs.
XFB is kinda rare, so it's okay to eat allocations here.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
-rw-r--r-- | libs/vkd3d/state.c | 83 | ||||
-rw-r--r-- | libs/vkd3d/vkd3d_private.h | 2 |
2 files changed, 74 insertions, 11 deletions
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index c2def7f5..b4967866 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -2002,6 +2002,63 @@ static void d3d12_pipeline_state_set_name(struct d3d12_pipeline_state *state, co } } +static void vkd3d_shader_transform_feedback_info_free(struct vkd3d_shader_transform_feedback_info *xfb_info) +{ + unsigned int i; + + if (!xfb_info) + return; + + for (i = 0; i < xfb_info->element_count; i++) + vkd3d_free((void*)xfb_info->elements[i].semantic_name); + vkd3d_free((void*)xfb_info->elements); + vkd3d_free((void*)xfb_info->buffer_strides); + vkd3d_free(xfb_info); +} + +static struct vkd3d_shader_transform_feedback_info *vkd3d_shader_transform_feedback_info_dup( + const D3D12_STREAM_OUTPUT_DESC *so_desc) +{ + struct vkd3d_shader_transform_feedback_element *new_entries = NULL; + struct vkd3d_shader_transform_feedback_info *xfb_info; + unsigned int *new_buffer_strides = NULL; + unsigned int num_duped = 0; + unsigned int i; + + xfb_info = vkd3d_calloc(1, sizeof(*xfb_info)); + if (!xfb_info) + return NULL; + + new_buffer_strides = malloc(so_desc->NumStrides * sizeof(*new_buffer_strides)); + if (!new_buffer_strides) + goto fail; + memcpy(new_buffer_strides, so_desc->pBufferStrides, so_desc->NumStrides * sizeof(*new_buffer_strides)); + xfb_info->buffer_strides = new_buffer_strides; + + new_entries = malloc(so_desc->NumEntries * sizeof(*new_entries)); + if (!new_entries) + goto fail; + memcpy(new_entries, so_desc->pSODeclaration, so_desc->NumEntries * sizeof(*new_entries)); + xfb_info->elements = new_entries; + + for (i = 0; i < so_desc->NumEntries; i++, num_duped++) + if (!(new_entries[i].semantic_name = vkd3d_strdup(new_entries[i].semantic_name))) + goto fail; + + xfb_info->buffer_stride_count = so_desc->NumStrides; + xfb_info->element_count = so_desc->NumEntries; + + return xfb_info; + +fail: + for (i = 0; i < num_duped; i++) + vkd3d_free((void*)new_entries[i].semantic_name); + vkd3d_free(new_buffer_strides); + vkd3d_free(new_entries); + vkd3d_free(xfb_info); + return NULL; +} + void d3d12_pipeline_state_dec_ref(struct d3d12_pipeline_state *state) { struct d3d12_device *device = state->device; @@ -2023,6 +2080,8 @@ void d3d12_pipeline_state_dec_ref(struct d3d12_pipeline_state *state) if (state->root_signature) d3d12_root_signature_dec_ref(state->root_signature); + if (state->pipeline_type == VKD3D_PIPELINE_TYPE_GRAPHICS) + vkd3d_shader_transform_feedback_info_free(state->graphics.cached_desc.xfb_info); vkd3d_free(state); } } @@ -3147,12 +3206,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s const struct vkd3d_vulkan_info *vk_info = &device->vk_info; uint32_t instance_divisors[D3D12_VS_INPUT_REGISTER_COUNT]; uint32_t aligned_offsets[D3D12_VS_INPUT_REGISTER_COUNT]; - struct vkd3d_shader_transform_feedback_info xfb_info; bool have_attachment, can_compile_pipeline_early; struct vkd3d_shader_stage_io_map ms_ps_interface; struct vkd3d_shader_signature output_signature; struct vkd3d_shader_signature input_signature; - VkShaderStageFlagBits xfb_stage = 0; VkSampleCountFlagBits sample_count; const struct vkd3d_format *format; unsigned int i, j, stage_count; @@ -3373,18 +3430,20 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s } graphics->xfb_enabled = true; + graphics->cached_desc.xfb_info = vkd3d_shader_transform_feedback_info_dup(so_desc); - xfb_info.elements = (const struct vkd3d_shader_transform_feedback_element *)so_desc->pSODeclaration; - xfb_info.element_count = so_desc->NumEntries; - xfb_info.buffer_strides = so_desc->pBufferStrides; - xfb_info.buffer_stride_count = so_desc->NumStrides; + if (!graphics->cached_desc.xfb_info) + { + hr = E_OUTOFMEMORY; + goto fail; + } if (graphics->stage_flags & VK_SHADER_STAGE_GEOMETRY_BIT) - xfb_stage = VK_SHADER_STAGE_GEOMETRY_BIT; + graphics->cached_desc.xfb_stage = VK_SHADER_STAGE_GEOMETRY_BIT; else if (graphics->stage_flags & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) - xfb_stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + graphics->cached_desc.xfb_stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; else - xfb_stage = VK_SHADER_STAGE_VERTEX_BIT; + graphics->cached_desc.xfb_stage = VK_SHADER_STAGE_VERTEX_BIT; } graphics->patch_vertex_count = 0; @@ -3483,8 +3542,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s /* TODO: Move this to vkd3d_create_shader_stage itself. */ d3d12_pipeline_state_init_shader_interface(state, device, shader_stages[i].stage, &ms_ps_interface, &shader_interface); - - shader_interface.xfb_info = shader_stages[i].stage == xfb_stage ? &xfb_info : NULL; + shader_interface.xfb_info = shader_stages[i].stage == graphics->cached_desc.xfb_stage ? + graphics->cached_desc.xfb_info : NULL; d3d12_pipeline_state_init_compile_arguments(state, device, shader_interface.stage, &compile_args); if (FAILED(hr = vkd3d_create_shader_stage(device, @@ -3902,6 +3961,8 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP d3d12_root_signature_dec_ref(object->root_signature); d3d12_pipeline_state_free_spirv_code(object); d3d12_pipeline_state_destroy_shader_modules(object, device); + if (object->pipeline_type == VKD3D_PIPELINE_TYPE_GRAPHICS) + vkd3d_shader_transform_feedback_info_free(object->graphics.cached_desc.xfb_info); VK_CALL(vkDestroyPipelineCache(device->vk_device, object->vk_pso_cache, NULL)); vkd3d_free(object); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 1652cbcc..5fc2b248 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1589,6 +1589,8 @@ struct d3d12_graphics_pipeline_state_cached_desc unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; struct vkd3d_shader_parameter ps_shader_parameters[1]; bool is_dual_source_blending; + VkShaderStageFlagBits xfb_stage; + struct vkd3d_shader_transform_feedback_info *xfb_info; }; struct d3d12_graphics_pipeline_state |