Bill Hollings 2017-12-04 17:02:08 -05:00
Родитель c93d44ba3c 4a9d3cebd0
Коммит 5502b00682
16 изменённых файлов: 447 добавлений и 45 удалений

Просмотреть файл

@ -0,0 +1,30 @@
Texture2D<float4> uSampler : register(t0);
SamplerState _uSampler_sampler : register(s0);
static float4 FragColor;
static float2 vTexCoord;
struct SPIRV_Cross_Input
{
float2 vTexCoord : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
float _19_tmp = uSampler.CalculateLevelOfDetail(_uSampler_sampler, vTexCoord);
FragColor = float2(_19_tmp, _19_tmp).xyxy;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vTexCoord = stage_input.vTexCoord;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

Просмотреть файл

@ -19,19 +19,19 @@ struct alias_2
alias_1 alias_1;
};
layout(binding = 0, std430) buffer _10_11
{
alias_2 alias;
} alias_3;
layout(binding = 1, std140) buffer _15_16
layout(binding = 0, std430) buffer alias_3
{
alias_2 alias;
} alias_4;
layout(binding = 1, std140) buffer alias_5
{
alias_2 alias;
} alias_6;
void main()
{
alias_2 alias_5 = alias_3.alias;
alias_4.alias = alias_5;
alias_2 alias_7 = alias_4.alias;
alias_6.alias = alias_7;
}

Просмотреть файл

@ -0,0 +1,19 @@
#version 450
layout(binding = 0, std430) buffer Foobar
{
vec4 _data[];
} Foobar_1;
layout(binding = 1, std430) buffer Foobaz
{
vec4 _data[];
} Foobaz_1;
layout(location = 0) out vec4 _entryPointOutput;
void main()
{
_entryPointOutput = Foobar_1._data[0] + Foobaz_1._data[0];
}

Просмотреть файл

@ -0,0 +1,17 @@
#version 450
layout(binding = 1, rgba32f) uniform image2D RWIm;
layout(binding = 0, rgba32f) uniform writeonly imageBuffer RWBuf;
layout(binding = 1) uniform sampler2D ROIm;
layout(binding = 0) uniform samplerBuffer ROBuf;
layout(location = 0) out vec4 _entryPointOutput;
void main()
{
imageStore(RWIm, ivec2(uvec2(10u)), vec4(10.0, 0.5, 8.0, 2.0));
vec4 _69 = imageLoad(RWIm, ivec2(uvec2(30u)));
imageStore(RWBuf, int(80u), _69);
_entryPointOutput = (_69 + texelFetch(ROIm, ivec2(uvec2(50u, 60u)), 0)) + texelFetch(ROBuf, int(80u));
}

Просмотреть файл

@ -0,0 +1,30 @@
Texture2D<float4> uSampler : register(t0);
SamplerState _uSampler_sampler : register(s0);
static float4 FragColor;
static float2 vTexCoord;
struct SPIRV_Cross_Input
{
float2 vTexCoord : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
float _19_tmp = uSampler.CalculateLevelOfDetail(_uSampler_sampler, vTexCoord);
FragColor = float2(_19_tmp, _19_tmp).xyxy;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vTexCoord = stage_input.vTexCoord;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

Просмотреть файл

@ -19,19 +19,19 @@ struct alias_2
alias_1 alias_1;
};
layout(binding = 0, std430) buffer _10_11
{
alias_2 alias;
} alias_3;
layout(binding = 1, std140) buffer _15_16
layout(binding = 0, std430) buffer alias_3
{
alias_2 alias;
} alias_4;
layout(binding = 1, std140) buffer alias_5
{
alias_2 alias;
} alias_6;
void main()
{
alias_2 alias_5 = alias_3.alias;
alias_4.alias = alias_5;
alias_2 alias_7 = alias_4.alias;
alias_6.alias = alias_7;
}

Просмотреть файл

