host_shaders: Add compute shader to copy BC4 as RG32UI to RGBA8
This commit is contained in:
parent
5169ce9fcd
commit
dc81a90640
|
@ -2,6 +2,7 @@ set(SHADER_FILES
|
||||||
block_linear_unswizzle_2d.comp
|
block_linear_unswizzle_2d.comp
|
||||||
block_linear_unswizzle_3d.comp
|
block_linear_unswizzle_3d.comp
|
||||||
full_screen_triangle.vert
|
full_screen_triangle.vert
|
||||||
|
opengl_copy_bc4.comp
|
||||||
opengl_present.frag
|
opengl_present.frag
|
||||||
opengl_present.vert
|
opengl_present.vert
|
||||||
pitch_unswizzle.comp
|
pitch_unswizzle.comp
|
||||||
|
|
70
src/video_core/host_shaders/opengl_copy_bc4.comp
Normal file
70
src/video_core/host_shaders/opengl_copy_bc4.comp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#version 430 core
|
||||||
|
#extension GL_ARB_gpu_shader_int64 : require
|
||||||
|
|
||||||
|
layout (local_size_x = 4, local_size_y = 4) in;
|
||||||
|
|
||||||
|
layout(binding = 0, rg32ui) readonly uniform uimage3D bc4_input;
|
||||||
|
layout(binding = 1, rgba8ui) writeonly uniform uimage3D bc4_output;
|
||||||
|
|
||||||
|
layout(location = 0) uniform uvec3 src_offset;
|
||||||
|
layout(location = 1) uniform uvec3 dst_offset;
|
||||||
|
|
||||||
|
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_rgtc.txt
|
||||||
|
uint DecompressBlock(uint64_t bits, uvec2 coord) {
|
||||||
|
const uint code_offset = 16 + 3 * (4 * coord.y + coord.x);
|
||||||
|
const uint code = uint(bits >> code_offset) & 7;
|
||||||
|
const uint red0 = uint(bits >> 0) & 0xff;
|
||||||
|
const uint red1 = uint(bits >> 8) & 0xff;
|
||||||
|
if (red0 > red1) {
|
||||||
|
switch (code) {
|
||||||
|
case 0:
|
||||||
|
return red0;
|
||||||
|
case 1:
|
||||||
|
return red1;
|
||||||
|
case 2:
|
||||||
|
return (6 * red0 + 1 * red1) / 7;
|
||||||
|
case 3:
|
||||||
|
return (5 * red0 + 2 * red1) / 7;
|
||||||
|
case 4:
|
||||||
|
return (4 * red0 + 3 * red1) / 7;
|
||||||
|
case 5:
|
||||||
|
return (3 * red0 + 4 * red1) / 7;
|
||||||
|
case 6:
|
||||||
|
return (2 * red0 + 5 * red1) / 7;
|
||||||
|
case 7:
|
||||||
|
return (1 * red0 + 6 * red1) / 7;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (code) {
|
||||||
|
case 0:
|
||||||
|
return red0;
|
||||||
|
case 1:
|
||||||
|
return red1;
|
||||||
|
case 2:
|
||||||
|
return (4 * red0 + 1 * red1) / 5;
|
||||||
|
case 3:
|
||||||
|
return (3 * red0 + 2 * red1) / 5;
|
||||||
|
case 4:
|
||||||
|
return (2 * red0 + 3 * red1) / 5;
|
||||||
|
case 5:
|
||||||
|
return (1 * red0 + 4 * red1) / 5;
|
||||||
|
case 6:
|
||||||
|
return 0;
|
||||||
|
case 7:
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
uvec2 packed_bits = imageLoad(bc4_input, ivec3(gl_WorkGroupID + src_offset)).rg;
|
||||||
|
uint64_t bits = packUint2x32(packed_bits);
|
||||||
|
uint red = DecompressBlock(bits, gl_LocalInvocationID.xy);
|
||||||
|
uvec4 color = uvec4(red & 0xff, 0, 0, 0xff);
|
||||||
|
imageStore(bc4_output, ivec3(gl_GlobalInvocationID + dst_offset), color);
|
||||||
|
}
|
Loading…
Reference in a new issue