diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 97d3adce..8e96d208 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -868,8 +868,9 @@ 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, gather, grad, lod, lod_zero, shadow; + bool shadow_sampler, array, bias, gather, grad, lod, lod_zero, offset, shadow; const struct glsl_resource_type_info *resource_type_info; + const struct vkd3d_shader_src_param *resource, *sampler; unsigned int resource_id, resource_idx, resource_space; unsigned int sampler_id, sampler_idx, sampler_space; const struct vkd3d_shader_descriptor_info1 *d; @@ -881,23 +882,27 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk struct glsl_dst dst; bias = ins->opcode == VKD3DSIH_SAMPLE_B; - gather = ins->opcode == VKD3DSIH_GATHER4; + gather = ins->opcode == VKD3DSIH_GATHER4 || ins->opcode == VKD3DSIH_GATHER4_PO; 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; + offset = ins->opcode == VKD3DSIH_GATHER4_PO; shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; + resource = &ins->src[1 + offset]; + sampler = &ins->src[2 + offset]; + if (vkd3d_shader_instruction_has_texel_offset(ins)) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled texel sample offset."); - if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr - || ins->src[2].reg.idx[0].rel_addr || ins->src[2].reg.idx[1].rel_addr) + if (resource->reg.idx[0].rel_addr || resource->reg.idx[1].rel_addr + || sampler->reg.idx[0].rel_addr || sampler->reg.idx[1].rel_addr) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, "Descriptor indexing is not supported."); - resource_id = ins->src[1].reg.idx[0].offset; - resource_idx = ins->src[1].reg.idx[1].offset; + resource_id = resource->reg.idx[0].offset; + resource_idx = resource->reg.idx[1].offset; if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) { resource_type = d->resource_type; @@ -927,8 +932,8 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk array = false; } - sampler_id = ins->src[2].reg.idx[0].offset; - sampler_idx = ins->src[2].reg.idx[1].offset; + sampler_id = sampler->reg.idx[0].offset; + sampler_idx = sampler->reg.idx[1].offset; if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) { sampler_space = d->register_space; @@ -958,7 +963,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk sample = vkd3d_string_buffer_get(&gen->string_buffers); if (gather) - vkd3d_string_buffer_printf(sample, "textureGather("); + vkd3d_string_buffer_printf(sample, "textureGather%s(", offset ? "Offset" : ""); else if (grad) vkd3d_string_buffer_printf(sample, "textureGrad("); else if (lod) @@ -990,13 +995,19 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk vkd3d_string_buffer_printf(sample, ", "); shader_glsl_print_src(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); } + if (offset) + { + vkd3d_string_buffer_printf(sample, ", "); + shader_glsl_print_src(sample, gen, &ins->src[1], + vkd3d_write_mask_from_component_count(coord_size - array), ins->src[1].reg.data_type); + } if (gather) { - if ((component_idx = vsir_swizzle_get_component(ins->src[2].swizzle, 0))) + if ((component_idx = vsir_swizzle_get_component(sampler->swizzle, 0))) vkd3d_string_buffer_printf(sample, ", %d", component_idx); } vkd3d_string_buffer_printf(sample, ")"); - shader_glsl_print_swizzle(sample, ins->src[1].swizzle, ins->dst[0].write_mask); + shader_glsl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask); shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", sample->buffer); @@ -1502,6 +1513,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, shader_glsl_cast(gen, ins, "uint", "uvec"); break; case VKD3DSIH_GATHER4: + case VKD3DSIH_GATHER4_PO: case VKD3DSIH_SAMPLE: case VKD3DSIH_SAMPLE_B: case VKD3DSIH_SAMPLE_C: diff --git a/tests/hlsl/gather-offset.shader_test b/tests/hlsl/gather-offset.shader_test index 1c1274e5..edc5d22d 100644 --- a/tests/hlsl/gather-offset.shader_test +++ b/tests/hlsl/gather-offset.shader_test @@ -113,5 +113,5 @@ float4 main() : sv_target [test] uniform 0 int4 1 0 0 0 -todo(glsl | msl) draw quad +todo(msl) draw quad probe (0, 0) rgba (0.1, 0.2, 0.2, 0.1)