diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index a1c45dbd..4eb69b81 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -38,8 +38,27 @@ struct vkd3d_shader_code size_t size; }; +enum vkd3d_descriptor_type +{ + VKD3D_DESCRIPTOR_TYPE_UNKNOWN, + VKD3D_DESCRIPTOR_TYPE_CBV, /* cb# */ + VKD3D_DESCRIPTOR_TYPE_SRV, /* t# */ + VKD3D_DESCRIPTOR_TYPE_UAV, /* u# */ + VKD3D_DESCRIPTOR_TYPE_SAMPLER, /* s# */ +}; + +struct vkd3d_shader_resource_binding +{ + enum vkd3d_descriptor_type type; + unsigned int index; + + uint32_t descriptor_set; + uint32_t binding; +}; + HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_code *spirv, uint32_t compiler_options); + struct vkd3d_shader_code *spirv, uint32_t compiler_options, + const struct vkd3d_shader_resource_binding *bindings, unsigned int binding_count); void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code); HRESULT vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 0b5bf680..2e135b2f 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1365,6 +1365,9 @@ struct vkd3d_dxbc_compiler struct vkd3d_control_flow_info *control_flow_info; size_t control_flow_info_size; + unsigned int binding_count; + const struct vkd3d_shader_resource_binding *bindings; + const struct vkd3d_shader_signature *input_signature; const struct vkd3d_shader_signature *output_signature; struct @@ -1377,7 +1380,8 @@ struct vkd3d_dxbc_compiler }; struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, - const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options) + const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options, + const struct vkd3d_shader_resource_binding *bindings, unsigned int binding_count) { const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature; struct vkd3d_dxbc_compiler *compiler; @@ -1427,9 +1431,74 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader compiler->input_signature = &shader_desc->input_signature; compiler->output_signature = &shader_desc->output_signature; + if (binding_count) + { + compiler->binding_count = binding_count; + compiler->bindings = bindings; + } + return compiler; } +struct vkd3d_descriptor_binding +{ + uint32_t set; + uint32_t binding; +}; + +static struct vkd3d_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding( + struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg) +{ + enum vkd3d_descriptor_type descriptor_type; + struct vkd3d_descriptor_binding vk_binding; + unsigned int reg_idx = reg->idx[0].offset; + unsigned int i; + + descriptor_type = VKD3D_DESCRIPTOR_TYPE_UNKNOWN; + if (reg->type == VKD3DSPR_CONSTBUFFER) + descriptor_type = VKD3D_DESCRIPTOR_TYPE_CBV; + else if (reg->type == VKD3DSPR_RESOURCE) + descriptor_type = VKD3D_DESCRIPTOR_TYPE_SRV; + else if (reg->type == VKD3DSPR_UAV) + descriptor_type = VKD3D_DESCRIPTOR_TYPE_UAV; + else if (reg->type == VKD3DSPR_SAMPLER) + descriptor_type = VKD3D_DESCRIPTOR_TYPE_SAMPLER; + else + FIXME("Unhandled register type %#x.\n", reg->type); + + if (descriptor_type != VKD3D_DESCRIPTOR_TYPE_UNKNOWN) + { + for (i = 0; i < compiler->binding_count; ++i) + { + const struct vkd3d_shader_resource_binding *current = &compiler->bindings[i]; + + if (current->type == descriptor_type && current->index == reg_idx) + { + vk_binding.set = current->descriptor_set; + vk_binding.binding = current->binding; + return vk_binding; + } + } + if (compiler->binding_count) + FIXME("Could not find descriptor binding for %#x, %u.\n", descriptor_type, reg_idx); + } + + vk_binding.set = 0; + vk_binding.binding = reg_idx; + return vk_binding; +} + +static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compiler *compiler, + uint32_t variable_id, const struct vkd3d_shader_register *reg) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + struct vkd3d_descriptor_binding vk_binding; + + vk_binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg); + vkd3d_spirv_build_op_decorate1(builder, variable_id, SpvDecorationDescriptorSet, vk_binding.set); + vkd3d_spirv_build_op_decorate1(builder, variable_id, SpvDecorationBinding, vk_binding.binding); +} + static void vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_symbol *symbol) { @@ -2291,18 +2360,17 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi const struct vkd3d_shader_instruction *instruction) { uint32_t vec4_id, array_type_id, length_id, struct_id, pointer_type_id, var_id; - const struct vkd3d_shader_src_param *src = &instruction->declaration.src; + const struct vkd3d_shader_register *reg = &instruction->declaration.src.reg; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; struct vkd3d_symbol reg_symbol; - unsigned int cb_idx, cb_size; + unsigned int cb_size; assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); if (instruction->flags & VKD3DSI_INDEXED_DYNAMIC) vkd3d_spirv_enable_capability(builder, SpvCapabilityUniformBufferArrayDynamicIndexing); - cb_idx = src->reg.idx[0].offset; - cb_size = src->reg.idx[1].offset; + cb_size = reg->idx[1].offset; vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE); length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, cb_size); @@ -2318,12 +2386,11 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, pointer_type_id, SpvStorageClassUniform, 0); - vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationDescriptorSet, 0); - vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationBinding, cb_idx); + vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, var_id, reg); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, &src->reg); + vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); - vkd3d_symbol_make_register(®_symbol, &src->reg); + vkd3d_symbol_make_register(®_symbol, reg); reg_symbol.id = var_id; reg_symbol.info.storage_class = SpvStorageClassUniform; vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); @@ -2370,17 +2437,13 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, ptr_type_id, var_id; struct vkd3d_symbol reg_symbol; - unsigned int sampler_idx; - - sampler_idx = reg->idx[0].offset; type_id = vkd3d_spirv_get_op_type_sampler(builder); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0); - vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationDescriptorSet, 0); - vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationBinding, sampler_idx); + vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, var_id, reg); vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); @@ -2455,16 +2518,18 @@ static const struct vkd3d_spirv_resource_type *vkd3d_dxbc_compiler_enable_resour } static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_compiler *compiler, - const struct vkd3d_shader_semantic *semantic, bool is_uav) + const struct vkd3d_shader_semantic *semantic) { const SpvStorageClass storage_class = SpvStorageClassUniformConstant; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_register *reg = &semantic->reg.reg; const struct vkd3d_spirv_resource_type *resource_type_info; uint32_t sampled_type_id, type_id, ptr_type_id, var_id; enum vkd3d_component_type sampled_type; struct vkd3d_symbol resource_symbol; - unsigned int reg_idx; + bool is_uav; + is_uav = reg->type == VKD3DSPR_UAV; if (!(resource_type_info = vkd3d_dxbc_compiler_enable_resource_type(compiler, semantic->resource_type, is_uav))) { @@ -2472,8 +2537,6 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp return; } - reg_idx = semantic->reg.reg.idx[0].offset; - sampled_type = vkd3d_component_type_from_data_type(semantic->resource_data_type); sampled_type_id = vkd3d_spirv_get_type_id(builder, sampled_type, 1); @@ -2484,12 +2547,11 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0); - vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationDescriptorSet, 0); - vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationBinding, reg_idx); + vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, var_id, reg); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, &semantic->reg.reg); + vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); - vkd3d_symbol_make_resource(&resource_symbol, &semantic->reg.reg); + vkd3d_symbol_make_resource(&resource_symbol, reg); resource_symbol.id = var_id; resource_symbol.info.resource.sampled_type = sampled_type; resource_symbol.info.resource.type_id = type_id; @@ -2500,7 +2562,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &instruction->declaration.semantic, false); + vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &instruction->declaration.semantic); } static void vkd3d_dxbc_compiler_emit_dcl_uav_typed(struct vkd3d_dxbc_compiler *compiler, @@ -2509,7 +2571,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_uav_typed(struct vkd3d_dxbc_compiler *c if (instruction->flags) FIXME("Unhandled flags %#x.\n", instruction->flags); - vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &instruction->declaration.semantic, true); + vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &instruction->declaration.semantic); } static void vkd3d_dxbc_compiler_emit_dcl_input(struct vkd3d_dxbc_compiler *compiler, diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 98c8c3c7..9c95c1f5 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -19,7 +19,8 @@ #include "vkd3d_shader_private.h" HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_code *spirv, uint32_t compiler_options) + struct vkd3d_shader_code *spirv, uint32_t compiler_options, + const struct vkd3d_shader_resource_binding *bindings, unsigned int binding_count) { struct vkd3d_dxbc_compiler *spirv_compiler; struct vkd3d_shader_version shader_version; @@ -30,8 +31,8 @@ HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, HRESULT hr; bool ret; - TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x.\n", - dxbc->code, dxbc->size, spirv, compiler_options); + TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x, bindings %p, binding_count %u.\n", + dxbc->code, dxbc->size, spirv, compiler_options, bindings, binding_count); if (FAILED(hr = shader_extract_from_dxbc(dxbc->code, dxbc->size, &shader_desc))) { @@ -50,7 +51,7 @@ HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, shader_sm4_read_header(parser_data, &ptr, &shader_version); if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&shader_version, - &shader_desc, compiler_options))) + &shader_desc, compiler_options, bindings, binding_count))) { ERR("Failed to create DXBC compiler.\n"); shader_sm4_free(parser_data); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index af7fe251..7a0a08bf 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -822,7 +822,8 @@ void free_shader_desc(struct vkd3d_shader_desc *desc) DECLSPEC_HIDDEN; struct vkd3d_dxbc_compiler; struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, - const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options) DECLSPEC_HIDDEN; + const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options, + const struct vkd3d_shader_resource_binding *bindings, unsigned int binding_count) DECLSPEC_HIDDEN; void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN; bool vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 42b3b70e..b0a4c97e 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -701,7 +701,7 @@ static bool d3d12_shader_bytecode_is_spirv(const D3D12_SHADER_BYTECODE *code) } static HRESULT create_shader_stage(struct d3d12_device *device, struct VkPipelineShaderStageCreateInfo *stage_desc, - enum VkShaderStageFlagBits stage, const D3D12_SHADER_BYTECODE *code, uint32_t compiler_options) + enum VkShaderStageFlagBits stage, const D3D12_SHADER_BYTECODE *code) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct VkShaderModuleCreateInfo shader_desc; @@ -728,7 +728,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, struct VkPipelin else { struct vkd3d_shader_code dxbc = {code->pShaderBytecode, code->BytecodeLength}; - if (FAILED(hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, compiler_options))) + if (FAILED(hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, 0, NULL, 0))) { WARN("Failed to compile shader, hr %#x.\n", hr); return hr; @@ -769,7 +769,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pipeline_info.pNext = NULL; pipeline_info.flags = 0; - if (FAILED(hr = create_shader_stage(device, &pipeline_info.stage, VK_SHADER_STAGE_COMPUTE_BIT, &desc->CS, 0))) + if (FAILED(hr = create_shader_stage(device, &pipeline_info.stage, VK_SHADER_STAGE_COMPUTE_BIT, &desc->CS))) return hr; pipeline_info.layout = root_signature->vk_pipeline_layout; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; @@ -1108,7 +1108,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s continue; if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count], - shader_stages[i].stage, b, 0))) + shader_stages[i].stage, b))) goto fail; ++graphics->stage_count; diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index ad0eadf4..e862f9a4 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -162,7 +162,7 @@ int main(int argc, char **argv) return 1; } - hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, options.compiler_options); + hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, options.compiler_options, NULL, 0); vkd3d_shader_free_shader_code(&dxbc); if (FAILED(hr)) {