rpcsx/rpcs3/Emu/RSX/Program/GLSLSnippets/CopyBufferToImage.glsl

234 lines
6.6 KiB
Plaintext
Raw Normal View History

R"(
#version 430
#extension GL_ARB_shader_stencil_export : enable
#define ENABLE_DEPTH_STENCIL_LOAD %stencil_export_supported
#define FMT_GL_DEPTH_COMPONENT16 0x81A5
#define FMT_GL_DEPTH_COMPONENT32F 0x8CAC
#define FMT_GL_DEPTH24_STENCIL8 0x88F0
#define FMT_GL_DEPTH32F_STENCIL8 0x8CAD
#define FMT_GL_RGBA8 0x8058
#define FMT_GL_BGRA8 0x80E1
#define FMT_GL_RGB565 0x8D62
#define FMT_GL_RGB5_A1 0x8057
#define FMT_GL_BGR5_A1 0x99F0
#define FMT_GL_RGBA4 0x8056
#define FMT_GL_R8 0x8229
#define FMT_GL_R16 0x822A
#define FMT_GL_R32F 0x822E
#define FMT_GL_RG8 0x822B
#define FMT_GL_RG8_SNORM 0x8F95
#define FMT_GL_RG16 0x822C
#define FMT_GL_RG16F 0x822F
#define FMT_GL_RGBA16F 0x881A
#define FMT_GL_RGBA32F 0x8814
#define bswap_u16(bits) (bits & 0xFF) << 8 | (bits & 0xFF00) >> 8 | (bits & 0xFF0000) << 8 | (bits & 0xFF000000) >> 8
#define bswap_u32(bits) (bits & 0xFF) << 24 | (bits & 0xFF00) << 8 | (bits & 0xFF0000) >> 8 | (bits & 0xFF000000) >> 24
layout(location=0) out vec4 fragColor;
layout(%set, binding=%loc, std430) readonly restrict buffer RawDataBlock
{
uint data[];
};
#if USE_UBO
layout(%push_block) uniform UnpackConfiguration
{
uint swap_bytes;
uint src_pitch;
uint format;
};
#else
uniform uint swap_bytes;
uniform uint src_pitch;
uniform uint format;
#endif
uint getTexelOffset()
{
const ivec2 coords = ivec2(gl_FragCoord.xy);
return coords.y * src_pitch + coords.x;
}
// Decoders. Beware of multi-wide swapped types (e.g swap(16x2) != swap(32x1))
uint readUint8(const in uint address)
{
const uint block = address / 4;
const uint offset = address % 4;
return bitfieldExtract(data[block], int(offset) * 8, 8);
}
uint readUint16(const in uint address)
{
const uint block = address / 2;
const uint offset = address % 2;
const uint value = bitfieldExtract(data[block], int(offset) * 16, 16);
if (swap_bytes != 0)
{
return bswap_u16(value);
}
return value;
}
uint readUint32(const in uint address)
{
const uint value = data[address];
return (swap_bytes != 0) ? bswap_u32(value) : value;
}
uvec2 readUint24_8(const in uint address)
{
const uint raw_value = data[address];
const uint stencil = bitfieldExtract(raw_value, 0, 8);
if (swap_bytes != 0)
{
const uint depth = min(bswap_u32(raw_value), 0xffffff);
return uvec2(depth, stencil);
}
return uvec2(
bitfieldExtract(raw_value, 8, 24),
stencil
);
}
uvec2 readUint8x2(const in uint address)
{
const uint raw = readUint16(address);
return uvec2(bitfieldExtract(raw, 0, 8), bitfieldExtract(raw, 8, 8));
}
ivec2 readInt8x2(const in uint address)
{
const ivec2 raw = ivec2(readUint8x2(address));
return raw - (ivec2(greaterThan(raw, ivec2(127))) * 256);
}
#define readFixed8(address) readUint8(address) / 255.f
#define readFixed8x2(address) readUint8x2(address) / 255.f
#define readFixed8x2Snorm(address) readInt8x2(address) / 127.f
vec4 readFixed8x4(const in uint address)
{
const uint raw = readUint32(address);
return uvec4(
bitfieldExtract(raw, 0, 8),
bitfieldExtract(raw, 8, 8),
bitfieldExtract(raw, 16, 8),
bitfieldExtract(raw, 24, 8)
) / 255.f;
}
#define readFixed16(address) readUint16(uint(address)) / 65535.f
#define readFixed16x2(address) vec2(readFixed16(address * 2 + 0), readFixed16(address * 2 + 1))
#define readFixed16x4(address) vec4(readFixed16(address * 4 + 0), readFixed16(address * 4 + 1), readFixed16(address * 4 + 2), readFixed16(address * 4 + 3))
#define readFloat16(address) unpackHalf2x16(readUint16(uint(address))).x
#define readFloat16x2(address) vec2(readFloat16(address * 2 + 0), readFloat16(address * 2 + 1))
#define readFloat16x4(address) vec4(readFloat16(address * 4 + 0), readFloat16(address * 4 + 1), readFloat16(address * 4 + 2), readFloat16(address * 4 + 3))
#define readFloat32(address) uintBitsToFloat(readUint32(address))
#define readFloat32x4(address) uintBitsToFloat(uvec4(readUint32(address * 4 + 0), readUint32(address * 4 + 1), readUint32(address * 4 + 2), readUint32(address * 4 + 3)))
void main()
{
const uint texel_address = getTexelOffset();
uint utmp;
uvec2 utmp2;
switch (format)
{
// Depth formats
case FMT_GL_DEPTH_COMPONENT16:
gl_FragDepth = readFixed16(texel_address);
break;
case FMT_GL_DEPTH_COMPONENT32F:
gl_FragDepth = readFloat16(texel_address);
break;
#if ENABLE_DEPTH_STENCIL_LOAD
// Depth-stencil formats. Unsupported on NVIDIA due to missing extensions.
case FMT_GL_DEPTH24_STENCIL8:
case FMT_GL_DEPTH32F_STENCIL8:
utmp2 = readUint24_8(texel_address);
gl_FragDepth = float(utmp2.x) / 0xffffff;
gl_FragStencilRefARB = int(utmp2.y);
break;
#endif
// Simple color
case FMT_GL_RGBA8:
fragColor = readFixed8x4(texel_address);
break;
case FMT_GL_BGRA8:
fragColor = readFixed8x4(texel_address).bgra;
break;
case FMT_GL_R8:
fragColor.r = readFixed8(texel_address);
break;
case FMT_GL_R16:
fragColor.r = readFixed16(texel_address);
break;
case FMT_GL_R32F:
fragColor.r = readFloat32(texel_address);
break;
case FMT_GL_RG8:
fragColor.rg = readFixed8x2(texel_address);
break;
case FMT_GL_RG8_SNORM:
fragColor.rg = readFixed8x2Snorm(texel_address);
break;
case FMT_GL_RG16:
fragColor.rg = readFixed16x2(texel_address);
break;
case FMT_GL_RG16F:
fragColor.rg = readFloat16x2(texel_address);
break;
case FMT_GL_RGBA16F:
fragColor = readFloat16x4(texel_address);
break;
case FMT_GL_RGBA32F:
fragColor = readFloat32x4(texel_address);
break;
// Packed color
case FMT_GL_RGB565:
utmp = readUint16(texel_address);
fragColor.b = bitfieldExtract(utmp, 0, 5) / 31.f;
fragColor.g = bitfieldExtract(utmp, 5, 6) / 63.f;
fragColor.r = bitfieldExtract(utmp, 11, 5) / 31.f;
break;
case FMT_GL_BGR5_A1:
utmp = readUint16(texel_address);
fragColor.b = bitfieldExtract(utmp, 0, 5) / 31.f;
fragColor.g = bitfieldExtract(utmp, 5, 5) / 31.f;
fragColor.r = bitfieldExtract(utmp, 10, 5) / 31.f;
fragColor.a = bitfieldExtract(utmp, 15, 1) * 1.f;
break;
case FMT_GL_RGB5_A1:
utmp = readUint16(texel_address);
fragColor.a = bitfieldExtract(utmp, 0, 1) * 1.f;
fragColor.b = bitfieldExtract(utmp, 1, 5) / 31.f;
fragColor.g = bitfieldExtract(utmp, 6, 5) / 31.f;
fragColor.r = bitfieldExtract(utmp, 11, 5) / 31.f;
break;
case FMT_GL_RGBA4:
utmp = readUint16(texel_address);
fragColor.b = bitfieldExtract(utmp, 0, 4) / 15.f;
fragColor.g = bitfieldExtract(utmp, 4, 4) / 15.f;
fragColor.r = bitfieldExtract(utmp, 8, 4) / 15.f;
fragColor.a = bitfieldExtract(utmp, 12, 4) / 15.f;
break;
}
}
)"