Merge pull request #715 from KhronosGroup/fix-709
Use GL_EXT_samplerless_texture_functions in Vulkan GLSL.
This commit is contained in:
commit
e0fb64bfe7
3
main.cpp
3
main.cpp
@ -832,7 +832,8 @@ static int main_inner(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
combined_image_samplers = !args.vulkan_semantics;
|
combined_image_samplers = !args.vulkan_semantics;
|
||||||
build_dummy_sampler = true;
|
if (!args.vulkan_semantics)
|
||||||
|
build_dummy_sampler = true;
|
||||||
compiler = unique_ptr<CompilerGLSL>(new CompilerGLSL(read_spirv_file(args.input)));
|
compiler = unique_ptr<CompilerGLSL>(new CompilerGLSL(read_spirv_file(args.input)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_EXT_samplerless_texture_functions : require
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler Sampler;
|
layout(set = 0, binding = 0) uniform sampler Sampler;
|
||||||
layout(set = 0, binding = 0) uniform texture2D SampledImage;
|
layout(set = 0, binding = 0) uniform texture2D SampledImage;
|
||||||
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 _entryPointOutput;
|
layout(location = 0) out vec4 _entryPointOutput;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
ivec2 _152 = ivec3(int(gl_FragCoord.x * 1280.0), int(gl_FragCoord.y * 720.0), 0).xy;
|
ivec2 _152 = ivec3(int(gl_FragCoord.x * 1280.0), int(gl_FragCoord.y * 720.0), 0).xy;
|
||||||
_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);
|
_entryPointOutput = ((texelFetch(SampledImage, _152, 0) + texelFetch(SampledImage, _152, 0)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_EXT_samplerless_texture_functions : require
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler Sampler;
|
layout(set = 0, binding = 0) uniform sampler Sampler;
|
||||||
layout(set = 0, binding = 0) uniform texture2D SampledImage;
|
layout(set = 0, binding = 0) uniform texture2D SampledImage;
|
||||||
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 _entryPointOutput;
|
layout(location = 0) out vec4 _entryPointOutput;
|
||||||
|
|
||||||
vec4 sample_fetch(texture2D tex, ivec3 UV)
|
vec4 sample_fetch(texture2D tex, ivec3 UV)
|
||||||
{
|
{
|
||||||
return texelFetch(sampler2D(tex, SPIRV_Cross_DummySampler), UV.xy, UV.z);
|
return texelFetch(tex, UV.xy, UV.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sample_sampler(texture2D tex, vec2 UV)
|
vec4 sample_sampler(texture2D tex, vec2 UV)
|
||||||
@ -21,7 +21,7 @@ vec4 _main(vec4 xIn)
|
|||||||
ivec3 coord = ivec3(int(xIn.x * 1280.0), int(xIn.y * 720.0), 0);
|
ivec3 coord = ivec3(int(xIn.x * 1280.0), int(xIn.y * 720.0), 0);
|
||||||
ivec3 param = coord;
|
ivec3 param = coord;
|
||||||
vec4 value = sample_fetch(SampledImage, param);
|
vec4 value = sample_fetch(SampledImage, param);
|
||||||
value += texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), coord.xy, coord.z);
|
value += texelFetch(SampledImage, coord.xy, coord.z);
|
||||||
vec2 param_1 = xIn.xy;
|
vec2 param_1 = xIn.xy;
|
||||||
value += sample_sampler(SampledImage, param_1);
|
value += sample_sampler(SampledImage, param_1);
|
||||||
value += texture(sampler2D(SampledImage, Sampler), xIn.xy);
|
value += texture(sampler2D(SampledImage, Sampler), xIn.xy);
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_EXT_samplerless_texture_functions : require
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform texture2D uSampler2D;
|
layout(set = 0, binding = 0) uniform texture2D uSampler2D;
|
||||||
layout(set = 0, binding = 0) uniform texture2DMS uSampler2DMS;
|
layout(set = 0, binding = 0) uniform texture2DMS uSampler2DMS;
|
||||||
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
ivec2 b = textureSize(sampler2D(uSampler2D, SPIRV_Cross_DummySampler), 0);
|
ivec2 b = textureSize(uSampler2D, 0);
|
||||||
ivec2 c = textureSize(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler));
|
ivec2 c = textureSize(uSampler2DMS);
|
||||||
int l1 = textureQueryLevels(sampler2D(uSampler2D, SPIRV_Cross_DummySampler));
|
int l1 = textureQueryLevels(uSampler2D);
|
||||||
int s0 = textureSamples(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler));
|
int s0 = textureSamples(uSampler2DMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,8 +1098,8 @@ const SPIRType &Compiler::get_non_pointer_type(uint32_t type_id) const
|
|||||||
|
|
||||||
bool Compiler::is_sampled_image_type(const SPIRType &type)
|
bool Compiler::is_sampled_image_type(const SPIRType &type)
|
||||||
{
|
{
|
||||||
return (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage) &&
|
return (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage) && type.image.sampled == 1 &&
|
||||||
type.image.sampled == 1 && type.image.dim != DimBuffer;
|
type.image.dim != DimBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
|
void Compiler::set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
|
||||||
|
@ -4083,30 +4083,32 @@ string CompilerGLSL::to_function_name(uint32_t tex, const SPIRType &imgtype, boo
|
|||||||
return is_legacy() ? legacy_tex_op(fname, imgtype, lod, tex) : fname;
|
return is_legacy() ? legacy_tex_op(fname, imgtype, lod, tex) : fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CompilerGLSL::convert_separate_image_to_combined(uint32_t id)
|
std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id)
|
||||||
{
|
{
|
||||||
auto &imgtype = expression_type(id);
|
|
||||||
auto *var = maybe_get_backing_variable(id);
|
auto *var = maybe_get_backing_variable(id);
|
||||||
|
|
||||||
// If we are fetching from a plain OpTypeImage, we must combine with a dummy sampler.
|
// If we are fetching from a plain OpTypeImage, we must combine with a dummy sampler in GLSL.
|
||||||
|
// In Vulkan GLSL, we can make use of the newer GL_EXT_samplerless_texture_functions.
|
||||||
if (var)
|
if (var)
|
||||||
{
|
{
|
||||||
auto &type = get<SPIRType>(var->basetype);
|
auto &type = get<SPIRType>(var->basetype);
|
||||||
if (type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer)
|
if (type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer)
|
||||||
{
|
{
|
||||||
if (!dummy_sampler_id)
|
|
||||||
SPIRV_CROSS_THROW(
|
|
||||||
"Cannot find dummy sampler ID. Was build_dummy_sampler_for_combined_images() called?");
|
|
||||||
|
|
||||||
if (options.vulkan_semantics)
|
if (options.vulkan_semantics)
|
||||||
{
|
{
|
||||||
auto sampled_type = imgtype;
|
// Newer glslang supports this extension to deal with texture2D as argument to texture functions.
|
||||||
sampled_type.basetype = SPIRType::SampledImage;
|
if (dummy_sampler_id)
|
||||||
return join(type_to_glsl(sampled_type), "(", to_expression(id), ", ", to_expression(dummy_sampler_id),
|
SPIRV_CROSS_THROW("Vulkan GLSL should not have a dummy sampler for combining.");
|
||||||
")");
|
require_extension_internal("GL_EXT_samplerless_texture_functions");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!dummy_sampler_id)
|
||||||
|
SPIRV_CROSS_THROW(
|
||||||
|
"Cannot find dummy sampler ID. Was build_dummy_sampler_for_combined_images() called?");
|
||||||
|
|
||||||
return to_combined_image_sampler(id, dummy_sampler_id);
|
return to_combined_image_sampler(id, dummy_sampler_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4121,7 +4123,7 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, boo
|
|||||||
{
|
{
|
||||||
string farg_str;
|
string farg_str;
|
||||||
if (is_fetch)
|
if (is_fetch)
|
||||||
farg_str = convert_separate_image_to_combined(img);
|
farg_str = convert_separate_image_to_expression(img);
|
||||||
else
|
else
|
||||||
farg_str = to_expression(img);
|
farg_str = to_expression(img);
|
||||||
|
|
||||||
@ -7526,7 +7528,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
if (options.es)
|
if (options.es)
|
||||||
SPIRV_CROSS_THROW("textureQueryLevels not supported in ES profile.");
|
SPIRV_CROSS_THROW("textureQueryLevels not supported in ES profile.");
|
||||||
|
|
||||||
auto expr = join("textureQueryLevels(", convert_separate_image_to_combined(ops[2]), ")");
|
auto expr = join("textureQueryLevels(", convert_separate_image_to_expression(ops[2]), ")");
|
||||||
auto &restype = get<SPIRType>(ops[0]);
|
auto &restype = get<SPIRType>(ops[0]);
|
||||||
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
||||||
emit_op(result_type, id, expr, true);
|
emit_op(result_type, id, expr, true);
|
||||||
@ -7543,7 +7545,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
if (type.image.sampled == 2)
|
if (type.image.sampled == 2)
|
||||||
expr = join("imageSamples(", to_expression(ops[2]), ")");
|
expr = join("imageSamples(", to_expression(ops[2]), ")");
|
||||||
else
|
else
|
||||||
expr = join("textureSamples(", convert_separate_image_to_combined(ops[2]), ")");
|
expr = join("textureSamples(", convert_separate_image_to_expression(ops[2]), ")");
|
||||||
|
|
||||||
auto &restype = get<SPIRType>(ops[0]);
|
auto &restype = get<SPIRType>(ops[0]);
|
||||||
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
||||||
@ -7564,7 +7566,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
uint32_t result_type = ops[0];
|
uint32_t result_type = ops[0];
|
||||||
uint32_t id = ops[1];
|
uint32_t id = ops[1];
|
||||||
|
|
||||||
auto expr = join("textureSize(", convert_separate_image_to_combined(ops[2]), ", ",
|
auto expr = join("textureSize(", convert_separate_image_to_expression(ops[2]), ", ",
|
||||||
bitcast_expression(SPIRType::Int, ops[3]), ")");
|
bitcast_expression(SPIRType::Int, ops[3]), ")");
|
||||||
auto &restype = get<SPIRType>(ops[0]);
|
auto &restype = get<SPIRType>(ops[0]);
|
||||||
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
||||||
@ -7783,7 +7785,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This path is hit for samplerBuffers and multisampled images which do not have LOD.
|
// This path is hit for samplerBuffers and multisampled images which do not have LOD.
|
||||||
expr = join("textureSize(", convert_separate_image_to_combined(ops[2]), ")");
|
expr = join("textureSize(", convert_separate_image_to_expression(ops[2]), ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &restype = get<SPIRType>(ops[0]);
|
auto &restype = get<SPIRType>(ops[0]);
|
||||||
@ -9282,8 +9284,7 @@ void CompilerGLSL::branch(uint32_t from, uint32_t to)
|
|||||||
// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
|
// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
|
||||||
// write to the ladder here, and defer the break.
|
// write to the ladder here, and defer the break.
|
||||||
// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
|
// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
|
||||||
if (current_emitting_switch && is_loop_break(to) &&
|
if (current_emitting_switch && is_loop_break(to) && current_emitting_switch->loop_dominator != -1u &&
|
||||||
current_emitting_switch->loop_dominator != -1u &&
|
|
||||||
get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
|
get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
|
||||||
{
|
{
|
||||||
if (!current_emitting_switch->need_ladder_break)
|
if (!current_emitting_switch->need_ladder_break)
|
||||||
|
@ -574,7 +574,7 @@ protected:
|
|||||||
std::string convert_float_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
std::string convert_float_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
||||||
std::string convert_double_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
std::string convert_double_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
||||||
|
|
||||||
std::string convert_separate_image_to_combined(uint32_t id);
|
std::string convert_separate_image_to_expression(uint32_t id);
|
||||||
|
|
||||||
// Builtins in GLSL are always specific signedness, but the SPIR-V can declare them
|
// Builtins in GLSL are always specific signedness, but the SPIR-V can declare them
|
||||||
// as either unsigned or signed.
|
// as either unsigned or signed.
|
||||||
|
@ -3161,8 +3161,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
|||||||
farg_str += to_expression(sample);
|
farg_str += to_expression(sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msl_options.swizzle_texture_samples && is_sampled_image_type(imgtype) &&
|
if (msl_options.swizzle_texture_samples && is_sampled_image_type(imgtype) && (!is_gather || !imgtype.image.depth))
|
||||||
(!is_gather || !imgtype.image.depth))
|
|
||||||
{
|
{
|
||||||
// Add the swizzle constant from the swizzle buffer.
|
// Add the swizzle constant from the swizzle buffer.
|
||||||
if (!is_gather)
|
if (!is_gather)
|
||||||
@ -4687,8 +4686,8 @@ bool CompilerMSL::SampledImageScanner::handle(spv::Op opcode, const uint32_t *ar
|
|||||||
case OpImageSampleProjDrefImplicitLod:
|
case OpImageSampleProjDrefImplicitLod:
|
||||||
case OpImageFetch:
|
case OpImageFetch:
|
||||||
case OpImageGather:
|
case OpImageGather:
|
||||||
compiler.has_sampled_images = compiler.has_sampled_images ||
|
compiler.has_sampled_images =
|
||||||
compiler.is_sampled_image_type(compiler.expression_type(args[2]));
|
compiler.has_sampled_images || compiler.is_sampled_image_type(compiler.expression_type(args[2]));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user