Skip to content

Commit c07c303

Browse files
Use GL_EXT_samplerless_texture_functions in Vulkan GLSL.
1 parent 44ed664 commit c07c303

File tree

8 files changed

+37
-36
lines changed

8 files changed

+37
-36
lines changed

main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,8 @@ static int main_inner(int argc, char *argv[])
832832
else
833833
{
834834
combined_image_samplers = !args.vulkan_semantics;
835-
build_dummy_sampler = true;
835+
if (!args.vulkan_semantics)
836+
build_dummy_sampler = true;
836837
compiler = unique_ptr<CompilerGLSL>(new CompilerGLSL(read_spirv_file(args.input)));
837838
}
838839

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#version 450
2+
#extension GL_EXT_samplerless_texture_functions : require
23

34
layout(set = 0, binding = 0) uniform sampler Sampler;
45
layout(set = 0, binding = 0) uniform texture2D SampledImage;
5-
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
66

77
layout(location = 0) out vec4 _entryPointOutput;
88

99
void main()
1010
{
1111
ivec2 _152 = ivec3(int(gl_FragCoord.x * 1280.0), int(gl_FragCoord.y * 720.0), 0).xy;
12-
_entryPointOutput = ((texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), _152, 0) + texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), _152, 0)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy);
12+
_entryPointOutput = ((texelFetch(SampledImage, _152, 0) + texelFetch(SampledImage, _152, 0)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy);
1313
}
1414

reference/shaders/asm/frag/image-fetch-no-sampler.asm.vk.frag.vk

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#version 450
2+
#extension GL_EXT_samplerless_texture_functions : require
23

34
layout(set = 0, binding = 0) uniform sampler Sampler;
45
layout(set = 0, binding = 0) uniform texture2D SampledImage;
5-
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
66

77
layout(location = 0) out vec4 _entryPointOutput;
88

99
vec4 sample_fetch(texture2D tex, ivec3 UV)
1010
{
11-
return texelFetch(sampler2D(tex, SPIRV_Cross_DummySampler), UV.xy, UV.z);
11+
return texelFetch(tex, UV.xy, UV.z);
1212
}
1313

1414
vec4 sample_sampler(texture2D tex, vec2 UV)
@@ -21,7 +21,7 @@ vec4 _main(vec4 xIn)
2121
ivec3 coord = ivec3(int(xIn.x * 1280.0), int(xIn.y * 720.0), 0);
2222
ivec3 param = coord;
2323
vec4 value = sample_fetch(SampledImage, param);
24-
value += texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), coord.xy, coord.z);
24+
value += texelFetch(SampledImage, coord.xy, coord.z);
2525
vec2 param_1 = xIn.xy;
2626
value += sample_sampler(SampledImage, param_1);
2727
value += texture(sampler2D(SampledImage, Sampler), xIn.xy);
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#version 450
2+
#extension GL_EXT_samplerless_texture_functions : require
23

34
layout(set = 0, binding = 0) uniform texture2D uSampler2D;
45
layout(set = 0, binding = 0) uniform texture2DMS uSampler2DMS;
5-
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
66

77
void main()
88
{
9-
ivec2 b = textureSize(sampler2D(uSampler2D, SPIRV_Cross_DummySampler), 0);
10-
ivec2 c = textureSize(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler));
11-
int l1 = textureQueryLevels(sampler2D(uSampler2D, SPIRV_Cross_DummySampler));
12-
int s0 = textureSamples(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler));
9+
ivec2 b = textureSize(uSampler2D, 0);
10+
ivec2 c = textureSize(uSampler2DMS);
11+
int l1 = textureQueryLevels(uSampler2D);
12+
int s0 = textureSamples(uSampler2DMS);
1313
}
1414

spirv_cross.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,8 +1098,8 @@ const SPIRType &Compiler::get_non_pointer_type(uint32_t type_id) const
10981098

10991099
bool Compiler::is_sampled_image_type(const SPIRType &type)
11001100
{
1101-
return (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage) &&
1102-
type.image.sampled == 1 && type.image.dim != DimBuffer;
1101+
return (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage) && type.image.sampled == 1 &&
1102+
type.image.dim != DimBuffer;
11031103
}
11041104

11051105
void Compiler::set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,

spirv_glsl.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4083,30 +4083,32 @@ string CompilerGLSL::to_function_name(uint32_t tex, const SPIRType &imgtype, boo
40834083
return is_legacy() ? legacy_tex_op(fname, imgtype, lod, tex) : fname;
40844084
}
40854085

