summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-12-30 01:39:05 -0300
committerGravatar ReinUsesLisp2020-12-30 01:39:35 -0300
commit12d16248dd61d2998ee271e16d6980d6df963bbe (patch)
tree0717a3b516a58411d5860568c65381ae5c7fc4c6 /src
parenthost_shaders: Add copyright headers to OpenGL present shaders (diff)
downloadyuzu-12d16248dd61d2998ee271e16d6980d6df963bbe.tar.gz
yuzu-12d16248dd61d2998ee271e16d6980d6df963bbe.tar.xz
yuzu-12d16248dd61d2998ee271e16d6980d6df963bbe.zip
host_shaders: Add block linear upload compute shaders
Diffstat (limited to 'src')
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt2
-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
3 files changed, 249 insertions, 0 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index ff20bc93b..7feb6df99 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -1,4 +1,6 @@
1set(SHADER_FILES 1set(SHADER_FILES
2 block_linear_unswizzle_2d.comp
3 block_linear_unswizzle_3d.comp
2 opengl_present.frag 4 opengl_present.frag
3 opengl_present.vert 5 opengl_present.vert
4) 6)
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}