Remap swizzle for HLSL and RWBuffer.

This commit is contained in:
Hans-Kristian Arntzen 2017-10-24 09:52:12 +02:00
parent ab3f114120
commit a95295cb23
6 changed files with 216 additions and 11 deletions

View File

@ -14,7 +14,7 @@ void comp_main()
uint _27;
InterlockedAdd(uImage[int2(1, 5)], 1u, _27);
int _28 = int(_27);
iImage[int2(1, 6)] = int4(_28, _28, _28, _28);
iImage[int2(1, 6)] = int4(_28, _28, _28, _28).x;
uint _32;
InterlockedOr(uImage[int2(1, 5)], 1u, _32);
uint _34;

View File

@ -1,5 +1,27 @@
RWTexture2D<float> uImageIn : register(u0);
RWTexture2D<float> uImageOut : register(u1);
RWTexture2D<float> uImageInF : register(u0);
RWTexture2D<float> uImageOutF : register(u1);
RWTexture2D<int> uImageInI : register(u2);
RWTexture2D<int> uImageOutI : register(u3);
RWTexture2D<uint> uImageInU : register(u4);
RWTexture2D<uint> uImageOutU : register(u5);
RWBuffer<float> uImageInBuffer : register(u6);
RWBuffer<float> uImageOutBuffer : register(u7);
RWTexture2D<float2> uImageInF2 : register(u0);
RWTexture2D<float2> uImageOutF2 : register(u1);
RWTexture2D<int2> uImageInI2 : register(u2);
RWTexture2D<int2> uImageOutI2 : register(u3);
RWTexture2D<uint2> uImageInU2 : register(u4);
RWTexture2D<uint2> uImageOutU2 : register(u5);
RWBuffer<float2> uImageInBuffer2 : register(u6);
RWBuffer<float2> uImageOutBuffer2 : register(u7);
RWTexture2D<float4> uImageInF4 : register(u0);
RWTexture2D<float4> uImageOutF4 : register(u1);
RWTexture2D<int4> uImageInI4 : register(u2);
RWTexture2D<int4> uImageOutI4 : register(u3);
RWTexture2D<uint4> uImageInU4 : register(u4);
RWTexture2D<uint4> uImageOutU4 : register(u5);
RWBuffer<float4> uImageInBuffer4 : register(u6);
RWBuffer<float4> uImageOutBuffer4 : register(u7);
static uint3 gl_GlobalInvocationID;
struct SPIRV_Cross_Input
@ -9,8 +31,30 @@ struct SPIRV_Cross_Input
void comp_main()
{
float4 v = uImageIn[int2(gl_GlobalInvocationID.xy)];
uImageOut[int2(gl_GlobalInvocationID.xy)] = v;
float4 f = float4(uImageInF[int2(gl_GlobalInvocationID.xy)]);
uImageOutF[int2(gl_GlobalInvocationID.xy)] = f.x;
int4 i = int4(uImageInI[int2(gl_GlobalInvocationID.xy)]);
uImageOutI[int2(gl_GlobalInvocationID.xy)] = i.x;
uint4 u = uint4(uImageInU[int2(gl_GlobalInvocationID.xy)]);
uImageOutU[int2(gl_GlobalInvocationID.xy)] = u.x;
float4 b = float4(uImageInBuffer[int(gl_GlobalInvocationID.x)]);
uImageOutBuffer[int(gl_GlobalInvocationID.x)] = b.x;
float4 f2 = uImageInF2[int2(gl_GlobalInvocationID.xy)].xyyy;
uImageOutF2[int2(gl_GlobalInvocationID.xy)] = f2.xy;
int4 i2 = uImageInI2[int2(gl_GlobalInvocationID.xy)].xyyy;
uImageOutI2[int2(gl_GlobalInvocationID.xy)] = i2.xy;
uint4 u2 = uImageInU2[int2(gl_GlobalInvocationID.xy)].xyyy;
uImageOutU2[int2(gl_GlobalInvocationID.xy)] = u2.xy;
float4 b2 = uImageInBuffer2[int(gl_GlobalInvocationID.x)].xyyy;
uImageOutBuffer2[int(gl_GlobalInvocationID.x)] = b2.xy;
float4 f4 = uImageInF4[int2(gl_GlobalInvocationID.xy)];
uImageOutF4[int2(gl_GlobalInvocationID.xy)] = f4;
int4 i4 = uImageInI4[int2(gl_GlobalInvocationID.xy)];
uImageOutI4[int2(gl_GlobalInvocationID.xy)] = i4;
uint4 u4 = uImageInU4[int2(gl_GlobalInvocationID.xy)];
uImageOutU4[int2(gl_GlobalInvocationID.xy)] = u4;
float4 b4 = uImageInBuffer4[int(gl_GlobalInvocationID.x)];
uImageOutBuffer4[int(gl_GlobalInvocationID.x)] = b4;
}
[numthreads(1, 1, 1)]

