|
#version 430
|
|
|
|
#define FORCE_EARLY_Z layout(early_fragment_tests) in
|
|
|
|
#extension GL_ARB_shading_language_420pack : enable
|
|
|
|
#define ATTRIBUTE_LOCATION(x)
|
|
#define FRAGMENT_OUTPUT_LOCATION(x)
|
|
#define FRAGMENT_OUTPUT_LOCATION_INDEXED(x, y)
|
|
#define UBO_BINDING(packing, x) layout(packing, binding = x)
|
|
#define SAMPLER_BINDING(x) layout(binding = x)
|
|
#define SSBO_BINDING(x) layout(binding = x)
|
|
|
|
#define VARYING_LOCATION(x)
|
|
|
|
#extension GL_ARB_shader_storage_buffer_object : enable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define float2 vec2
|
|
#define float3 vec3
|
|
#define float4 vec4
|
|
#define uint2 uvec2
|
|
#define uint3 uvec3
|
|
#define uint4 uvec4
|
|
#define int2 ivec2
|
|
#define int3 ivec3
|
|
#define int4 ivec4
|
|
#define frac fract
|
|
#define lerp mix
|
|
#define PALETTE_FORMAT_RGB5A3 1
|
|
|
|
#ifdef VULKAN
|
|
|
|
layout(std140, push_constant) uniform PushConstants {
|
|
uvec2 dst_size;
|
|
uvec2 src_size;
|
|
uint src_offset;
|
|
uint src_row_stride;
|
|
uint palette_offset;
|
|
} push_constants;
|
|
#define u_dst_size (push_constants.dst_size)
|
|
#define u_src_size (push_constants.src_size)
|
|
#define u_src_offset (push_constants.src_offset)
|
|
#define u_src_row_stride (push_constants.src_row_stride)
|
|
#define u_palette_offset (push_constants.palette_offset)
|
|
|
|
TEXEL_BUFFER_BINDING(0) uniform usamplerBuffer s_input_buffer;
|
|
TEXEL_BUFFER_BINDING(1) uniform usamplerBuffer s_palette_buffer;
|
|
|
|
IMAGE_BINDING(rgba8, 0) uniform writeonly image2DArray output_image;
|
|
|
|
#else
|
|
|
|
uniform uvec2 u_dst_size;
|
|
uniform uvec2 u_src_size;
|
|
uniform uint u_src_offset;
|
|
uniform uint u_src_row_stride;
|
|
uniform uint u_palette_offset;
|
|
|
|
SAMPLER_BINDING(9) uniform usamplerBuffer s_input_buffer;
|
|
SAMPLER_BINDING(10) uniform usamplerBuffer s_palette_buffer;
|
|
|
|
layout(rgba8, binding = 0) uniform writeonly image2DArray output_image;
|
|
|
|
#endif
|
|
|
|
uint Swap16(uint v)
|
|
{
|
|
// Convert BE to LE.
|
|
return ((v >> 8) | (v << 8)) & 0xFFFFu;
|
|
}
|
|
|
|
uint Convert3To8(uint v)
|
|
{
|
|
// Swizzle bits: 00000123 -> 12312312
|
|
return (v << 5) | (v << 2) | (v >> 1);
|
|
}
|
|
uint Convert4To8(uint v)
|
|
{
|
|
// Swizzle bits: 00001234 -> 12341234
|
|
return (v << 4) | v;
|
|
}
|
|
uint Convert5To8(uint v)
|
|
{
|
|
// Swizzle bits: 00012345 -> 12345123
|
|
return (v << 3) | (v >> 2);
|
|
}
|
|
uint Convert6To8(uint v)
|
|
{
|
|
// Swizzle bits: 00123456 -> 12345612
|
|
return (v << 2) | (v >> 4);
|
|
}
|
|
|
|
uint GetTiledTexelOffset(uvec2 block_size, uvec2 coords)
|
|
{
|
|
uvec2 block = coords / block_size;
|
|
uvec2 offset = coords % block_size;
|
|
uint buffer_pos = u_src_offset;
|
|
buffer_pos += block.y * u_src_row_stride;
|
|
buffer_pos += block.x * (block_size.x * block_size.y);
|
|
buffer_pos += offset.y * block_size.x;
|
|
buffer_pos += offset.x;
|
|
return buffer_pos;
|
|
}
|
|
|
|
uvec4 GetPaletteColor(uint index)
|
|
{
|
|
// Fetch and swap BE to LE.
|
|
uint val = Swap16(texelFetch(s_palette_buffer, int(u_palette_offset + index)).x);
|
|
|
|
uvec4 color;
|
|
#if defined(PALETTE_FORMAT_IA8)
|
|
uint a = bitfieldExtract(val, 8, 8);
|
|
uint i = bitfieldExtract(val, 0, 8);
|
|
color = uvec4(i, i, i, a);
|
|
#elif defined(PALETTE_FORMAT_RGB565)
|
|
color.x = Convert5To8(bitfieldExtract(val, 11, 5));
|
|
color.y = Convert6To8(bitfieldExtract(val, 5, 6));
|
|
color.z = Convert5To8(bitfieldExtract(val, 0, 5));
|
|
color.a = 255u;
|
|
|
|
#elif defined(PALETTE_FORMAT_RGB5A3)
|
|
if ((val & 0x8000u) != 0u)
|
|
{
|
|
color.x = Convert5To8(bitfieldExtract(val, 10, 5));
|
|
color.y = Convert5To8(bitfieldExtract(val, 5, 5));
|
|
color.z = Convert5To8(bitfieldExtract(val, 0, 5));
|
|
color.a = 255u;
|
|
}
|
|
else
|
|
{
|
|
color.a = Convert3To8(bitfieldExtract(val, 12, 3));
|
|
color.r = Convert4To8(bitfieldExtract(val, 8, 4));
|
|
color.g = Convert4To8(bitfieldExtract(val, 4, 4));
|
|
color.b = Convert4To8(bitfieldExtract(val, 0, 4));
|
|
}
|
|
#else
|
|
// Not used.
|
|
color = uvec4(0, 0, 0, 0);
|
|
#endif
|
|
|
|
return color;
|
|
}
|
|
|
|
vec4 GetPaletteColorNormalized(uint index)
|
|
{
|
|
uvec4 color = GetPaletteColor(index);
|
|
return vec4(color) / 255.0;
|
|
}
|
|
|
|
|
|
layout(local_size_x = 8, local_size_y = 8) in;
|
|
|
|
void main()
|
|
{
|
|
uvec2 coords = gl_GlobalInvocationID.xy;
|
|
|
|
// Tiled in 4x4 blocks, 16 bits per pixel
|
|
uint buffer_pos = GetTiledTexelOffset(uvec2(4u, 4u), coords);
|
|
uint index = texelFetch(s_input_buffer, int(buffer_pos)).x) & 0x3FFFu;
|
|
vec4 norm_color = GetPaletteColorNormalized(index);
|
|
imageStore(output_image, ivec3(ivec2(coords), 0), norm_color);
|
|
}
|
|
Compute shader failed to compile with the following errors:
|
|
ERROR: 1:131: error(#132) Syntax error: ")" parse error
|
|
ERROR: error(#273) 1 compilation errors. No code generated
|
|
|
|
|