Support image load-store without format in HLSL.

This commit is contained in:
Hans-Kristian Arntzen 2017-11-29 12:13:48 +01:00
parent c405274e38
commit c65248fdce
4 changed files with 88 additions and 9 deletions

View File

@ -22,6 +22,9 @@ RWTexture2D<uint4> uImageInU4 : register(u4);
RWTexture2D<uint4> uImageOutU4 : register(u5);
RWBuffer<float4> uImageInBuffer4 : register(u6);
RWBuffer<float4> uImageOutBuffer4 : register(u7);
RWTexture2D<float4> uImageNoFmtF : register(u8);
RWTexture2D<uint4> uImageNoFmtU : register(u9);
RWTexture2D<int4> uImageNoFmtI : register(u10);
static uint3 gl_GlobalInvocationID;
struct SPIRV_Cross_Input
@ -38,11 +41,17 @@ void comp_main()
uImageOutF2[int2(gl_GlobalInvocationID.xy)] = uImageInF2[int2(gl_GlobalInvocationID.xy)].xyyy.xy;
uImageOutI2[int2(gl_GlobalInvocationID.xy)] = uImageInI2[int2(gl_GlobalInvocationID.xy)].xyyy.xy;
uImageOutU2[int2(gl_GlobalInvocationID.xy)] = uImageInU2[int2(gl_GlobalInvocationID.xy)].xyyy.xy;
uImageOutBuffer2[int(gl_GlobalInvocationID.x)] = uImageInBuffer2[int(gl_GlobalInvocationID.x)].xyyy.xy;
float4 _135 = uImageInBuffer2[int(gl_GlobalInvocationID.x)].xyyy;
uImageOutBuffer2[int(gl_GlobalInvocationID.x)] = _135.xy;
uImageOutF4[int2(gl_GlobalInvocationID.xy)] = uImageInF4[int2(gl_GlobalInvocationID.xy)];
uImageOutI4[int2(gl_GlobalInvocationID.xy)] = uImageInI4[int2(gl_GlobalInvocationID.xy)];
uImageOutU4[int2(gl_GlobalInvocationID.xy)] = uImageInU4[int2(gl_GlobalInvocationID.xy)];
int4 _165 = uImageInI4[int2(gl_GlobalInvocationID.xy)];
uImageOutI4[int2(gl_GlobalInvocationID.xy)] = _165;
uint4 _180 = uImageInU4[int2(gl_GlobalInvocationID.xy)];
uImageOutU4[int2(gl_GlobalInvocationID.xy)] = _180;
uImageOutBuffer4[int(gl_GlobalInvocationID.x)] = uImageInBuffer4[int(gl_GlobalInvocationID.x)];
uImageNoFmtF[int2(gl_GlobalInvocationID.xy)] = _135;
uImageNoFmtU[int2(gl_GlobalInvocationID.xy)] = _180;
uImageNoFmtI[int2(gl_GlobalInvocationID.xy)] = _165;
}
[numthreads(1, 1, 1)]

View File

@ -22,6 +22,9 @@ RWTexture2D<uint4> uImageInU4 : register(u4);
RWTexture2D<uint4> uImageOutU4 : register(u5);
RWBuffer<float4> uImageInBuffer4 : register(u6);
RWBuffer<float4> uImageOutBuffer4 : register(u7);
RWTexture2D<float4> uImageNoFmtF : register(u8);
RWTexture2D<uint4> uImageNoFmtU : register(u9);
RWTexture2D<int4> uImageNoFmtI : register(u10);
static uint3 gl_GlobalInvocationID;
struct SPIRV_Cross_Input
@ -55,6 +58,9 @@ void comp_main()
uImageOutU4[int2(gl_GlobalInvocationID.xy)] = u4;
float4 b4 = uImageInBuffer4[int(gl_GlobalInvocationID.x)];
uImageOutBuffer4[int(gl_GlobalInvocationID.x)] = b4;
uImageNoFmtF[int2(gl_GlobalInvocationID.xy)] = b2;
uImageNoFmtU[int2(gl_GlobalInvocationID.xy)] = u4;
uImageNoFmtI[int2(gl_GlobalInvocationID.xy)] = i4;
}
[numthreads(1, 1, 1)]

View File

@ -28,6 +28,10 @@ layout(rgba32ui, binding = 5) uniform writeonly uimage2D uImageOutU4;
layout(rgba32f, binding = 6) uniform readonly imageBuffer uImageInBuffer4;
layout(rgba32f, binding = 7) uniform writeonly imageBuffer uImageOutBuffer4;
layout(binding = 8) uniform writeonly image2D uImageNoFmtF;
layout(binding = 9) uniform writeonly uimage2D uImageNoFmtU;
layout(binding = 10) uniform writeonly iimage2D uImageNoFmtI;
void main()
{
vec4 f = imageLoad(uImageInF, ivec2(gl_GlobalInvocationID.xy));
@ -65,5 +69,9 @@ void main()
vec4 b4 = imageLoad(uImageInBuffer4, int(gl_GlobalInvocationID.x));
imageStore(uImageOutBuffer4, int(gl_GlobalInvocationID.x), b4);
imageStore(uImageNoFmtF, ivec2(gl_GlobalInvocationID.xy), b2);
imageStore(uImageNoFmtU, ivec2(gl_GlobalInvocationID.xy), u4);
imageStore(uImageNoFmtI, ivec2(gl_GlobalInvocationID.xy), i4);
}