@ -0,0 +1,24 @@
#version 450
layout(binding = 0, std430) buffer Foobar
{
vec4 _data[];
} Foobar_1;
layout(binding = 1, std430) buffer Foobaz
{
vec4 _data[];
} Foobaz_1;
layout(location = 0) out vec4 _entryPointOutput;
vec4 _main()
{
return Foobar_1._data[0] + Foobaz_1._data[0];
}
void main()
{
_entryPointOutput = _main();
}

Просмотреть файл

@ -0,0 +1,26 @@
#version 450
layout(binding = 1, rgba32f) uniform image2D RWIm;
layout(binding = 0, rgba32f) uniform writeonly imageBuffer RWBuf;
layout(binding = 1) uniform sampler2D ROIm;
layout(binding = 0) uniform samplerBuffer ROBuf;
layout(location = 0) out vec4 _entryPointOutput;
vec4 _main()
{
vec4 storeTemp = vec4(10.0, 0.5, 8.0, 2.0);
imageStore(RWIm, ivec2(uvec2(10u)), storeTemp);
vec4 v = imageLoad(RWIm, ivec2(uvec2(30u)));
imageStore(RWBuf, int(80u), v);
v += texelFetch(ROIm, ivec2(uvec2(50u, 60u)), 0);
v += texelFetch(ROBuf, int(80u));
return v;
}
void main()
{
vec4 _45 = _main();
_entryPointOutput = _45;
}

Просмотреть файл

@ -0,0 +1,10 @@
#version 450
layout(location = 0) in vec2 vTexCoord;
layout(binding = 0) uniform sampler2D uSampler;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = textureQueryLod(uSampler, vTexCoord).xyxy;
}

Просмотреть файл

@ -0,0 +1,56 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 2
; Bound: 29
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %_entryPointOutput
OpExecutionMode %main OriginUpperLeft
OpSource HLSL 500
OpName %main "main"
OpName %_main_ "@main("
OpName %Foobar "Foobar"
OpMemberName %Foobar 0 "@data"
OpName %Foobar_0 "Foobar"
OpName %Foobaz "Foobaz"
OpName %_entryPointOutput "@entryPointOutput"
OpDecorate %_runtimearr_v4float ArrayStride 16
OpMemberDecorate %Foobar 0 Offset 0
OpDecorate %Foobar BufferBlock
OpDecorate %Foobar_0 DescriptorSet 0
OpDecorate %Foobar_0 Binding 0
OpDecorate %Foobaz DescriptorSet 0
OpDecorate %Foobaz Binding 1
OpDecorate %_entryPointOutput Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%8 = OpTypeFunction %v4float
%_runtimearr_v4float = OpTypeRuntimeArray %v4float
%Foobar = OpTypeStruct %_runtimearr_v4float
%_ptr_Uniform_Foobar = OpTypePointer Uniform %Foobar
%Foobar_0 = OpVariable %_ptr_Uniform_Foobar Uniform
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%Foobaz = OpVariable %_ptr_Uniform_Foobar Uniform
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
%main = OpFunction %void None %3
%5 = OpLabel
%28 = OpFunctionCall %v4float %_main_
OpStore %_entryPointOutput %28
OpReturn
OpFunctionEnd
%_main_ = OpFunction %v4float None %8
%10 = OpLabel
%18 = OpAccessChain %_ptr_Uniform_v4float %Foobar_0 %int_0 %int_0
%19 = OpLoad %v4float %18
%21 = OpAccessChain %_ptr_Uniform_v4float %Foobaz %int_0 %int_0
%22 = OpLoad %v4float %21
%23 = OpFAdd %v4float %19 %22
OpReturnValue %23
OpFunctionEnd

Просмотреть файл

