diff options
| -rw-r--r-- | src/video_core/host_shaders/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/host_shaders/opengl_copy_bc4.comp | 70 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 5770c4761..338bf9eec 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -2,6 +2,7 @@ set(SHADER_FILES | |||
| 2 | block_linear_unswizzle_2d.comp | 2 | block_linear_unswizzle_2d.comp |
| 3 | block_linear_unswizzle_3d.comp | 3 | block_linear_unswizzle_3d.comp |
| 4 | full_screen_triangle.vert | 4 | full_screen_triangle.vert |
| 5 | opengl_copy_bc4.comp | ||
| 5 | opengl_present.frag | 6 | opengl_present.frag |
| 6 | opengl_present.vert | 7 | opengl_present.vert |
| 7 | pitch_unswizzle.comp | 8 | pitch_unswizzle.comp |
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 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #version 430 core | ||
| 6 | #extension GL_ARB_gpu_shader_int64 : require | ||
| 7 | |||
| 8 | layout (local_size_x = 4, local_size_y = 4) in; | ||
| 9 | |||
| 10 | layout(binding = 0, rg32ui) readonly uniform uimage3D bc4_input; | ||
| 11 | layout(binding = 1, rgba8ui) writeonly uniform uimage3D bc4_output; | ||
| 12 | |||
| 13 | layout(location = 0) uniform uvec3 src_offset; | ||
| 14 | layout(location = 1) uniform uvec3 dst_offset; | ||
| 15 | |||
| 16 | // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_rgtc.txt | ||
| 17 | uint DecompressBlock(uint64_t bits, uvec2 coord) { | ||
| 18 | const uint code_offset = 16 + 3 * (4 * coord.y + coord.x); | ||
| 19 | const uint code = uint(bits >> code_offset) & 7; | ||
| 20 | const uint red0 = uint(bits >> 0) & 0xff; | ||
| 21 | const uint red1 = uint(bits >> 8) & 0xff; | ||
| 22 | if (red0 > red1) { | ||
| 23 | switch (code) { | ||
| 24 | case 0: | ||
| 25 | return red0; | ||
| 26 | case 1: | ||
| 27 | return red1; | ||
| 28 | case 2: | ||
| 29 | return (6 * red0 + 1 * red1) / 7; | ||
| 30 | case 3: | ||
| 31 | return (5 * red0 + 2 * red1) / 7; | ||
| 32 | case 4: | ||
| 33 | return (4 * red0 + 3 * red1) / 7; | ||
| 34 | case 5: | ||
| 35 | return (3 * red0 + 4 * red1) / 7; | ||
| 36 | case 6: | ||
| 37 | return (2 * red0 + 5 * red1) / 7; | ||
| 38 | case 7: | ||
| 39 | return (1 * red0 + 6 * red1) / 7; | ||
| 40 | } | ||
| 41 | } else { | ||
| 42 | switch (code) { | ||
| 43 | case 0: | ||
| 44 | return red0; | ||
| 45 | case 1: | ||
| 46 | return red1; | ||
| 47 | case 2: | ||
| 48 | return (4 * red0 + 1 * red1) / 5; | ||
| 49 | case 3: | ||
| 50 | return (3 * red0 + 2 * red1) / 5; | ||
| 51 | case 4: | ||
| 52 | return (2 * red0 + 3 * red1) / 5; | ||
| 53 | case 5: | ||
| 54 | return (1 * red0 + 4 * red1) / 5; | ||
| 55 | case 6: | ||
| 56 | return 0; | ||
| 57 | case 7: | ||
| 58 | return 0xff; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | void main() { | ||
| 65 | uvec2 packed_bits = imageLoad(bc4_input, ivec3(gl_WorkGroupID + src_offset)).rg; | ||
| 66 | uint64_t bits = packUint2x32(packed_bits); | ||
| 67 | uint red = DecompressBlock(bits, gl_LocalInvocationID.xy); | ||
| 68 | uvec4 color = uvec4(red & 0xff, 0, 0, 0xff); | ||
| 69 | imageStore(bc4_output, ivec3(gl_GlobalInvocationID + dst_offset), color); | ||
| 70 | } | ||