View File

@ -74,77 +74,129 @@ static unsigned image_format_to_components(ImageFormat fmt)
case ImageFormatRgb10a2ui:
return 4;
case ImageFormatUnknown:
return 4; // Assume 4.
default:
SPIRV_CROSS_THROW("Unrecognized typed image format.");
}
}
static string image_format_to_type(ImageFormat fmt)
static string image_format_to_type(ImageFormat fmt, SPIRType::BaseType basetype)
{
switch (fmt)
{
case ImageFormatR8:
case ImageFormatR16:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "unorm float";
case ImageFormatRg8:
case ImageFormatRg16:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "unorm float2";
case ImageFormatRgba8:
case ImageFormatRgba16:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "unorm float4";
case ImageFormatRgb10A2:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "unorm float4";
case ImageFormatR8Snorm:
case ImageFormatR16Snorm:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "snorm float";
case ImageFormatRg8Snorm:
case ImageFormatRg16Snorm:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "snorm float2";
case ImageFormatRgba8Snorm:
case ImageFormatRgba16Snorm:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "snorm float4";
case ImageFormatR16f:
case ImageFormatR32f:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "float";
case ImageFormatRg16f:
case ImageFormatRg32f:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "float2";
case ImageFormatRgba16f:
case ImageFormatRgba32f:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "float4";
case ImageFormatR11fG11fB10f:
if (basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "float3";
case ImageFormatR8i:
case ImageFormatR16i:
case ImageFormatR32i:
if (basetype != SPIRType::Int)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "int";
case ImageFormatRg8i:
case ImageFormatRg16i:
case ImageFormatRg32i:
if (basetype != SPIRType::Int)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "int2";
case ImageFormatRgba8i:
case ImageFormatRgba16i:
case ImageFormatRgba32i:
if (basetype != SPIRType::Int)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "int4";
case ImageFormatR8ui:
case ImageFormatR16ui:
case ImageFormatR32ui:
if (basetype != SPIRType::UInt)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "uint";
case ImageFormatRg8ui:
case ImageFormatRg16ui:
case ImageFormatRg32ui:
if (basetype != SPIRType::UInt)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "uint2";
case ImageFormatRgba8ui:
case ImageFormatRgba16ui:
case ImageFormatRgba32ui:
if (basetype != SPIRType::UInt)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "uint4";
case ImageFormatRgb10a2ui:
return "int4";
if (basetype != SPIRType::UInt)
SPIRV_CROSS_THROW("Mismatch in image type and base type of image.");
return "uint4";
case ImageFormatUnknown:
switch (basetype)
{
case SPIRType::Float:
return "float4";
case SPIRType::Int:
return "int4";
case SPIRType::UInt:
return "uint4";
default:
SPIRV_CROSS_THROW("Unsupported base type for image.");
}
default:
SPIRV_CROSS_THROW("Unrecognized typed image format.");
@ -204,7 +256,7 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type)
if (type.image.sampled == 1)
return join("Buffer<", type_to_glsl(imagetype), components, ">");
else if (type.image.sampled == 2)
return join("RWBuffer<", image_format_to_type(type.image.format), ">");
return join("RWBuffer<", image_format_to_type(type.image.format, imagetype.basetype), ">");
else
SPIRV_CROSS_THROW("Sampler buffers must be either sampled or unsampled. Cannot deduce in runtime.");
case DimSubpassData:
@ -217,7 +269,9 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type)
const char *ms = type.image.ms ? "MS" : "";
const char *rw = typed_load ? "RW" : "";
return join(rw, "Texture", dim, ms, arrayed, "<",
typed_load ? image_format_to_type(type.image.format) : join(type_to_glsl(imagetype), components), ">");
typed_load ? image_format_to_type(type.image.format, imagetype.basetype) :
join(type_to_glsl(imagetype), components),
">");
}
string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type)
@ -3242,9 +3296,11 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
if (var && var->forwardable)
{
auto &e = emit_op(result_type, id, imgexpr, true);
bool forward = forced_temporaries.find(id) == end(forced_temporaries);
auto &e = emit_op(result_type, id, imgexpr, forward);
e.loaded_from = var->self;
var->dependees.push_back(id);
if (forward)
var->dependees.push_back(id);
}
else
emit_op(result_type, id, imgexpr, false);