From d75966ab9e4b0fefd71102b62a020b6e093676b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 1 Aug 2017 10:51:45 +0200 Subject: [PATCH] libs/vkd3d: Assign non-overlapping push constant ranges for root constants. --- include/vkd3d_shader.h | 15 +++++++++++++-- libs/vkd3d-shader/spirv.c | 33 +++++++++++++++++++++++++++++---- libs/vkd3d/state.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 8eaae4df..e04d3b85 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -32,6 +32,16 @@ enum vkd3d_shader_compiler_option VKD3D_SHADER_COMPILER_OPTIONS_FORCE_32_BIT = 0x7fffffff, }; +enum vkd3d_shader_visibility +{ + VKD3D_SHADER_VISIBILITY_ALL, + VKD3D_SHADER_VISIBILITY_VERTEX, + VKD3D_SHADER_VISIBILITY_HULL, + VKD3D_SHADER_VISIBILITY_DOMAIN, + VKD3D_SHADER_VISIBILITY_GEOMETRY, + VKD3D_SHADER_VISIBILITY_PIXEL, +}; + struct vkd3d_shader_code { const void *code; @@ -59,9 +69,10 @@ struct vkd3d_shader_resource_binding struct vkd3d_shader_push_constant { unsigned int register_index; + enum vkd3d_shader_visibility shader_visibility; - unsigned int offset; - unsigned int count; + unsigned int offset; /* in bytes */ + unsigned int size; /* in bytes */ }; HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 4628586b..2052f122 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1483,6 +1483,28 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader return compiler; } +static bool vkd3d_dxbc_compiler_check_shader_visibility(struct vkd3d_dxbc_compiler *compiler, + enum vkd3d_shader_visibility visibility) +{ + switch (visibility) + { + case VKD3D_SHADER_VISIBILITY_ALL: + return true; + case VKD3D_SHADER_VISIBILITY_VERTEX: + return compiler->shader_type == VKD3D_SHADER_TYPE_VERTEX; + case VKD3D_SHADER_VISIBILITY_HULL: + return compiler->shader_type == VKD3D_SHADER_TYPE_HULL; + case VKD3D_SHADER_VISIBILITY_DOMAIN: + return compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN; + case VKD3D_SHADER_VISIBILITY_GEOMETRY: + return compiler->shader_type == VKD3D_SHADER_TYPE_GEOMETRY; + case VKD3D_SHADER_VISIBILITY_PIXEL: + return compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL; + } + + return false; +} + static struct vkd3d_push_constant_buffer *vkd3d_dxbc_compiler_find_push_constant( struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg) { @@ -1493,6 +1515,9 @@ static struct vkd3d_push_constant_buffer *vkd3d_dxbc_compiler_find_push_constant { struct vkd3d_push_constant_buffer *current = &compiler->push_constants[i]; + if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->pc.shader_visibility)) + continue; + if (current->pc.register_index == reg_idx) return current; } @@ -2472,7 +2497,7 @@ static void vkd3d_dxbc_compiler_emit_push_constants(struct vkd3d_dxbc_compiler * reg_idx = cb->reg.idx[0].offset; vkd3d_spirv_build_op_member_decorate1(builder, struct_id, j, - SpvDecorationOffset, cb->pc.offset * sizeof(uint32_t)); + SpvDecorationOffset, cb->pc.offset); vkd3d_spirv_build_op_member_name(builder, struct_id, j, "cb%u", reg_idx); vkd3d_symbol_make_register(®_symbol, &cb->reg); @@ -2507,9 +2532,9 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi if ((push_cb = vkd3d_dxbc_compiler_find_push_constant(compiler, reg))) { push_cb->reg = *reg; - if (cb_size * VKD3D_VEC4_SIZE != push_cb->pc.count) - FIXME("Push constant size do not match (cb size %u, constant count %u).\n", - cb_size, push_cb->pc.count); + if (cb_size * VKD3D_VEC4_SIZE * sizeof(uint32_t) != push_cb->pc.size) + FIXME("Push constant size do not match (cb size %u, constant size %u).\n", + cb_size, push_cb->pc.size); return; } diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index f52fcd55..3e228667 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -191,6 +191,28 @@ static VkShaderStageFlags stage_flags_from_visibility(D3D12_SHADER_VISIBILITY vi } } +static enum vkd3d_shader_visibility vkd3d_shader_visibility_from_d3d12(D3D12_SHADER_VISIBILITY visibility) +{ + switch (visibility) + { + case D3D12_SHADER_VISIBILITY_ALL: + return VKD3D_SHADER_VISIBILITY_ALL; + case D3D12_SHADER_VISIBILITY_VERTEX: + return VKD3D_SHADER_VISIBILITY_VERTEX; + case D3D12_SHADER_VISIBILITY_HULL: + return VKD3D_SHADER_VISIBILITY_HULL; + case D3D12_SHADER_VISIBILITY_DOMAIN: + return VKD3D_SHADER_VISIBILITY_DOMAIN; + case D3D12_SHADER_VISIBILITY_GEOMETRY: + return VKD3D_SHADER_VISIBILITY_GEOMETRY; + case D3D12_SHADER_VISIBILITY_PIXEL: + return VKD3D_SHADER_VISIBILITY_PIXEL; + default: + FIXME("Unhandled visibility %#x.\n", visibility); + return VKD3D_SHADER_VISIBILITY_ALL; + } +} + static VkDescriptorType vk_descriptor_type_from_d3d12_range_type(D3D12_DESCRIPTOR_RANGE_TYPE type) { switch (type) @@ -327,7 +349,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa struct VkDescriptorSetLayoutBinding *binding_desc = NULL, *cur_binding; struct VkDescriptorSetLayoutCreateInfo set_desc; struct VkPushConstantRange *push_constants = NULL; - uint32_t descriptor_idx; + uint32_t descriptor_idx, offset; unsigned int i, j, k; VkResult vr; HRESULT hr; @@ -416,6 +438,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa } /* Map root constants to push constants. */ + offset = 0; for (i = 0, j = 0; i < desc->NumParameters; ++i) { const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; @@ -431,7 +454,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa } push_constants[j].stageFlags = stage_flags_from_visibility(p->ShaderVisibility); - push_constants[j].offset = 0; + push_constants[j].offset = offset; push_constants[j].size = p->u.Constants.Num32BitValues * sizeof(uint32_t); root_signature->constants[j].root_parameter_index = i; @@ -439,9 +462,11 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa root_signature->constants[j].offset = push_constants[j].offset; root_signature->push_constants[j].register_index = p->u.Constants.ShaderRegister; - root_signature->push_constants[j].offset = 0; - root_signature->push_constants[j].count = p->u.Constants.Num32BitValues; + root_signature->push_constants[j].shader_visibility = vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility); + root_signature->push_constants[j].offset = push_constants[j].offset; + root_signature->push_constants[j].size = push_constants[j].size; + offset += push_constants[j].size; ++j; }