View File

@ -0,0 +1,21 @@
Buffer<float4> uSamp : register(t4);
RWBuffer<float4> uSampo : register(u5);
static float4 gl_Position;
struct SPIRV_Cross_Output
{
float4 gl_Position : SV_Position;
};
void vert_main()
{
gl_Position = uSamp.Load(10) + uSampo[100];
}
SPIRV_Cross_Output main()
{
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
return stage_output;
}

View File

@ -1,12 +1,69 @@
#version 450
layout(local_size_x = 1) in;
layout(r32f, binding = 0) uniform readonly mediump image2D uImageIn;
layout(r32f, binding = 1) uniform writeonly mediump image2D uImageOut;
layout(r32f, binding = 0) uniform readonly image2D uImageInF;
layout(r32f, binding = 1) uniform writeonly image2D uImageOutF;
layout(r32i, binding = 2) uniform readonly iimage2D uImageInI;
layout(r32i, binding = 3) uniform writeonly iimage2D uImageOutI;
layout(r32ui, binding = 4) uniform readonly uimage2D uImageInU;
layout(r32ui, binding = 5) uniform writeonly uimage2D uImageOutU;
layout(r32f, binding = 6) uniform readonly imageBuffer uImageInBuffer;
layout(r32f, binding = 7) uniform writeonly imageBuffer uImageOutBuffer;
layout(rg32f, binding = 0) uniform readonly image2D uImageInF2;
layout(rg32f, binding = 1) uniform writeonly image2D uImageOutF2;
layout(rg32i, binding = 2) uniform readonly iimage2D uImageInI2;
layout(rg32i, binding = 3) uniform writeonly iimage2D uImageOutI2;
layout(rg32ui, binding = 4) uniform readonly uimage2D uImageInU2;
layout(rg32ui, binding = 5) uniform writeonly uimage2D uImageOutU2;
layout(rg32f, binding = 6) uniform readonly imageBuffer uImageInBuffer2;
layout(rg32f, binding = 7) uniform writeonly imageBuffer uImageOutBuffer2;
layout(rgba32f, binding = 0) uniform readonly image2D uImageInF4;
layout(rgba32f, binding = 1) uniform writeonly image2D uImageOutF4;
layout(rgba32i, binding = 2) uniform readonly iimage2D uImageInI4;
layout(rgba32i, binding = 3) uniform writeonly iimage2D uImageOutI4;
layout(rgba32ui, binding = 4) uniform readonly uimage2D uImageInU4;
layout(rgba32ui, binding = 5) uniform writeonly uimage2D uImageOutU4;
layout(rgba32f, binding = 6) uniform readonly imageBuffer uImageInBuffer4;
layout(rgba32f, binding = 7) uniform writeonly imageBuffer uImageOutBuffer4;
void main()
{
vec4 v = imageLoad(uImageIn, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOut, ivec2(gl_GlobalInvocationID.xy), v);
vec4 f = imageLoad(uImageInF, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutF, ivec2(gl_GlobalInvocationID.xy), f);
ivec4 i = imageLoad(uImageInI, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutI, ivec2(gl_GlobalInvocationID.xy), i);
uvec4 u = imageLoad(uImageInU, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutU, ivec2(gl_GlobalInvocationID.xy), u);
vec4 b = imageLoad(uImageInBuffer, int(gl_GlobalInvocationID.x));
imageStore(uImageOutBuffer, int(gl_GlobalInvocationID.x), b);
vec4 f2 = imageLoad(uImageInF2, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutF2, ivec2(gl_GlobalInvocationID.xy), f2);
ivec4 i2 = imageLoad(uImageInI2, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutI2, ivec2(gl_GlobalInvocationID.xy), i2);
uvec4 u2 = imageLoad(uImageInU2, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutU2, ivec2(gl_GlobalInvocationID.xy), u2);
vec4 b2 = imageLoad(uImageInBuffer2, int(gl_GlobalInvocationID.x));
imageStore(uImageOutBuffer2, int(gl_GlobalInvocationID.x), b2);
vec4 f4 = imageLoad(uImageInF4, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutF4, ivec2(gl_GlobalInvocationID.xy), f4);
ivec4 i4 = imageLoad(uImageInI4, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutI4, ivec2(gl_GlobalInvocationID.xy), i4);
uvec4 u4 = imageLoad(uImageInU4, ivec2(gl_GlobalInvocationID.xy));
imageStore(uImageOutU4, ivec2(gl_GlobalInvocationID.xy), u4);
vec4 b4 = imageLoad(uImageInBuffer4, int(gl_GlobalInvocationID.x));
imageStore(uImageOutBuffer4, int(gl_GlobalInvocationID.x), b4);
}

