Merge pull request #1366 from KhronosGroup/fix-1365
HLSL: Implement image queries for UAV images.
This commit is contained in:
commit
3c43f055df
8
reference/opt/shaders-hlsl/frag/image-query-uav.frag
Normal file
8
reference/opt/shaders-hlsl/frag/image-query-uav.frag
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
void frag_main()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
frag_main();
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
void frag_main()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
frag_main();
|
||||||
|
}
|
64
reference/shaders-hlsl/frag/image-query-uav.frag
Normal file
64
reference/shaders-hlsl/frag/image-query-uav.frag
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
RWTexture1D<float4> uImage1D : register(u0);
|
||||||
|
RWTexture2D<float2> uImage2D : register(u1);
|
||||||
|
RWTexture2DArray<float> uImage2DArray : register(u2);
|
||||||
|
RWTexture3D<unorm float4> uImage3D : register(u3);
|
||||||
|
RWBuffer<snorm float4> uImageBuffer : register(u6);
|
||||||
|
|
||||||
|
uint3 SPIRV_Cross_imageSize(RWTexture2DArray<float> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint3 ret;
|
||||||
|
Tex.GetDimensions(ret.x, ret.y, ret.z);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint2 SPIRV_Cross_imageSize(RWTexture2D<float2> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint2 ret;
|
||||||
|
Tex.GetDimensions(ret.x, ret.y);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint SPIRV_Cross_imageSize(RWTexture1D<float4> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint ret;
|
||||||
|
Tex.GetDimensions(ret.x);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint3 SPIRV_Cross_imageSize(RWTexture3D<unorm float4> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint3 ret;
|
||||||
|
Tex.GetDimensions(ret.x, ret.y, ret.z);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint SPIRV_Cross_imageSize(RWBuffer<snorm float4> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint ret;
|
||||||
|
Tex.GetDimensions(ret.x);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void frag_main()
|
||||||
|
{
|
||||||
|
uint _14_dummy_parameter;
|
||||||
|
int a = int(SPIRV_Cross_imageSize(uImage1D, _14_dummy_parameter));
|
||||||
|
uint _22_dummy_parameter;
|
||||||
|
int2 b = int2(SPIRV_Cross_imageSize(uImage2D, _22_dummy_parameter));
|
||||||
|
uint _30_dummy_parameter;
|
||||||
|
int3 c = int3(SPIRV_Cross_imageSize(uImage2DArray, _30_dummy_parameter));
|
||||||
|
uint _36_dummy_parameter;
|
||||||
|
int3 d = int3(SPIRV_Cross_imageSize(uImage3D, _36_dummy_parameter));
|
||||||
|
uint _42_dummy_parameter;
|
||||||
|
int e = int(SPIRV_Cross_imageSize(uImageBuffer, _42_dummy_parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
frag_main();
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
RWTexture1D<float4> uImage1D : register(u0);
|
||||||
|
RWTexture2D<float2> uImage2D : register(u1);
|
||||||
|
Texture2DArray<float4> uImage2DArray : register(t2);
|
||||||
|
RWTexture3D<unorm float4> uImage3D : register(u3);
|
||||||
|
RWBuffer<snorm float4> uImageBuffer : register(u6);
|
||||||
|
|
||||||
|
uint3 SPIRV_Cross_textureSize(Texture2DArray<float4> Tex, uint Level, out uint Param)
|
||||||
|
{
|
||||||
|
uint3 ret;
|
||||||
|
Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint2 SPIRV_Cross_imageSize(RWTexture2D<float2> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint2 ret;
|
||||||
|
Tex.GetDimensions(ret.x, ret.y);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint SPIRV_Cross_imageSize(RWTexture1D<float4> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint ret;
|
||||||
|
Tex.GetDimensions(ret.x);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint3 SPIRV_Cross_imageSize(RWTexture3D<unorm float4> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint3 ret;
|
||||||
|
Tex.GetDimensions(ret.x, ret.y, ret.z);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint SPIRV_Cross_imageSize(RWBuffer<snorm float4> Tex, out uint Param)
|
||||||
|
{
|
||||||
|
uint ret;
|
||||||
|
Tex.GetDimensions(ret.x);
|
||||||
|
Param = 0u;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void frag_main()
|
||||||
|
{
|
||||||
|
uint _14_dummy_parameter;
|
||||||
|
int a = int(SPIRV_Cross_imageSize(uImage1D, _14_dummy_parameter));
|
||||||
|
uint _22_dummy_parameter;
|
||||||
|
int2 b = int2(SPIRV_Cross_imageSize(uImage2D, _22_dummy_parameter));
|
||||||
|
uint _30_dummy_parameter;
|
||||||
|
int3 c = int3(SPIRV_Cross_textureSize(uImage2DArray, 0u, _30_dummy_parameter));
|
||||||
|
uint _36_dummy_parameter;
|
||||||
|
int3 d = int3(SPIRV_Cross_imageSize(uImage3D, _36_dummy_parameter));
|
||||||
|
uint _42_dummy_parameter;
|
||||||
|
int e = int(SPIRV_Cross_imageSize(uImageBuffer, _42_dummy_parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
frag_main();
|
||||||
|
}
|
18
shaders-hlsl/frag/image-query-uav.frag
Normal file
18
shaders-hlsl/frag/image-query-uav.frag
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(rgba32f, binding = 0) uniform writeonly image1D uImage1D;
|
||||||
|
layout(rg32f, binding = 1) uniform writeonly image2D uImage2D;
|
||||||
|
layout(r32f, binding = 2) uniform readonly image2DArray uImage2DArray;
|
||||||
|
layout(rgba8, binding = 3) uniform writeonly image3D uImage3D;
|
||||||
|
layout(rgba8_snorm, binding = 6) uniform writeonly imageBuffer uImageBuffer;
|
||||||
|
|
||||||
|
// There is no RWTexture2DMS.
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int a = imageSize(uImage1D);
|
||||||
|
ivec2 b = imageSize(uImage2D);
|
||||||
|
ivec3 c = imageSize(uImage2DArray);
|
||||||
|
ivec3 d = imageSize(uImage3D);
|
||||||
|
int e = imageSize(uImageBuffer);
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(rgba32f, binding = 0) uniform writeonly image1D uImage1D;
|
||||||
|
layout(rg32f, binding = 1) uniform writeonly image2D uImage2D;
|
||||||
|
layout(r32f, binding = 2) uniform readonly image2DArray uImage2DArray;
|
||||||
|
layout(rgba8, binding = 3) uniform writeonly image3D uImage3D;
|
||||||
|
layout(rgba8_snorm, binding = 6) uniform writeonly imageBuffer uImageBuffer;
|
||||||
|
|
||||||
|
// There is no RWTexture2DMS.
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int a = imageSize(uImage1D);
|
||||||
|
ivec2 b = imageSize(uImage2D);
|
||||||
|
ivec3 c = imageSize(uImage2DArray);
|
||||||
|
ivec3 d = imageSize(uImage3D);
|
||||||
|
int e = imageSize(uImageBuffer);
|
||||||
|
}
|
224
spirv_hlsl.cpp
224
spirv_hlsl.cpp
@ -23,6 +23,41 @@ using namespace spv;
|
|||||||
using namespace SPIRV_CROSS_NAMESPACE;
|
using namespace SPIRV_CROSS_NAMESPACE;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
enum class ImageFormatNormalizedState
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Unorm = 1,
|
||||||
|
Snorm = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
static ImageFormatNormalizedState image_format_to_normalized_state(ImageFormat fmt)
|
||||||
|
{
|
||||||
|
switch (fmt)
|
||||||
|
{
|
||||||
|
case ImageFormatR8:
|
||||||
|
case ImageFormatR16:
|
||||||
|
case ImageFormatRg8:
|
||||||
|
case ImageFormatRg16:
|
||||||
|
case ImageFormatRgba8:
|
||||||
|
case ImageFormatRgba16:
|
||||||
|
case ImageFormatRgb10A2:
|
||||||
|
return ImageFormatNormalizedState::Unorm;
|
||||||
|
|
||||||
|
case ImageFormatR8Snorm:
|
||||||
|
case ImageFormatR16Snorm:
|
||||||
|
case ImageFormatRg8Snorm:
|
||||||
|
case ImageFormatRg16Snorm:
|
||||||
|
case ImageFormatRgba8Snorm:
|
||||||
|
case ImageFormatRgba16Snorm:
|
||||||
|
return ImageFormatNormalizedState::Snorm;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImageFormatNormalizedState::None;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned image_format_to_components(ImageFormat fmt)
|
static unsigned image_format_to_components(ImageFormat fmt)
|
||||||
{
|
{
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
@ -1423,66 +1458,14 @@ void CompilerHLSL::emit_resources()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (required_textureSizeVariants != 0)
|
emit_texture_size_variants(required_texture_size_variants.srv, "4", false, "");
|
||||||
|
for (uint32_t norm = 0; norm < 3; norm++)
|
||||||
{
|
{
|
||||||
static const char *types[QueryTypeCount] = { "float4", "int4", "uint4" };
|
for (uint32_t comp = 0; comp < 4; comp++)
|
||||||
static const char *dims[QueryDimCount] = { "Texture1D", "Texture1DArray", "Texture2D", "Texture2DArray",
|
|
||||||
"Texture3D", "Buffer", "TextureCube", "TextureCubeArray",
|
|
||||||
"Texture2DMS", "Texture2DMSArray" };
|
|
||||||
|
|
||||||
static const bool has_lod[QueryDimCount] = { true, true, true, true, true, false, true, true, false, false };
|
|
||||||
|
|
||||||
static const char *ret_types[QueryDimCount] = {
|
|
||||||
"uint", "uint2", "uint2", "uint3", "uint3", "uint", "uint2", "uint3", "uint2", "uint3",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint32_t return_arguments[QueryDimCount] = {
|
|
||||||
1, 2, 2, 3, 3, 1, 2, 3, 2, 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (uint32_t index = 0; index < QueryDimCount; index++)
|
|
||||||
{
|
{
|
||||||
for (uint32_t type_index = 0; type_index < QueryTypeCount; type_index++)
|
static const char *qualifiers[] = { "", "unorm ", "snorm " };
|
||||||
{
|
static const char *vecsizes[] = { "", "2", "3", "4" };
|
||||||
uint32_t bit = 16 * type_index + index;
|
emit_texture_size_variants(required_texture_size_variants.uav[norm][comp], vecsizes[comp], true, qualifiers[norm]);
|
||||||
uint64_t mask = 1ull << bit;
|
|
||||||
|
|
||||||
if ((required_textureSizeVariants & mask) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
statement(ret_types[index], " SPIRV_Cross_textureSize(", dims[index], "<", types[type_index],
|
|
||||||
"> Tex, uint Level, out uint Param)");
|
|
||||||
begin_scope();
|
|
||||||
statement(ret_types[index], " ret;");
|
|
||||||
switch (return_arguments[index])
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (has_lod[index])
|
|
||||||
statement("Tex.GetDimensions(Level, ret.x, Param);");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
statement("Tex.GetDimensions(ret.x);");
|
|
||||||
statement("Param = 0u;");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (has_lod[index])
|
|
||||||
statement("Tex.GetDimensions(Level, ret.x, ret.y, Param);");
|
|
||||||
else
|
|
||||||
statement("Tex.GetDimensions(ret.x, ret.y, Param);");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (has_lod[index])
|
|
||||||
statement("Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param);");
|
|
||||||
else
|
|
||||||
statement("Tex.GetDimensions(ret.x, ret.y, ret.z, Param);");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
statement("return ret;");
|
|
||||||
end_scope();
|
|
||||||
statement("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1845,6 +1828,83 @@ void CompilerHLSL::emit_resources()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompilerHLSL::emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav, const char *type_qualifier)
|
||||||
|
{
|
||||||
|
if (variant_mask == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static const char *types[QueryTypeCount] = { "float", "int", "uint" };
|
||||||
|
static const char *dims[QueryDimCount] = { "Texture1D", "Texture1DArray", "Texture2D", "Texture2DArray",
|
||||||
|
"Texture3D", "Buffer", "TextureCube", "TextureCubeArray",
|
||||||
|
"Texture2DMS", "Texture2DMSArray" };
|
||||||
|
|
||||||
|
static const bool has_lod[QueryDimCount] = { true, true, true, true, true, false, true, true, false, false };
|
||||||
|
|
||||||
|
static const char *ret_types[QueryDimCount] = {
|
||||||
|
"uint", "uint2", "uint2", "uint3", "uint3", "uint", "uint2", "uint3", "uint2", "uint3",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t return_arguments[QueryDimCount] = {
|
||||||
|
1, 2, 2, 3, 3, 1, 2, 3, 2, 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t index = 0; index < QueryDimCount; index++)
|
||||||
|
{
|
||||||
|
for (uint32_t type_index = 0; type_index < QueryTypeCount; type_index++)
|
||||||
|
{
|
||||||
|
uint32_t bit = 16 * type_index + index;
|
||||||
|
uint64_t mask = 1ull << bit;
|
||||||
|
|
||||||
|
if ((variant_mask & mask) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
statement(ret_types[index], " SPIRV_Cross_", (uav ? "image" : "texture"), "Size(", (uav ? "RW" : ""),
|
||||||
|
dims[index], "<", type_qualifier, types[type_index], vecsize_qualifier,
|
||||||
|
"> Tex, ", (uav ? "" : "uint Level, "), "out uint Param)");
|
||||||
|
begin_scope();
|
||||||
|
statement(ret_types[index], " ret;");
|
||||||
|
switch (return_arguments[index])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (has_lod[index] && !uav)
|
||||||
|
statement("Tex.GetDimensions(Level, ret.x, Param);");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statement("Tex.GetDimensions(ret.x);");
|
||||||
|
statement("Param = 0u;");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (has_lod[index] && !uav)
|
||||||
|
statement("Tex.GetDimensions(Level, ret.x, ret.y, Param);");
|
||||||
|
else if (!uav)
|
||||||
|
statement("Tex.GetDimensions(ret.x, ret.y, Param);");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statement("Tex.GetDimensions(ret.x, ret.y);");
|
||||||
|
statement("Param = 0u;");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (has_lod[index] && !uav)
|
||||||
|
statement("Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param);");
|
||||||
|
else if (!uav)
|
||||||
|
statement("Tex.GetDimensions(ret.x, ret.y, ret.z, Param);");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statement("Tex.GetDimensions(ret.x, ret.y, ret.z);");
|
||||||
|
statement("Param = 0u;");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
statement("return ret;");
|
||||||
|
end_scope();
|
||||||
|
statement("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string CompilerHLSL::layout_for_member(const SPIRType &type, uint32_t index)
|
string CompilerHLSL::layout_for_member(const SPIRType &type, uint32_t index)
|
||||||
{
|
{
|
||||||
auto &flags = get_member_decoration_bitset(type.self, index);
|
auto &flags = get_member_decoration_bitset(type.self, index);
|
||||||
@ -4834,8 +4894,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||||||
auto result_type = ops[0];
|
auto result_type = ops[0];
|
||||||
auto id = ops[1];
|
auto id = ops[1];
|
||||||
|
|
||||||
require_texture_query_variant(expression_type(ops[2]));
|
require_texture_query_variant(ops[2]);
|
||||||
|
|
||||||
auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
|
auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
|
||||||
statement("uint ", dummy_samples_levels, ";");
|
statement("uint ", dummy_samples_levels, ";");
|
||||||
|
|
||||||
@ -4853,12 +4912,22 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||||||
auto result_type = ops[0];
|
auto result_type = ops[0];
|
||||||
auto id = ops[1];
|
auto id = ops[1];
|
||||||
|
|
||||||
require_texture_query_variant(expression_type(ops[2]));
|
require_texture_query_variant(ops[2]);
|
||||||
|
bool uav = expression_type(ops[2]).image.sampled == 2;
|
||||||
|
|
||||||
|
if (const auto *var = maybe_get_backing_variable(ops[2]))
|
||||||
|
if (hlsl_options.nonwritable_uav_texture_as_srv && has_decoration(var->self, DecorationNonWritable))
|
||||||
|
uav = false;
|
||||||
|
|
||||||
auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
|
auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
|
||||||
statement("uint ", dummy_samples_levels, ";");
|
statement("uint ", dummy_samples_levels, ";");
|
||||||
|
|
||||||
auto expr = join("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", 0u, ", dummy_samples_levels, ")");
|
string expr;
|
||||||
|
if (uav)
|
||||||
|
expr = join("SPIRV_Cross_imageSize(", to_expression(ops[2]), ", ", dummy_samples_levels, ")");
|
||||||
|
else
|
||||||
|
expr = join("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", 0u, ", dummy_samples_levels, ")");
|
||||||
|
|
||||||
auto &restype = get<SPIRType>(ops[0]);
|
auto &restype = get<SPIRType>(ops[0]);
|
||||||
expr = bitcast_expression(restype, SPIRType::UInt, expr);
|
expr = bitcast_expression(restype, SPIRType::UInt, expr);
|
||||||
emit_op(result_type, id, expr, true);
|
emit_op(result_type, id, expr, true);
|
||||||
@ -4871,13 +4940,24 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||||||
auto result_type = ops[0];
|
auto result_type = ops[0];
|
||||||
auto id = ops[1];
|
auto id = ops[1];
|
||||||
|
|
||||||
require_texture_query_variant(expression_type(ops[2]));
|
require_texture_query_variant(ops[2]);
|
||||||
|
bool uav = expression_type(ops[2]).image.sampled == 2;
|
||||||
|
if (opcode == OpImageQueryLevels && uav)
|
||||||
|
SPIRV_CROSS_THROW("Cannot query levels for UAV images.");
|
||||||
|
|
||||||
|
if (const auto *var = maybe_get_backing_variable(ops[2]))
|
||||||
|
if (hlsl_options.nonwritable_uav_texture_as_srv && has_decoration(var->self, DecorationNonWritable))
|
||||||
|
uav = false;
|
||||||
|
|
||||||
// Keep it simple and do not emit special variants to make this look nicer ...
|
// Keep it simple and do not emit special variants to make this look nicer ...
|
||||||
// This stuff is barely, if ever, used.
|
// This stuff is barely, if ever, used.
|
||||||
forced_temporaries.insert(id);
|
forced_temporaries.insert(id);
|
||||||
auto &type = get<SPIRType>(result_type);
|
auto &type = get<SPIRType>(result_type);
|
||||||
statement(variable_decl(type, to_name(id)), ";");
|
statement(variable_decl(type, to_name(id)), ";");
|
||||||
|
|
||||||
|
if (uav)
|
||||||
|
statement("SPIRV_Cross_imageSize(", to_expression(ops[2]), ", ", to_name(id), ");");
|
||||||
|
else
|
||||||
statement("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", 0u, ", to_name(id), ");");
|
statement("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", 0u, ", to_name(id), ");");
|
||||||
|
|
||||||
auto &restype = get<SPIRType>(ops[0]);
|
auto &restype = get<SPIRType>(ops[0]);
|
||||||
@ -5192,8 +5272,16 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerHLSL::require_texture_query_variant(const SPIRType &type)
|
void CompilerHLSL::require_texture_query_variant(uint32_t var_id)
|
||||||
{
|
{
|
||||||
|
if (const auto *var = maybe_get_backing_variable(var_id))
|
||||||
|
var_id = var->self;
|
||||||
|
|
||||||
|
auto &type = expression_type(var_id);
|
||||||
|
bool uav = type.image.sampled == 2;
|
||||||
|
if (hlsl_options.nonwritable_uav_texture_as_srv && has_decoration(var_id, DecorationNonWritable))
|
||||||
|
uav = false;
|
||||||
|
|
||||||
uint32_t bit = 0;
|
uint32_t bit = 0;
|
||||||
switch (type.image.dim)
|
switch (type.image.dim)
|
||||||
{
|
{
|
||||||
@ -5242,11 +5330,15 @@ void CompilerHLSL::require_texture_query_variant(const SPIRType &type)
|
|||||||
SPIRV_CROSS_THROW("Unsupported query type.");
|
SPIRV_CROSS_THROW("Unsupported query type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto norm_state = image_format_to_normalized_state(type.image.format);
|
||||||
|
auto &variant = uav ? required_texture_size_variants.uav[uint32_t(norm_state)][image_format_to_components(type.image.format) - 1] :
|
||||||
|
required_texture_size_variants.srv;
|
||||||
|
|
||||||
uint64_t mask = 1ull << bit;
|
uint64_t mask = 1ull << bit;
|
||||||
if ((required_textureSizeVariants & mask) == 0)
|
if ((variant & mask) == 0)
|
||||||
{
|
{
|
||||||
force_recompile();
|
force_recompile();
|
||||||
required_textureSizeVariants |= mask;
|
variant |= mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,8 +264,23 @@ private:
|
|||||||
bool requires_scalar_reflect = false;
|
bool requires_scalar_reflect = false;
|
||||||
bool requires_scalar_refract = false;
|
bool requires_scalar_refract = false;
|
||||||
bool requires_scalar_faceforward = false;
|
bool requires_scalar_faceforward = false;
|
||||||
uint64_t required_textureSizeVariants = 0;
|
|
||||||
void require_texture_query_variant(const SPIRType &type);
|
struct TextureSizeVariants
|
||||||
|
{
|
||||||
|
// MSVC 2013 workaround.
|
||||||
|
TextureSizeVariants()
|
||||||
|
{
|
||||||
|
srv = 0;
|
||||||
|
for (auto &unorm : uav)
|
||||||
|
for (auto &u : unorm)
|
||||||
|
u = 0;
|
||||||
|
}
|
||||||
|
uint64_t srv;
|
||||||
|
uint64_t uav[3][4];
|
||||||
|
} required_texture_size_variants;
|
||||||
|
|
||||||
|
void require_texture_query_variant(uint32_t var_id);
|
||||||
|
void emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav, const char *type_qualifier);
|
||||||
|
|
||||||
enum TextureQueryVariantDim
|
enum TextureQueryVariantDim
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user