diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2020-12-30 05:47:08 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2020-12-30 05:47:08 +0100 |
commit | dc81a906402b0a39c3ff1964cdf935b46b062b5d (patch) | |
tree | bad2a6bcd46541ba2650b27e9bc090e91e4163f2 /src/video_core/host_shaders/opengl_copy_bc4.comp | |
parent | host_shaders: Add shader to render a full screen triangle (diff) | |
download | yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.tar yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.tar.gz yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.tar.bz2 yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.tar.lz yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.tar.xz yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.tar.zst yuzu-dc81a906402b0a39c3ff1964cdf935b46b062b5d.zip |
Diffstat (limited to 'src/video_core/host_shaders/opengl_copy_bc4.comp')
-rw-r--r-- | src/video_core/host_shaders/opengl_copy_bc4.comp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/video_core/host_shaders/opengl_copy_bc4.comp b/src/video_core/host_shaders/opengl_copy_bc4.comp new file mode 100644 index 000000000..7b8e20fbe --- /dev/null +++ b/src/video_core/host_shaders/opengl_copy_bc4.comp @@ -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); +} |