@ -0,0 +1,103 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 2
; Bound: 63
; Schema: 0
OpCapability Shader
OpCapability SampledBuffer
OpCapability ImageBuffer
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %_entryPointOutput
OpExecutionMode %main OriginUpperLeft
OpSource HLSL 500
OpName %main "main"
OpName %_main_ "@main("
OpName %storeTemp "storeTemp"
OpName %RWIm "RWIm"
OpName %v "v"
OpName %RWBuf "RWBuf"
OpName %ROIm "ROIm"
OpName %ROBuf "ROBuf"
OpName %_entryPointOutput "@entryPointOutput"
OpDecorate %RWIm DescriptorSet 0
OpDecorate %RWIm Binding 1
OpDecorate %RWBuf DescriptorSet 0
OpDecorate %RWBuf Binding 0
OpDecorate %ROIm DescriptorSet 0
OpDecorate %ROIm Binding 1
OpDecorate %ROBuf DescriptorSet 0
OpDecorate %ROBuf Binding 0
OpDecorate %_entryPointOutput Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%8 = OpTypeFunction %v4float
%_ptr_Function_v4float = OpTypePointer Function %v4float
%float_10 = OpConstant %float 10
%float_0_5 = OpConstant %float 0.5
%float_8 = OpConstant %float 8
%float_2 = OpConstant %float 2
%17 = OpConstantComposite %v4float %float_10 %float_0_5 %float_8 %float_2
%18 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
%RWIm = OpVariable %_ptr_UniformConstant_18 UniformConstant
%uint = OpTypeInt 32 0
%v2uint = OpTypeVector %uint 2
%uint_10 = OpConstant %uint 10
%25 = OpConstantComposite %v2uint %uint_10 %uint_10
%uint_30 = OpConstant %uint 30
%30 = OpConstantComposite %v2uint %uint_30 %uint_30
%32 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f
%_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32
%RWBuf = OpVariable %_ptr_UniformConstant_32 UniformConstant
%uint_80 = OpConstant %uint 80
%38 = OpTypeImage %float 2D 0 0 0 1 Unknown
%SampledImage = OpTypeSampledImage %38
%_ptr_UniformConstant_38 = OpTypePointer UniformConstant %SampledImage
%ROIm = OpVariable %_ptr_UniformConstant_38 UniformConstant
%uint_50 = OpConstant %uint 50
%uint_60 = OpConstant %uint 60
%44 = OpConstantComposite %v2uint %uint_50 %uint_60
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%50 = OpTypeImage %float Buffer 0 0 0 1 Rgba32f
%_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50
%ROBuf = OpVariable %_ptr_UniformConstant_50 UniformConstant
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
%main = OpFunction %void None %3
%5 = OpLabel
%62 = OpFunctionCall %v4float %_main_
OpStore %_entryPointOutput %62
OpReturn
OpFunctionEnd
%_main_ = OpFunction %v4float None %8
%10 = OpLabel
%storeTemp = OpVariable %_ptr_Function_v4float Function
%v = OpVariable %_ptr_Function_v4float Function
OpStore %storeTemp %17
%21 = OpLoad %18 %RWIm
%26 = OpLoad %v4float %storeTemp
OpImageWrite %21 %25 %26
%28 = OpLoad %18 %RWIm
%31 = OpImageRead %v4float %28 %30
OpStore %v %31
%35 = OpLoad %32 %RWBuf
%37 = OpLoad %v4float %v
OpImageWrite %35 %uint_80 %37
%41 = OpLoad %SampledImage %ROIm
%ROImage = OpImage %38 %41
%47 = OpImageFetch %v4float %ROImage %44 Lod %int_0
%48 = OpLoad %v4float %v
%49 = OpFAdd %v4float %48 %47
OpStore %v %49
%53 = OpLoad %50 %ROBuf
%54 = OpImageFetch %v4float %53 %uint_80
%55 = OpLoad %v4float %v
%56 = OpFAdd %v4float %55 %54
OpStore %v %56
%57 = OpLoad %v4float %v
OpReturnValue %57
OpFunctionEnd

Просмотреть файл

