From d477a0073435303c86c27eba5464245590e29184 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 18 Oct 2024 21:21:15 +0200 Subject: [PATCH] vkd3d-shader/glsl: Implement VKD3DSIH_SAMPLE_GRAD. --- libs/vkd3d-shader/glsl.c | 49 +++++++++++++++++++++--------- tests/hlsl/sample-grad.shader_test | 18 +++++------ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 0af5059a..d469eed0 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -20,8 +20,14 @@ struct glsl_resource_type_info { + /* The number of coordinates needed to sample the resource type. */ size_t coord_size; + /* Whether the resource type is an array type. */ + bool array; + /* Whether the resource type has a shadow/comparison variant. */ bool shadow; + /* The type suffix for resource type. I.e., the "2D" part of "usampler2D" + * or "iimage2D". */ const char *type_suffix; }; @@ -102,17 +108,17 @@ static const struct glsl_resource_type_info *shader_glsl_get_resource_type_info( { static const struct glsl_resource_type_info info[] = { - {0, 0, "None"}, /* VKD3D_SHADER_RESOURCE_NONE */ - {1, 0, "Buffer"}, /* VKD3D_SHADER_RESOURCE_BUFFER */ - {1, 1, "1D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */ - {2, 1, "2D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */ - {2, 0, "2DMS"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */ - {3, 0, "3D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */ - {3, 1, "Cube"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */ - {2, 1, "1DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ - {3, 1, "2DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ - {3, 0, "2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ - {4, 1, "CubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ + {0, 0, 0, "None"}, /* VKD3D_SHADER_RESOURCE_NONE */ + {1, 0, 0, "Buffer"}, /* VKD3D_SHADER_RESOURCE_BUFFER */ + {1, 0, 1, "1D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */ + {2, 0, 1, "2D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */ + {2, 0, 0, "2DMS"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */ + {3, 0, 0, "3D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */ + {3, 0, 1, "Cube"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */ + {2, 1, 1, "1DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ + {3, 1, 1, "2DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ + {3, 1, 0, "2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ + {4, 1, 1, "CubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ }; if (!t || t >= ARRAY_SIZE(info)) @@ -862,10 +868,10 @@ static void shader_glsl_print_shadow_coord(struct vkd3d_string_buffer *buffer, s static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { + bool shadow_sampler, array, bias, grad, lod, lod_zero, shadow; const struct glsl_resource_type_info *resource_type_info; unsigned int resource_id, resource_idx, resource_space; unsigned int sampler_id, sampler_idx, sampler_space; - bool shadow_sampler, bias, lod, lod_zero, shadow; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_component_type sampled_type; enum vkd3d_shader_resource_type resource_type; @@ -875,6 +881,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk struct glsl_dst dst; bias = ins->opcode == VKD3DSIH_SAMPLE_B; + grad = ins->opcode == VKD3DSIH_SAMPLE_GRAD; lod = ins->opcode == VKD3DSIH_SAMPLE_LOD || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; lod_zero = ins->opcode == VKD3DSIH_SAMPLE_C_LZ; shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; @@ -909,12 +916,14 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) { coord_size = resource_type_info->coord_size; + array = resource_type_info->array; } else { vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled resource type %#x.", resource_type); coord_size = 2; + array = false; } sampler_id = ins->src[2].reg.idx[0].offset; @@ -947,7 +956,9 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk glsl_dst_init(&dst, gen, ins, &ins->dst[0]); sample = vkd3d_string_buffer_get(&gen->string_buffers); - if (lod) + if (grad) + vkd3d_string_buffer_printf(sample, "textureGrad("); + else if (lod) vkd3d_string_buffer_printf(sample, "textureLod("); else vkd3d_string_buffer_printf(sample, "texture("); @@ -958,7 +969,16 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk else shader_glsl_print_src(sample, gen, &ins->src[0], vkd3d_write_mask_from_component_count(coord_size), ins->src[0].reg.data_type); - if (lod_zero) + if (grad) + { + vkd3d_string_buffer_printf(sample, ", "); + shader_glsl_print_src(sample, gen, &ins->src[3], + vkd3d_write_mask_from_component_count(coord_size - array), ins->src[3].reg.data_type); + vkd3d_string_buffer_printf(sample, ", "); + shader_glsl_print_src(sample, gen, &ins->src[4], + vkd3d_write_mask_from_component_count(coord_size - array), ins->src[4].reg.data_type); + } + else if (lod_zero) { vkd3d_string_buffer_printf(sample, ", 0.0"); } @@ -1564,6 +1584,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VKD3DSIH_SAMPLE_B: case VKD3DSIH_SAMPLE_C: case VKD3DSIH_SAMPLE_C_LZ: + case VKD3DSIH_SAMPLE_GRAD: case VKD3DSIH_SAMPLE_LOD: shader_glsl_sample(gen, ins); break; diff --git a/tests/hlsl/sample-grad.shader_test b/tests/hlsl/sample-grad.shader_test index c15e4b0c..e0c88b70 100644 --- a/tests/hlsl/sample-grad.shader_test +++ b/tests/hlsl/sample-grad.shader_test @@ -26,13 +26,13 @@ float4 main() : sv_target [test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(glsl) draw quad +draw quad probe (0,0) rgba (1.0, 0.0, 1.0, 0.0) uniform 0 float4 1.0 1.0 1.0 1.0 -todo(glsl) draw quad +draw quad probe (0,0) rgba (0.0, 0.0, 1.0, 0.0) uniform 0 float4 2.0 2.0 2.0 2.0 -todo(glsl) draw quad +draw quad probe (0,0) rgba (0.0, 0.0, 1.0, 0.0) [pixel shader fail(sm>=6)] @@ -46,13 +46,13 @@ float4 main() : sv_target [test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(glsl) draw quad +draw quad probe (0,0) rgba (1.0, 0.0, 1.0, 0.0) uniform 0 float4 1.0 1.0 1.0 1.0 -todo(glsl) draw quad +draw quad probe (0,0) rgba (0.0, 0.0, 1.0, 0.0) uniform 0 float4 2.0 2.0 2.0 2.0 -todo(glsl) draw quad +draw quad probe (0,0) rgba (0.0, 0.0, 1.0, 0.0) [require] @@ -70,11 +70,11 @@ float4 main() : sv_target [test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(glsl) draw quad +draw quad probe (0, 0) rgba (1.0, 0.0, 1.0, 0.0) uniform 0 float4 1.0 1.0 1.0 1.0 -todo(glsl) draw quad +draw quad probe (0, 0) rgba (0.0, 0.0, 1.0, 0.0) uniform 0 float4 2.0 2.0 2.0 2.0 -todo(glsl) draw quad +draw quad probe (0, 0) rgba (0.0, 0.0, 1.0, 0.0)