4086-
std::string CompilerGLSL::convert_separate_image_to_combined(uint32_t id)
4086+
std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id)
40874087
{
4088-
auto &imgtype = expression_type(id);
40894088
auto *var = maybe_get_backing_variable(id);
40904089

4091-
// If we are fetching from a plain OpTypeImage, we must combine with a dummy sampler.
4090+
// If we are fetching from a plain OpTypeImage, we must combine with a dummy sampler in GLSL.
4091+
// In Vulkan GLSL, we can make use of the newer GL_EXT_samplerless_texture_functions.
40924092
if (var)
40934093
{
40944094
auto &type = get<SPIRType>(var->basetype);
40954095
if (type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer)
40964096
{
4097-
if (!dummy_sampler_id)
4098-
SPIRV_CROSS_THROW(
4099-
"Cannot find dummy sampler ID. Was build_dummy_sampler_for_combined_images() called?");
4100-
41014097
if (options.vulkan_semantics)
41024098
{
4103-
auto sampled_type = imgtype;
4104-
sampled_type.basetype = SPIRType::SampledImage;
4105-
return join(type_to_glsl(sampled_type), "(", to_expression(id), ", ", to_expression(dummy_sampler_id),
4106-
")");
4099+
// Newer glslang supports this extension to deal with texture2D as argument to texture functions.
4100+
if (dummy_sampler_id)
4101+
SPIRV_CROSS_THROW("Vulkan GLSL should not have a dummy sampler for combining.");
4102+
require_extension_internal("GL_EXT_samplerless_texture_functions");
41074103
}
41084104
else
4105+
{
4106+
if (!dummy_sampler_id)
4107+
SPIRV_CROSS_THROW(
4108+
"Cannot find dummy sampler ID. Was build_dummy_sampler_for_combined_images() called?");
4109+
41094110
return to_combined_image_sampler(id, dummy_sampler_id);
4111+
}
41104112
}
41114113
}
41124114

@@ -4121,7 +4123,7 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, boo
41214123
{
41224124
string farg_str;
41234125
if (is_fetch)
4124-
farg_str = convert_separate_image_to_combined(img);
4126+
farg_str = convert_separate_image_to_expression(img);
41254127
else
41264128
farg_str = to_expression(img);
41274129

@@ -7526,7 +7528,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
75267528
if (options.es)
75277529
SPIRV_CROSS_THROW("textureQueryLevels not supported in ES profile.");
75287530

7529-
auto expr = join("textureQueryLevels(", convert_separate_image_to_combined(ops[2]), ")");
7531+
auto expr = join("textureQueryLevels(", convert_separate_image_to_expression(ops[2]), ")");
75307532
auto &restype = get<SPIRType>(ops[0]);
75317533
expr = bitcast_expression(restype, SPIRType::Int, expr);
75327534
emit_op(result_type, id, expr, true);
@@ -7543,7 +7545,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
75437545
if (type.image.sampled == 2)
75447546
expr = join("imageSamples(", to_expression(ops[2]), ")");
75457547
else
7546-
expr = join("textureSamples(", convert_separate_image_to_combined(ops[2]), ")");
7548+
expr = join("textureSamples(", convert_separate_image_to_expression(ops[2]), ")");
75477549

75487550
auto &restype = get<SPIRType>(ops[0]);
75497551
expr = bitcast_expression(restype, SPIRType::Int, expr);
@@ -7564,7 +7566,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
75647566
uint32_t result_type = ops[0];
75657567
uint32_t id = ops[1];
75667568

7567-
auto expr = join("textureSize(", convert_separate_image_to_combined(ops[2]), ", ",
7569+
auto expr = join("textureSize(", convert_separate_image_to_expression(ops[2]), ", ",
75687570
bitcast_expression(SPIRType::Int, ops[3]), ")");
75697571
auto &restype = get<SPIRType>(ops[0]);
75707572
expr = bitcast_expression(restype, SPIRType::Int, expr);
@@ -7783,7 +7785,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
77837785
else
77847786
{
77857787
// This path is hit for samplerBuffers and multisampled images which do not have LOD.
7786-
expr = join("textureSize(", convert_separate_image_to_combined(ops[2]), ")");
7788+
expr = join("textureSize(", convert_separate_image_to_expression(ops[2]), ")");
77877789
}
77887790

77897791
auto &restype = get<SPIRType>(ops[0]);
@@ -9282,8 +9284,7 @@ void CompilerGLSL::branch(uint32_t from, uint32_t to)
92829284
// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
92839285
// write to the ladder here, and defer the break.
92849286
// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
9285-
if (current_emitting_switch && is_loop_break(to) &&
9286-
current_emitting_switch->loop_dominator != -1u &&
9287+
if (current_emitting_switch && is_loop_break(to) && current_emitting_switch->loop_dominator != -1u &&
92879288
get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
92889289
{
92899290
if (!current_emitting_switch->need_ladder_break)

spirv_glsl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ class CompilerGLSL : public Compiler
574574
std::string convert_float_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
575575
std::string convert_double_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
576576

577-
std::string convert_separate_image_to_combined(uint32_t id);
577+
std::string convert_separate_image_to_expression(uint32_t id);
578578

579579
// Builtins in GLSL are always specific signedness, but the SPIR-V can declare them
580580
// as either unsigned or signed.

spirv_msl.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3161,8 +3161,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
31613161
farg_str += to_expression(sample);
31623162
}
31633163

3164-
if (msl_options.swizzle_texture_samples && is_sampled_image_type(imgtype) &&
3165-
(!is_gather || !imgtype.image.depth))
3164+
if (msl_options.swizzle_texture_samples && is_sampled_image_type(imgtype) && (!is_gather || !imgtype.image.depth))
31663165
{
31673166
// Add the swizzle constant from the swizzle buffer.
31683167
if (!is_gather)
@@ -4687,8 +4686,8 @@ bool CompilerMSL::SampledImageScanner::handle(spv::Op opcode, const uint32_t *ar
46874686
case OpImageSampleProjDrefImplicitLod:
46884687
case OpImageFetch:
46894688
case OpImageGather:
4690-
compiler.has_sampled_images = compiler.has_sampled_images ||
4691-
compiler.is_sampled_image_type(compiler.expression_type(args[2]));
4689+
compiler.has_sampled_images =
4690+
compiler.has_sampled_images || compiler.is_sampled_image_type(compiler.expression_type(args[2]));
46924691
break;
46934692
default:
46944693
break;

0 commit comments

Comments
 (0)