@ -679,7 +679,7 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
if (var.storage == StorageClassInput && interface_variable_exists_in_entry_point(var.self))
{
if (meta[type.self].decoration.decoration_flags & (1ull << DecorationBlock))
res.stage_inputs.push_back({ var.self, var.basetype, type.self, meta[type.self].decoration.alias });
res.stage_inputs.push_back({ var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
else
res.stage_inputs.push_back({ var.self, var.basetype, type.self, meta[var.self].decoration.alias });
}
@ -692,7 +692,7 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
else if (var.storage == StorageClassOutput && interface_variable_exists_in_entry_point(var.self))
{
if (meta[type.self].decoration.decoration_flags & (1ull << DecorationBlock))
res.stage_outputs.push_back({ var.self, var.basetype, type.self, meta[type.self].decoration.alias });
res.stage_outputs.push_back({ var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
else
res.stage_outputs.push_back({ var.self, var.basetype, type.self, meta[var.self].decoration.alias });
}
@ -700,24 +700,21 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
else if (type.storage == StorageClassUniform &&
(meta[type.self].decoration.decoration_flags & (1ull << DecorationBlock)))
{
auto &block_name = meta[type.self].decoration.alias;
res.uniform_buffers.push_back({ var.self, var.basetype, type.self,
block_name.empty() ? get_block_fallback_name(var.self) : block_name });
get_remapped_declared_block_name(var.self) });
}
// Old way to declare SSBOs.
else if (type.storage == StorageClassUniform &&
(meta[type.self].decoration.decoration_flags & (1ull << DecorationBufferBlock)))
{
auto &block_name = meta[type.self].decoration.alias;
res.storage_buffers.push_back({ var.self, var.basetype, type.self,
block_name.empty() ? get_block_fallback_name(var.self) : block_name });
get_remapped_declared_block_name(var.self) });
}
// Modern way to declare SSBOs.
else if (type.storage == StorageClassStorageBuffer)
{
auto &block_name = meta[type.self].decoration.alias;
res.storage_buffers.push_back({ var.self, var.basetype, type.self,
block_name.empty() ? get_block_fallback_name(var.self) : block_name });
get_remapped_declared_block_name(var.self) });
}
// Push constant blocks
else if (type.storage == StorageClassPushConstant)
@ -1180,7 +1177,10 @@ const std::string Compiler::get_fallback_name(uint32_t id) const
const std::string Compiler::get_block_fallback_name(uint32_t id) const
{
auto &var = get<SPIRVariable>(id);
return join("_", get<SPIRType>(var.basetype).self, "_", id);
if (get_name(id).empty())
return join("_", get<SPIRType>(var.basetype).self, "_", id);
else
return get_name(id);
}
uint64_t Compiler::get_decoration_mask(uint32_t id) const
@ -3802,3 +3802,17 @@ const std::vector<std::string> &Compiler::get_declared_extensions() const
{
return declared_extensions;
}
std::string Compiler::get_remapped_declared_block_name(uint32_t id) const
{
auto itr = declared_block_names.find(id);
if (itr != end(declared_block_names))
return itr->second;
else
{
auto &var = get<SPIRVariable>(id);
auto &type = get<SPIRType>(var.basetype);
auto &block_name = meta[type.self].decoration.alias;
return block_name.empty() ? get_block_fallback_name(id) : block_name;
}
}

Просмотреть файл

@ -410,6 +410,19 @@ public:
// Gets the list of all SPIR-V extensions which were declared in the SPIR-V module.
const std::vector<std::string> &get_declared_extensions() const;
// When declaring buffer blocks in GLSL, the name declared in the GLSL source
// might not be the same as the name declared in the SPIR-V module due to naming conflicts.
// In this case, SPIRV-Cross needs to find a fallback-name, and it might only
// be possible to know this name after compiling to GLSL.
// This is particularly important for HLSL input and UAVs which tends to reuse the same block type
// for multiple distinct blocks. For these cases it is not possible to modify the name of the type itself
// because it might be unique. Instead, you can use this interface to check after compilation which
// name was actually used if your input SPIR-V tends to have this problem.
// For other names like remapped names for variables, etc, it's generally enough to query the name of the variables
// after compiling, block names are an exception to this rule.
// ID is the name of a variable as returned by Resource::id, and must be a variable with a Block-like type.
std::string get_remapped_declared_block_name(uint32_t id) const;
protected:
const uint32_t *stream(const Instruction &instr) const
{
@ -729,6 +742,7 @@ protected:
std::vector<spv::Capability> declared_capabilities;
std::vector<std::string> declared_extensions;
std::unordered_map<uint32_t, std::string> declared_block_names;
};
}

