summaryrefslogtreecommitdiff
path: root/src/video_core/host_shaders
diff options
context:
space:
mode:
authorGravatar Levi2021-01-10 22:09:56 -0700
committerGravatar Levi2021-01-10 22:09:56 -0700
commit7a3c884e39fccfbb498b855080bffabc9ce2e7f1 (patch)
tree5056f9406dec188439cb0deb87603498243a9412 /src/video_core/host_shaders
parentMore forgetting... duh (diff)
parentMerge pull request #5229 from Morph1984/fullscreen-opt (diff)
downloadyuzu-7a3c884e39fccfbb498b855080bffabc9ce2e7f1.tar.gz
yuzu-7a3c884e39fccfbb498b855080bffabc9ce2e7f1.tar.xz
yuzu-7a3c884e39fccfbb498b855080bffabc9ce2e7f1.zip
Merge remote-tracking branch 'upstream/master' into int-flags
Diffstat (limited to 'src/video_core/host_shaders')
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt70
-rw-r--r--src/video_core/host_shaders/StringShaderHeader.cmake2
-rw-r--r--src/video_core/host_shaders/block_linear_unswizzle_2d.comp122
-rw-r--r--src/video_core/host_shaders/block_linear_unswizzle_3d.comp125
-rw-r--r--src/video_core/host_shaders/convert_depth_to_float.frag13
-rw-r--r--src/video_core/host_shaders/convert_float_to_depth.frag13
-rw-r--r--src/video_core/host_shaders/full_screen_triangle.vert29
-rw-r--r--src/video_core/host_shaders/opengl_copy_bc4.comp70
-rw-r--r--src/video_core/host_shaders/opengl_present.frag4
-rw-r--r--src/video_core/host_shaders/opengl_present.vert4
-rw-r--r--src/video_core/host_shaders/pitch_unswizzle.comp86
-rw-r--r--src/video_core/host_shaders/vulkan_blit_color_float.frag14
-rw-r--r--src/video_core/host_shaders/vulkan_blit_depth_stencil.frag16
-rw-r--r--src/video_core/host_shaders/vulkan_present.frag15
-rw-r--r--src/video_core/host_shaders/vulkan_present.vert19
-rw-r--r--src/video_core/host_shaders/vulkan_quad_array.comp28
-rw-r--r--src/video_core/host_shaders/vulkan_quad_indexed.comp41
-rw-r--r--src/video_core/host_shaders/vulkan_uint8.comp24
18 files changed, 674 insertions, 21 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index aa62363a7..4c7399d5a 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -1,18 +1,29 @@
1set(SHADER_FILES 1set(SHADER_FILES
2 block_linear_unswizzle_2d.comp
3 block_linear_unswizzle_3d.comp
4 convert_depth_to_float.frag
5 convert_float_to_depth.frag
6 full_screen_triangle.vert
7 opengl_copy_bc4.comp
2 opengl_present.frag 8 opengl_present.frag
3 opengl_present.vert 9 opengl_present.vert
10 pitch_unswizzle.comp
11 vulkan_blit_color_float.frag
12 vulkan_blit_depth_stencil.frag
13 vulkan_present.frag
14 vulkan_present.vert
15 vulkan_quad_array.comp
16 vulkan_quad_indexed.comp
17 vulkan_uint8.comp
4) 18)
5 19
6set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) 20find_program(GLSLANGVALIDATOR "glslangValidator" REQUIRED)
7set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) 21
22set(GLSL_FLAGS "")
8 23
24set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
9set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) 25set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders)
10add_custom_command( 26set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
11 OUTPUT
12 ${SHADER_DIR}
13 COMMAND
14 ${CMAKE_COMMAND} -E make_directory ${SHADER_DIR}
15)
16 27
17set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) 28set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in)
18set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) 29set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake)
@@ -20,19 +31,36 @@ set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake)
20foreach(FILENAME IN ITEMS ${SHADER_FILES}) 31foreach(FILENAME IN ITEMS ${SHADER_FILES})
21 string(REPLACE "." "_" SHADER_NAME ${FILENAME}) 32 string(REPLACE "." "_" SHADER_NAME ${FILENAME})
22 set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) 33 set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME})
23 set(HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h) 34 # Skip generating source headers on Vulkan exclusive files
24 add_custom_command( 35 if (NOT ${FILENAME} MATCHES "vulkan.*")
25 OUTPUT 36 set(SOURCE_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h)
26 ${HEADER_FILE} 37 add_custom_command(
27 COMMAND 38 OUTPUT
28 ${CMAKE_COMMAND} -P ${HEADER_GENERATOR} ${SOURCE_FILE} ${HEADER_FILE} ${INPUT_FILE} 39 ${SOURCE_HEADER_FILE}
29 MAIN_DEPENDENCY 40 COMMAND
30 ${SOURCE_FILE} 41 ${CMAKE_COMMAND} -P ${HEADER_GENERATOR} ${SOURCE_FILE} ${SOURCE_HEADER_FILE} ${INPUT_FILE}
31 DEPENDS 42 MAIN_DEPENDENCY
32 ${HEADER_GENERATOR} 43 ${SOURCE_FILE}
33 ${INPUT_FILE} 44 DEPENDS
34 ) 45 ${INPUT_FILE}
35 set(SHADER_HEADERS ${SHADER_HEADERS} ${HEADER_FILE}) 46 # HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified
47 )
48 set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE})
49 endif()
50 # Skip compiling to SPIR-V OpenGL exclusive files
51 if (NOT ${FILENAME} MATCHES "opengl.*")
52 string(TOUPPER ${SHADER_NAME}_SPV SPIRV_VARIABLE_NAME)
53 set(SPIRV_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}_spv.h)
54 add_custom_command(
55 OUTPUT
56 ${SPIRV_HEADER_FILE}
57 COMMAND
58 ${GLSLANGVALIDATOR} -V ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE}
59 MAIN_DEPENDENCY
60 ${SOURCE_FILE}
61 )
62 set(SHADER_HEADERS ${SHADER_HEADERS} ${SPIRV_HEADER_FILE})
63 endif()
36endforeach() 64endforeach()
37 65
38add_custom_target(host_shaders 66add_custom_target(host_shaders
diff --git a/src/video_core/host_shaders/StringShaderHeader.cmake b/src/video_core/host_shaders/StringShaderHeader.cmake
index 368bce0ed..c0fc49768 100644
--- a/src/video_core/host_shaders/StringShaderHeader.cmake
+++ b/src/video_core/host_shaders/StringShaderHeader.cmake
@@ -8,4 +8,6 @@ string(TOUPPER ${CONTENTS_NAME} CONTENTS_NAME)
8 8
9file(READ ${SOURCE_FILE} CONTENTS) 9file(READ ${SOURCE_FILE} CONTENTS)
10 10
11get_filename_component(OUTPUT_DIR ${HEADER_FILE} DIRECTORY)
12make_directory(${OUTPUT_DIR})
11configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY) 13configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY)
diff --git a/src/video_core/host_shaders/block_linear_unswizzle_2d.comp b/src/video_core/host_shaders/block_linear_unswizzle_2d.comp
new file mode 100644
index 000000000..a131be79e
--- /dev/null
+++ b/src/video_core/host_shaders/block_linear_unswizzle_2d.comp
@@ -0,0 +1,122 @@
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
6
7#ifdef VULKAN
8
9#extension GL_EXT_shader_16bit_storage : require
10#extension GL_EXT_shader_8bit_storage : require
11#define HAS_EXTENDED_TYPES 1
12#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
13#define END_PUSH_CONSTANTS };
14#define UNIFORM(n)
15#define BINDING_SWIZZLE_BUFFER 0
16#define BINDING_INPUT_BUFFER 1
17#define BINDING_OUTPUT_IMAGE 2
18
19#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
20
21#extension GL_NV_gpu_shader5 : enable
22#ifdef GL_NV_gpu_shader5
23#define HAS_EXTENDED_TYPES 1
24#else
25#define HAS_EXTENDED_TYPES 0
26#endif
27#define BEGIN_PUSH_CONSTANTS
28#define END_PUSH_CONSTANTS
29#define UNIFORM(n) layout (location = n) uniform
30#define BINDING_SWIZZLE_BUFFER 0
31#define BINDING_INPUT_BUFFER 1
32#define BINDING_OUTPUT_IMAGE 0
33
34#endif
35
36BEGIN_PUSH_CONSTANTS
37UNIFORM(0) uvec3 origin;
38UNIFORM(1) ivec3 destination;
39UNIFORM(2) uint bytes_per_block_log2;
40UNIFORM(3) uint layer_stride;
41UNIFORM(4) uint block_size;
42UNIFORM(5) uint x_shift;
43UNIFORM(6) uint block_height;
44UNIFORM(7) uint block_height_mask;
45END_PUSH_CONSTANTS
46
47layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
48 uint swizzle_table[];
49};
50
51#if HAS_EXTENDED_TYPES
52layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
53layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
54#endif
55layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
56layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
57layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; };
58
59layout(binding = BINDING_OUTPUT_IMAGE) uniform writeonly uimage2DArray output_image;
60
61layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
62
63const uint GOB_SIZE_X = 64;
64const uint GOB_SIZE_Y = 8;
65const uint GOB_SIZE_Z = 1;
66const uint GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
67
68const uint GOB_SIZE_X_SHIFT = 6;
69const uint GOB_SIZE_Y_SHIFT = 3;
70const uint GOB_SIZE_Z_SHIFT = 0;
71const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
72
73const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
74
75uint SwizzleOffset(uvec2 pos) {
76 pos = pos & SWIZZLE_MASK;
77 return swizzle_table[pos.y * 64 + pos.x];
78}
79
80uvec4 ReadTexel(uint offset) {
81 switch (bytes_per_block_log2) {
82#if HAS_EXTENDED_TYPES
83 case 0:
84 return uvec4(u8data[offset], 0, 0, 0);
85 case 1:
86 return uvec4(u16data[offset / 2], 0, 0, 0);
87#else
88 case 0:
89 return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
90 case 1:
91 return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
92#endif
93 case 2:
94 return uvec4(u32data[offset / 4], 0, 0, 0);
95 case 3:
96 return uvec4(u64data[offset / 8], 0, 0);
97 case 4:
98 return u128data[offset / 16];
99 }
100 return uvec4(0);
101}
102
103void main() {
104 uvec3 pos = gl_GlobalInvocationID + origin;
105 pos.x <<= bytes_per_block_log2;
106
107 // Read as soon as possible due to its latency
108 const uint swizzle = SwizzleOffset(pos.xy);
109
110 const uint block_y = pos.y >> GOB_SIZE_Y_SHIFT;
111
112 uint offset = 0;
113 offset += pos.z * layer_stride;
114 offset += (block_y >> block_height) * block_size;
115 offset += (block_y & block_height_mask) << GOB_SIZE_SHIFT;
116 offset += (pos.x >> GOB_SIZE_X_SHIFT) << x_shift;
117 offset += swizzle;
118
119 const uvec4 texel = ReadTexel(offset);
120 const ivec3 coord = ivec3(gl_GlobalInvocationID) + destination;
121 imageStore(output_image, coord, texel);
122}
diff --git a/src/video_core/host_shaders/block_linear_unswizzle_3d.comp b/src/video_core/host_shaders/block_linear_unswizzle_3d.comp
new file mode 100644
index 000000000..bb6872e6b
--- /dev/null
+++ b/src/video_core/host_shaders/block_linear_unswizzle_3d.comp
@@ -0,0 +1,125 @@
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
6
7#ifdef VULKAN
8
9#extension GL_EXT_shader_16bit_storage : require
10#extension GL_EXT_shader_8bit_storage : require
11#define HAS_EXTENDED_TYPES 1
12#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
13#define END_PUSH_CONSTANTS };
14#define UNIFORM(n)
15#define BINDING_SWIZZLE_BUFFER 0
16#define BINDING_INPUT_BUFFER 1
17#define BINDING_OUTPUT_IMAGE 2
18
19#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
20
21#extension GL_NV_gpu_shader5 : enable
22#ifdef GL_NV_gpu_shader5
23#define HAS_EXTENDED_TYPES 1
24#else
25#define HAS_EXTENDED_TYPES 0
26#endif
27#define BEGIN_PUSH_CONSTANTS
28#define END_PUSH_CONSTANTS
29#define UNIFORM(n) layout (location = n) uniform
30#define BINDING_SWIZZLE_BUFFER 0
31#define BINDING_INPUT_BUFFER 1
32#define BINDING_OUTPUT_IMAGE 0
33
34#endif
35
36BEGIN_PUSH_CONSTANTS
37UNIFORM(0) uvec3 origin;
38UNIFORM(1) ivec3 destination;
39UNIFORM(2) uint bytes_per_block_log2;
40UNIFORM(3) uint slice_size;
41UNIFORM(4) uint block_size;
42UNIFORM(5) uint x_shift;
43UNIFORM(6) uint block_height;
44UNIFORM(7) uint block_height_mask;
45UNIFORM(8) uint block_depth;
46UNIFORM(9) uint block_depth_mask;
47END_PUSH_CONSTANTS
48
49layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
50 uint swizzle_table[];
51};
52
53#if HAS_EXTENDED_TYPES
54layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
55layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
56#endif
57layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
58layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
59layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; };
60
61layout(binding = BINDING_OUTPUT_IMAGE) uniform writeonly uimage3D output_image;
62
63layout(local_size_x = 16, local_size_y = 8, local_size_z = 8) in;
64
65const uint GOB_SIZE_X = 64;
66const uint GOB_SIZE_Y = 8;
67const uint GOB_SIZE_Z = 1;
68const uint GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
69
70const uint GOB_SIZE_X_SHIFT = 6;
71const uint GOB_SIZE_Y_SHIFT = 3;
72const uint GOB_SIZE_Z_SHIFT = 0;
73const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
74
75const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
76
77uint SwizzleOffset(uvec2 pos) {
78 pos = pos & SWIZZLE_MASK;
79 return swizzle_table[pos.y * 64 + pos.x];
80}
81
82uvec4 ReadTexel(uint offset) {
83 switch (bytes_per_block_log2) {
84#if HAS_EXTENDED_TYPES
85 case 0:
86 return uvec4(u8data[offset], 0, 0, 0);
87 case 1:
88 return uvec4(u16data[offset / 2], 0, 0, 0);
89#else
90 case 0:
91 return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
92 case 1:
93 return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
94#endif
95 case 2:
96 return uvec4(u32data[offset / 4], 0, 0, 0);
97 case 3:
98 return uvec4(u64data[offset / 8], 0, 0);
99 case 4:
100 return u128data[offset / 16];
101 }
102 return uvec4(0);
103}
104
105void main() {
106 uvec3 pos = gl_GlobalInvocationID + origin;
107 pos.x <<= bytes_per_block_log2;
108
109 // Read as soon as possible due to its latency
110 const uint swizzle = SwizzleOffset(pos.xy);
111
112 const uint block_y = pos.y >> GOB_SIZE_Y_SHIFT;
113
114 uint offset = 0;
115 offset += (pos.z >> block_depth) * slice_size;
116 offset += (pos.z & block_depth_mask) << (GOB_SIZE_SHIFT + block_height);
117 offset += (block_y >> block_height) * block_size;
118 offset += (block_y & block_height_mask) << GOB_SIZE_SHIFT;
119 offset += (pos.x >> GOB_SIZE_X_SHIFT) << x_shift;
120 offset += swizzle;
121
122 const uvec4 texel = ReadTexel(offset);
123 const ivec3 coord = ivec3(gl_GlobalInvocationID) + destination;
124 imageStore(output_image, coord, texel);
125}
diff --git a/src/video_core/host_shaders/convert_depth_to_float.frag b/src/video_core/host_shaders/convert_depth_to_float.frag
new file mode 100644
index 000000000..624c58509
--- /dev/null
+++ b/src/video_core/host_shaders/convert_depth_to_float.frag
@@ -0,0 +1,13 @@
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 450
6
7layout(binding = 0) uniform sampler2D depth_texture;
8layout(location = 0) out float output_color;
9
10void main() {
11 ivec2 coord = ivec2(gl_FragCoord.xy);
12 output_color = texelFetch(depth_texture, coord, 0).r;
13}
diff --git a/src/video_core/host_shaders/convert_float_to_depth.frag b/src/video_core/host_shaders/convert_float_to_depth.frag
new file mode 100644
index 000000000..d86c795f4
--- /dev/null
+++ b/src/video_core/host_shaders/convert_float_to_depth.frag
@@ -0,0 +1,13 @@
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 450
6
7layout(binding = 0) uniform sampler2D color_texture;
8
9void main() {
10 ivec2 coord = ivec2(gl_FragCoord.xy);
11 float color = texelFetch(color_texture, coord, 0).r;
12 gl_FragDepth = color;
13}
diff --git a/src/video_core/host_shaders/full_screen_triangle.vert b/src/video_core/host_shaders/full_screen_triangle.vert
new file mode 100644
index 000000000..452ad6502
--- /dev/null
+++ b/src/video_core/host_shaders/full_screen_triangle.vert
@@ -0,0 +1,29 @@
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 450
6
7#ifdef VULKAN
8#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
9#define END_PUSH_CONSTANTS };
10#define UNIFORM(n)
11#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
12#define BEGIN_PUSH_CONSTANTS
13#define END_PUSH_CONSTANTS
14#define UNIFORM(n) layout (location = n) uniform
15#endif
16
17BEGIN_PUSH_CONSTANTS
18UNIFORM(0) vec2 tex_scale;
19UNIFORM(1) vec2 tex_offset;
20END_PUSH_CONSTANTS
21
22layout(location = 0) out vec2 texcoord;
23
24void main() {
25 float x = float((gl_VertexIndex & 1) << 2);
26 float y = float((gl_VertexIndex & 2) << 1);
27 gl_Position = vec4(x - 1.0, y - 1.0, 0.0, 1.0);
28 texcoord = fma(vec2(x, y) / 2.0, tex_scale, tex_offset);
29}
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
8layout (local_size_x = 4, local_size_y = 4) in;
9
10layout(binding = 0, rg32ui) readonly uniform uimage3D bc4_input;
11layout(binding = 1, rgba8ui) writeonly uniform uimage3D bc4_output;
12
13layout(location = 0) uniform uvec3 src_offset;
14layout(location = 1) uniform uvec3 dst_offset;
15
16// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_rgtc.txt
17uint 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
64void 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}
diff --git a/src/video_core/host_shaders/opengl_present.frag b/src/video_core/host_shaders/opengl_present.frag
index 8a4cb024b..84b818227 100644
--- a/src/video_core/host_shaders/opengl_present.frag
+++ b/src/video_core/host_shaders/opengl_present.frag
@@ -1,3 +1,7 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#version 430 core 5#version 430 core
2 6
3layout (location = 0) in vec2 frag_tex_coord; 7layout (location = 0) in vec2 frag_tex_coord;
diff --git a/src/video_core/host_shaders/opengl_present.vert b/src/video_core/host_shaders/opengl_present.vert
index 2235d31a4..c3b5adbba 100644
--- a/src/video_core/host_shaders/opengl_present.vert
+++ b/src/video_core/host_shaders/opengl_present.vert
@@ -1,3 +1,7 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#version 430 core 5#version 430 core
2 6
3out gl_PerVertex { 7out gl_PerVertex {
diff --git a/src/video_core/host_shaders/pitch_unswizzle.comp b/src/video_core/host_shaders/pitch_unswizzle.comp
new file mode 100644
index 000000000..cb48ec170
--- /dev/null
+++ b/src/video_core/host_shaders/pitch_unswizzle.comp
@@ -0,0 +1,86 @@
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
6
7#ifdef VULKAN
8
9#extension GL_EXT_shader_16bit_storage : require
10#extension GL_EXT_shader_8bit_storage : require
11#define HAS_EXTENDED_TYPES 1
12#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
13#define END_PUSH_CONSTANTS };
14#define UNIFORM(n)
15#define BINDING_INPUT_BUFFER 0
16#define BINDING_OUTPUT_IMAGE 1
17
18#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
19
20#extension GL_NV_gpu_shader5 : enable
21#ifdef GL_NV_gpu_shader5
22#define HAS_EXTENDED_TYPES 1
23#else
24#define HAS_EXTENDED_TYPES 0
25#endif
26#define BEGIN_PUSH_CONSTANTS
27#define END_PUSH_CONSTANTS
28#define UNIFORM(n) layout (location = n) uniform
29#define BINDING_INPUT_BUFFER 0
30#define BINDING_OUTPUT_IMAGE 0
31
32#endif
33
34BEGIN_PUSH_CONSTANTS
35UNIFORM(0) uvec2 origin;
36UNIFORM(1) ivec2 destination;
37UNIFORM(2) uint bytes_per_block;
38UNIFORM(3) uint pitch;
39END_PUSH_CONSTANTS
40
41#if HAS_EXTENDED_TYPES
42layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU8 { uint8_t u8data[]; };
43layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU16 { uint16_t u16data[]; };
44#endif
45layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU32 { uint u32data[]; };
46layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU64 { uvec2 u64data[]; };
47layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU128 { uvec4 u128data[]; };
48
49layout(binding = BINDING_OUTPUT_IMAGE) writeonly uniform uimage2D output_image;
50
51layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
52
53uvec4 ReadTexel(uint offset) {
54 switch (bytes_per_block) {
55#if HAS_EXTENDED_TYPES
56 case 1:
57 return uvec4(u8data[offset], 0, 0, 0);
58 case 2:
59 return uvec4(u16data[offset / 2], 0, 0, 0);
60#else
61 case 1:
62 return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
63 case 2:
64 return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
65#endif
66 case 4:
67 return uvec4(u32data[offset / 4], 0, 0, 0);
68 case 8:
69 return uvec4(u64data[offset / 8], 0, 0);
70 case 16:
71 return u128data[offset / 16];
72 }
73 return uvec4(0);
74}
75
76void main() {
77 uvec2 pos = gl_GlobalInvocationID.xy + origin;
78
79 uint offset = 0;
80 offset += pos.x * bytes_per_block;
81 offset += pos.y * pitch;
82
83 const uvec4 texel = ReadTexel(offset);
84 const ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + destination;
85 imageStore(output_image, coord, texel);
86}
diff --git a/src/video_core/host_shaders/vulkan_blit_color_float.frag b/src/video_core/host_shaders/vulkan_blit_color_float.frag
new file mode 100644
index 000000000..4a6aae410
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_blit_color_float.frag
@@ -0,0 +1,14 @@
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 450
6
7layout(binding = 0) uniform sampler2D tex;
8
9layout(location = 0) in vec2 texcoord;
10layout(location = 0) out vec4 color;
11
12void main() {
13 color = textureLod(tex, texcoord, 0);
14}
diff --git a/src/video_core/host_shaders/vulkan_blit_depth_stencil.frag b/src/video_core/host_shaders/vulkan_blit_depth_stencil.frag
new file mode 100644
index 000000000..19bb23a5a
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_blit_depth_stencil.frag
@@ -0,0 +1,16 @@
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 450
6#extension GL_ARB_shader_stencil_export : require
7
8layout(binding = 0) uniform sampler2D depth_tex;
9layout(binding = 1) uniform isampler2D stencil_tex;
10
11layout(location = 0) in vec2 texcoord;
12
13void main() {
14 gl_FragDepth = textureLod(depth_tex, texcoord, 0).r;
15 gl_FragStencilRefARB = textureLod(stencil_tex, texcoord, 0).r;
16}
diff --git a/src/video_core/host_shaders/vulkan_present.frag b/src/video_core/host_shaders/vulkan_present.frag
new file mode 100644
index 000000000..0979ff3e6
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_present.frag
@@ -0,0 +1,15 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#version 460 core
6
7layout (location = 0) in vec2 frag_tex_coord;
8
9layout (location = 0) out vec4 color;
10
11layout (binding = 1) uniform sampler2D color_texture;
12
13void main() {
14 color = texture(color_texture, frag_tex_coord);
15}
diff --git a/src/video_core/host_shaders/vulkan_present.vert b/src/video_core/host_shaders/vulkan_present.vert
new file mode 100644
index 000000000..00b868958
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_present.vert
@@ -0,0 +1,19 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#version 460 core
6
7layout (location = 0) in vec2 vert_position;
8layout (location = 1) in vec2 vert_tex_coord;
9
10layout (location = 0) out vec2 frag_tex_coord;
11
12layout (set = 0, binding = 0) uniform MatrixBlock {
13 mat4 modelview_matrix;
14};
15
16void main() {
17 gl_Position = modelview_matrix * vec4(vert_position, 0.0, 1.0);
18 frag_tex_coord = vert_tex_coord;
19}
diff --git a/src/video_core/host_shaders/vulkan_quad_array.comp b/src/video_core/host_shaders/vulkan_quad_array.comp
new file mode 100644
index 000000000..212f4e998
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_quad_array.comp
@@ -0,0 +1,28 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#version 460 core
6
7layout (local_size_x = 1024) in;
8
9layout (std430, set = 0, binding = 0) buffer OutputBuffer {
10 uint output_indexes[];
11};
12
13layout (push_constant) uniform PushConstants {
14 uint first;
15};
16
17void main() {
18 uint primitive = gl_GlobalInvocationID.x;
19 if (primitive * 6 >= output_indexes.length()) {
20 return;
21 }
22
23 const uint quad_map[6] = uint[](0, 1, 2, 0, 2, 3);
24 for (uint vertex = 0; vertex < 6; ++vertex) {
25 uint index = first + primitive * 4 + quad_map[vertex];
26 output_indexes[primitive * 6 + vertex] = index;
27 }
28}
diff --git a/src/video_core/host_shaders/vulkan_quad_indexed.comp b/src/video_core/host_shaders/vulkan_quad_indexed.comp
new file mode 100644
index 000000000..8655591d0
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_quad_indexed.comp
@@ -0,0 +1,41 @@
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 460 core
6
7layout (local_size_x = 1024) in;
8
9layout (std430, set = 0, binding = 0) readonly buffer InputBuffer {
10 uint input_indexes[];
11};
12
13layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer {
14 uint output_indexes[];
15};
16
17layout (push_constant) uniform PushConstants {
18 uint base_vertex;
19 int index_shift; // 0: uint8, 1: uint16, 2: uint32
20};
21
22void main() {
23 int primitive = int(gl_GlobalInvocationID.x);
24 if (primitive * 6 >= output_indexes.length()) {
25 return;
26 }
27
28 int index_size = 8 << index_shift;
29 int flipped_shift = 2 - index_shift;
30 int mask = (1 << flipped_shift) - 1;
31
32 const int quad_swizzle[6] = int[](0, 1, 2, 0, 2, 3);
33 for (uint vertex = 0; vertex < 6; ++vertex) {
34 int offset = primitive * 4 + quad_swizzle[vertex];
35 int int_offset = offset >> flipped_shift;
36 int bit_offset = (offset & mask) * index_size;
37 uint packed_input = input_indexes[int_offset];
38 uint index = bitfieldExtract(packed_input, bit_offset, index_size);
39 output_indexes[primitive * 6 + vertex] = index + base_vertex;
40 }
41}
diff --git a/src/video_core/host_shaders/vulkan_uint8.comp b/src/video_core/host_shaders/vulkan_uint8.comp
new file mode 100644
index 000000000..ad74d7af9
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_uint8.comp
@@ -0,0 +1,24 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#version 460 core
6#extension GL_EXT_shader_16bit_storage : require
7#extension GL_EXT_shader_8bit_storage : require
8
9layout (local_size_x = 1024) in;
10
11layout (std430, set = 0, binding = 0) readonly buffer InputBuffer {
12 uint8_t input_indexes[];
13};
14
15layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer {
16 uint16_t output_indexes[];
17};
18
19void main() {
20 uint id = gl_GlobalInvocationID.x;
21 if (id < input_indexes.length()) {
22 output_indexes[id] = uint16_t(input_indexes[id]);
23 }
24}