View File

@ -0,0 +1,9 @@
#version 450
layout(binding = 4) uniform samplerBuffer uSamp;
layout(rgba32f, binding = 5) uniform readonly imageBuffer uSampo;
void main()
{
gl_Position = texelFetch(uSamp, 10) + imageLoad(uSampo, 100);
}

View File

@ -23,6 +23,62 @@ using namespace spv;
using namespace spirv_cross;
using namespace std;
static unsigned image_format_to_components(ImageFormat fmt)
{
switch (fmt)
{
case ImageFormatR8:
case ImageFormatR16:
case ImageFormatR8Snorm:
case ImageFormatR16Snorm:
case ImageFormatR16f:
case ImageFormatR32f:
case ImageFormatR8i:
case ImageFormatR16i:
case ImageFormatR32i:
case ImageFormatR8ui:
case ImageFormatR16ui:
case ImageFormatR32ui:
return 1;
case ImageFormatRg8:
case ImageFormatRg16:
case ImageFormatRg8Snorm:
case ImageFormatRg16Snorm:
case ImageFormatRg16f:
case ImageFormatRg32f:
case ImageFormatRg8i:
case ImageFormatRg16i:
case ImageFormatRg32i:
case ImageFormatRg8ui:
case ImageFormatRg16ui:
case ImageFormatRg32ui:
return 2;
case ImageFormatR11fG11fB10f:
return 3;
case ImageFormatRgba8:
case ImageFormatRgba16:
case ImageFormatRgb10A2:
case ImageFormatRgba8Snorm:
case ImageFormatRgba16Snorm:
case ImageFormatRgba16f:
case ImageFormatRgba32f:
case ImageFormatRgba8i:
case ImageFormatRgba16i:
case ImageFormatRgba32i:
case ImageFormatRgba8ui:
case ImageFormatRgba16ui:
case ImageFormatRgba32ui:
case ImageFormatRgb10a2ui:
return 4;
default:
SPIRV_CROSS_THROW("Unrecognized typed image format.");
}
}
static string image_format_to_type(ImageFormat fmt)
{
switch (fmt)
@ -148,7 +204,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(imagetype.image.format), components, ">");
return join("RWBuffer<", image_format_to_type(type.image.format), ">");
else
SPIRV_CROSS_THROW("Sampler buffers must be either sampled or unsampled. Cannot deduce in runtime.");
case DimSubpassData:
@ -2745,6 +2801,12 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
auto *var = maybe_get_backing_variable(ops[2]);
auto imgexpr = join(to_expression(ops[2]), "[", to_expression(ops[3]), "]");
// The underlying image type in HLSL depends on the image format, unlike GLSL, where all images are "vec4",
// except that the underlying type changes how the data is interpreted.
if (var)
imgexpr = remap_swizzle(get<SPIRType>(result_type),
image_format_to_components(get<SPIRType>(var->basetype).image.format), imgexpr);
if (var && var->forwardable)
{
auto &e = emit_op(result_type, id, imgexpr, true);
@ -2759,7 +2821,19 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
case OpImageWrite:
{
auto *var = maybe_get_backing_variable(ops[0]);
statement(to_expression(ops[0]), "[", to_expression(ops[1]), "] = ", to_expression(ops[2]), ";");
// The underlying image type in HLSL depends on the image format, unlike GLSL, where all images are "vec4",
// except that the underlying type changes how the data is interpreted.
auto value_expr = to_expression(ops[2]);
if (var)
{
auto &type = get<SPIRType>(var->basetype);
auto narrowed_type = get<SPIRType>(type.image.type);
narrowed_type.vecsize = image_format_to_components(type.image.format);
value_expr = remap_swizzle(narrowed_type, expression_type(ops[2]).vecsize, value_expr);
}
statement(to_expression(ops[0]), "[", to_expression(ops[1]), "] = ", value_expr, ";");
if (var && variable_storage_is_aliased(*var))
flush_all_aliased_variables();
break;