diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 3a2f54c8f..78b9b1537 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -125,6 +125,11 @@ enum vkd3d_shader_structure_type * \since 1.18 */ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, + /** + * The structure is a vkd3d_shader_d3dbc_source_info structure. + * \since 1.18 + */ + VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; @@ -2312,6 +2317,41 @@ struct vkd3d_shader_scan_thread_group_size_info unsigned int x, y, z; }; +/** + * A chained structure containing legacy Direct3D bytecode compilation parameters. + * This structure specifies some information about the source environment that + * is not specified in the source shader format, but may be necessary for the + * target format. + * + * This structure is optional. + * + * This structure extends vkd3d_shader_compile_info. + * + * This structure contains only input parameters. + * + * \since 1.18 + */ +struct vkd3d_shader_d3dbc_source_info +{ + /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO. */ + enum vkd3d_shader_structure_type type; + /** Optional pointer to a structure containing further parameters. */ + const void *next; + + /** + * The dimension of each texture bound to the shader. + * + * If this structure is not specified, the dimension for all textures will + * be VKD3D_SHADER_RESOURCE_TEXTURE_2D. + * + * The dimension of textures in this array not used by the shader will be + * ignored. + * + * This field is ignored for shader models 2 and higher. + */ + enum vkd3d_shader_resource_type texture_dimensions[6]; +}; + /** * Data type of a shader varying, returned as part of struct * vkd3d_shader_signature_element. @@ -2805,6 +2845,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * * Depending on the source and target types, this function may support the * following chained structures: + * - vkd3d_shader_d3dbc_source_info * - vkd3d_shader_descriptor_offset_info * - vkd3d_shader_hlsl_source_info * - vkd3d_shader_interface_info diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 0a434a744..7812efa72 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -248,6 +248,8 @@ struct vkd3d_shader_sm1_parser struct vkd3d_shader_parser p; struct vsir_program *program; + const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; + uint16_t texture_descriptors; struct @@ -1223,6 +1225,8 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1) static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc, const struct vkd3d_shader_instruction *ins) { + enum vkd3d_shader_resource_type type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + const struct vkd3d_shader_d3dbc_source_info *source_info; unsigned int sampler_idx; switch (ins->opcode) @@ -1243,7 +1247,10 @@ static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc, if ((d3dbc->texture_descriptors & (1u << sampler_idx))) break; - d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, VKD3D_SHADER_RESOURCE_TEXTURE_2D); + if ((source_info = d3dbc->d3dbc_source_info) + && sampler_idx < ARRAY_SIZE(source_info->texture_dimensions)) + type = source_info->texture_dimensions[sampler_idx]; + d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, type); d3dbc->texture_descriptors |= (1u << sampler_idx); break; @@ -1456,6 +1463,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st uint16_t shader_type; size_t token_count; + sm1->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); + token_count = code_size / sizeof(*sm1->start); if (token_count < 2) diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index eb64d74b8..7f75cfd5d 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -950,6 +950,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig struct vkd3d_shader_scan_context { const struct vkd3d_shader_version *version; + const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; size_t descriptors_size; @@ -1017,6 +1018,7 @@ static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *con context->location.line = 2; /* Line 1 is the version token. */ context->api_version = VKD3D_SHADER_API_VERSION_1_2; context->combined_sampler_info = combined_sampler_info; + context->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); for (i = 0; i < compile_info->option_count; ++i) { diff --git a/tests/hlsl/ps1-sampler.shader_test b/tests/hlsl/ps1-sampler.shader_test index 517ea2e41..469bdf249 100644 --- a/tests/hlsl/ps1-sampler.shader_test +++ b/tests/hlsl/ps1-sampler.shader_test @@ -43,6 +43,58 @@ probe (480, 240) f32(1, 0, 1, 0) probe (320, 360) f32(1, 1, 0, 0) probe (480, 360) f32(1, 0, 0, 0) +[srv 0] +size (3d, 2, 2, 2) +1.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 +1.0 0.0 1.0 0.0 1.0 1.0 1.0 0.0 + +1.0 0.0 0.0 1.0 1.0 1.0 0.0 1.0 +1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 + +[test] +draw quad +probe (320, 240) f32(1, 1, 1, 1) +probe (480, 240) f32(1, 0, 1, 1) +probe (320, 360) f32(1, 1, 0, 1) +probe (480, 360) f32(1, 0, 0, 1) + +[srv 0] +size (cube, 1) +1.0 0.0 0.0 0.0 +1.0 0.0 0.1 0.0 +1.0 0.0 0.2 0.0 +1.0 0.0 0.3 0.0 +1.0 0.0 0.4 0.0 +1.0 0.0 0.5 0.0 + +[vertex shader] +float4 coord; + +void main(inout float4 pos : position, out float4 tex : texcoord) +{ + tex = coord; +} + +[test] +uniform 0 float4 1 0 0 0 +draw quad +probe (0, 0) f32(1.0, 0.0, 0.0, 0) +uniform 0 float4 -1 0 0 0 +draw quad +probe (0, 0) f32(1.0, 0.0, 0.1, 0) +uniform 0 float4 0 1 0 0 +draw quad +probe (0, 0) f32(1.0, 0.0, 0.2, 0) +uniform 0 float4 0 -1 0 0 +draw quad +probe (0, 0) f32(1.0, 0.0, 0.3, 0) +uniform 0 float4 0 0 1 0 +draw quad +probe (0, 0) f32(1.0, 0.0, 0.4, 0) +uniform 0 float4 0 0 -1 0 +draw quad +probe (0, 0) f32(1.0, 0.0, 0.5, 0) + [vertex shader] void main(inout float4 pos : position, out float4 tex : texcoord) { diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index a63b2432f..01d277814 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -354,6 +354,7 @@ static bool compile_hlsl_and_scan(struct vulkan_shader_runner *runner, enum shad static bool compile_d3d_code(struct vulkan_shader_runner *runner, enum shader_type type, struct vkd3d_shader_code *spirv) { + struct vkd3d_shader_d3dbc_source_info d3dbc_source_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO}; struct vkd3d_shader_varying_map_info varying_map_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_VARYING_MAP_INFO}; struct vkd3d_shader_spirv_target_info spirv_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO}; struct vkd3d_shader_interface_info interface_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO}; @@ -398,6 +399,28 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner, ok(varying_map_info.varying_count <= ARRAY_SIZE(varying_map), "Got unexpected count %u.\n", varying_map_info.varying_count); } + else if (type == SHADER_TYPE_PS && info.source_type == VKD3D_SHADER_SOURCE_D3D_BYTECODE) + { + info.next = &d3dbc_source_info; + + d3dbc_source_info.next = &spirv_info; + + for (i = 0; i < runner->r.resource_count; ++i) + { + const struct resource *resource = runner->r.resources[i]; + + if (resource->desc.type != RESOURCE_TYPE_TEXTURE + || resource->desc.slot > ARRAY_SIZE(d3dbc_source_info.texture_dimensions)) + continue; + + if (resource->desc.dimension == RESOURCE_DIMENSION_3D) + d3dbc_source_info.texture_dimensions[resource->desc.slot] = VKD3D_SHADER_RESOURCE_TEXTURE_3D; + else if (resource->desc.dimension == RESOURCE_DIMENSION_CUBE) + d3dbc_source_info.texture_dimensions[resource->desc.slot] = VKD3D_SHADER_RESOURCE_TEXTURE_CUBE; + else + d3dbc_source_info.texture_dimensions[resource->desc.slot] = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + } + } spirv_info.next = &interface_info; spirv_info.environment = VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0;