Просмотреть файл

@ -1374,17 +1374,24 @@ void CompilerGLSL::emit_buffer_block_native(const SPIRVariable &var)
bool is_readonly = ssbo && (flags & (1ull << DecorationNonWritable)) != 0;
bool is_coherent = ssbo && (flags & (1ull << DecorationCoherent)) != 0;
add_resource_name(var.self);
// Block names should never alias.
// Block names should never alias, but from HLSL input they kind of can because block types are reused for UAVs ...
auto buffer_name = to_name(type.self, false);
// Shaders never use the block by interface name, so we don't
// have to track this other than updating name caches.
if (meta[type.self].decoration.alias.empty() || resource_names.find(buffer_name) != end(resource_names))
buffer_name = get_block_fallback_name(var.self);
else
resource_names.insert(buffer_name);
// Make sure we get something unique.
add_variable(resource_names, buffer_name);
// If for some reason buffer_name is an illegal name, make a final fallback to a workaround name.
// This cannot conflict with anything else, so we're safe now.
if (buffer_name.empty())
buffer_name = join("_", get<SPIRType>(var.basetype).self, "_", var.self);
// Save for post-reflection later.
declared_block_names[var.self] = buffer_name;
statement(layout_for_variable(var), is_coherent ? "coherent " : "", is_restrict ? "restrict " : "",
is_writeonly ? "writeonly " : "", is_readonly ? "readonly " : "", ssbo ? "buffer " : "uniform ",
@ -1402,6 +1409,7 @@ void CompilerGLSL::emit_buffer_block_native(const SPIRVariable &var)
i++;
}
add_resource_name(var.self);
end_scope_decl(to_name(var.self) + type_to_array_glsl(type));
statement("");
}
@ -1521,8 +1529,6 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
require_extension("GL_EXT_shader_io_blocks");
}
add_resource_name(var.self);
// Block names should never alias.
auto block_name = to_name(type.self, false);
@ -1546,6 +1552,7 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
i++;
}
add_resource_name(var.self);
end_scope_decl(join(to_name(var.self), type_to_array_glsl(type)));
statement("");
}
@ -3451,6 +3458,15 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, boo
// Only enclose the UV expression if needed.
auto coord_expr = (*swizzle_expr == '\0') ? to_expression(coord) : (to_enclosed_expression(coord) + swizzle_expr);
// texelFetch only takes int, not uint.
auto &coord_type = expression_type(coord);
if (coord_type.basetype == SPIRType::UInt)
{
auto expected_type = coord_type;
expected_type.basetype = SPIRType::Int;
coord_expr = bitcast_expression(expected_type, coord_type.basetype, coord_expr);
}
// textureLod on sampler2DArrayShadow and samplerCubeShadow does not exist in GLSL for some reason.
// To emulate this, we will have to use textureGrad with a constant gradient of 0.
// The workaround will assert that the LOD is in fact constant 0, or we cannot emit correct code.
@ -6366,6 +6382,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
}
else
{
// imageLoad only accepts int coords, not uint.
auto coord_expr = to_expression(ops[3]);
auto target_coord_type = expression_type(ops[3]);
target_coord_type.basetype = SPIRType::Int;
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[3]).basetype, coord_expr);
// Plain image load/store.
if (type.image.ms)
{
@ -6374,11 +6396,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
SPIRV_CROSS_THROW("Multisampled image used in OpImageRead, but unexpected operand mask was used.");
uint32_t samples = ops[5];
imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ",
to_expression(samples), ")");
imgexpr =
join("imageLoad(", to_expression(ops[2]), ", ", coord_expr, ", ", to_expression(samples), ")");
}
else
imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", to_expression(ops[3]), ")");
imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", coord_expr, ")");
imgexpr = remap_swizzle(get<SPIRType>(result_type), 4, imgexpr);
pure = false;
@ -6435,17 +6457,23 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
auto store_type = value_type;
store_type.vecsize = 4;
// imageStore only accepts int coords, not uint.
auto coord_expr = to_expression(ops[1]);
auto target_coord_type = expression_type(ops[1]);
target_coord_type.basetype = SPIRType::Int;
coord_expr = bitcast_expression(target_coord_type, expression_type(ops[1]).basetype, coord_expr);
if (type.image.ms)
{
uint32_t operands = ops[3];
if (operands != ImageOperandsSampleMask || length != 5)
SPIRV_CROSS_THROW("Multisampled image used in OpImageWrite, but unexpected operand mask was used.");
uint32_t samples = ops[4];
statement("imageStore(", to_expression(ops[0]), ", ", to_expression(ops[1]), ", ", to_expression(samples),
", ", remap_swizzle(store_type, value_type.vecsize, to_expression(ops[2])), ");");
statement("imageStore(", to_expression(ops[0]), ", ", coord_expr, ", ", to_expression(samples), ", ",
remap_swizzle(store_type, value_type.vecsize, to_expression(ops[2])), ");");
}
else
statement("imageStore(", to_expression(ops[0]), ", ", to_expression(ops[1]), ", ",
statement("imageStore(", to_expression(ops[0]), ", ", coord_expr, ", ",
remap_swizzle(store_type, value_type.vecsize, to_expression(ops[2])), ");");
if (var && variable_storage_is_aliased(*var))
@ -7249,9 +7277,8 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type, uint32_t id)
}
}
void CompilerGLSL::add_variable(unordered_set<string> &variables, uint32_t id)
void CompilerGLSL::add_variable(unordered_set<string> &variables, string &name)
{
auto &name = meta[id].decoration.alias;
if (name.empty())
return;
@ -7265,6 +7292,12 @@ void CompilerGLSL::add_variable(unordered_set<string> &variables, uint32_t id)
update_name_cache(variables, name);
}
void CompilerGLSL::add_variable(unordered_set<string> &variables, uint32_t id)
{
auto &name = meta[id].decoration.alias;
add_variable(variables, name);
}
void CompilerGLSL::add_local_variable_name(uint32_t id)
{
add_variable(local_variable_names, id);

Просмотреть файл

@ -488,6 +488,7 @@ protected:
void remap_pls_variables();
void add_variable(std::unordered_set<std::string> &variables, uint32_t id);
void add_variable(std::unordered_set<std::string> &variables, std::string &name);
void check_function_call_constraints(const uint32_t *args, uint32_t length);
void handle_invalid_expression(uint32_t id);
void find_static_extensions();

Просмотреть файл

@ -1880,6 +1880,11 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
proj = true;
break;
case OpImageQueryLod:
opt = &ops[4];
length -= 4;
break;
default:
opt = &ops[4];
length -= 4;
@ -1961,6 +1966,11 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
texop += img_expr;
texop += ".Load";
}
else if (op == OpImageQueryLod)
{
texop += img_expr;
texop += ".CalculateLevelOfDetail";
}
else
{
auto &imgformat = get<SPIRType>(imgtype.image.type);
@ -2144,11 +2154,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
if (imgtype.image.dim != DimBuffer)
coord_expr = join("int", coordtype.vecsize + 1, "(", coord_expr, ", ", to_expression(lod), ")");
}
if (op != OpImageFetch)
{
else
expr += ", ";
}
expr += coord_expr;
if (dref)
@ -2203,7 +2210,21 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
expr += ")";
emit_op(result_type, id, expr, forward, false);
if (op == OpImageQueryLod)
{
// This is rather awkward.
// textureQueryLod returns two values, the "accessed level",
// as well as the actual LOD lambda.
// As far as I can tell, there is no way to get the .x component
// according to GLSL spec, and it depends on the sampler itself.
// Just assume X == Y, so we will need to splat the result to a float2.
statement("float _", id, "_tmp = ", expr, ";");
emit_op(result_type, id, join("float2(_", id, "_tmp, _", id, "_tmp)"), true, true);
}
else
{
emit_op(result_type, id, expr, forward, false);
}
}
string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
@ -3236,6 +3257,10 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
break;
}
case OpImageQueryLod:
emit_texture_op(instruction);
break;
case OpImageQuerySizeLod:
{
auto result_type = ops[0];