7 changed files with 748 additions and 0 deletions
-
2src/video_core/host_shaders/CMakeLists.txt
-
104src/video_core/host_shaders/block_linear_unswizzle_2d_buffer.comp
-
105src/video_core/host_shaders/block_linear_unswizzle_3d_buffer.comp
-
477src/video_core/renderer_vulkan/vk_compute_pass.cpp
-
38src/video_core/renderer_vulkan/vk_compute_pass.h
-
20src/video_core/renderer_vulkan/vk_texture_cache.cpp
-
2src/video_core/renderer_vulkan/vk_texture_cache.h
@ -0,0 +1,104 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#version 430 |
|||
|
|||
#extension GL_EXT_shader_16bit_storage : require |
|||
#extension GL_EXT_shader_8bit_storage : require |
|||
|
|||
#define BINDING_INPUT_BUFFER 0 |
|||
#define BINDING_OUTPUT_BUFFER 1 |
|||
|
|||
layout(push_constant) uniform PushConstants { |
|||
uvec3 dim; |
|||
uint bytes_per_block_log2; |
|||
|
|||
uvec3 origin; |
|||
uint layer_stride; |
|||
|
|||
uint block_size; |
|||
uint x_shift; |
|||
uint block_height; |
|||
uint block_height_mask; |
|||
} pc; |
|||
|
|||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; }; |
|||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; }; |
|||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; }; |
|||
|
|||
layout(binding = BINDING_OUTPUT_BUFFER, std430) writeonly buffer OutputBuffer { |
|||
uint out_u32[]; |
|||
}; |
|||
|
|||
layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in; |
|||
|
|||
const uint GOB_SIZE_X = 64; |
|||
const uint GOB_SIZE_Y = 8; |
|||
|
|||
const uint GOB_SIZE_X_SHIFT = 6; |
|||
const uint GOB_SIZE_Y_SHIFT = 3; |
|||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT; |
|||
|
|||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1u, GOB_SIZE_Y - 1u); |
|||
|
|||
uint SwizzleTable(uint pos) { |
|||
const uint t[8] = uint[]( |
|||
0x12100200, 0x13110301, 0x16140604, 0x17150705, |
|||
0x1a180a08, 0x1b190b09, 0x1e1c0e0c, 0x1f1d0f0d |
|||
); |
|||
const uint i = pos >> 4; |
|||
const uint h = (t[i / 4] >> ((i % 4) * 8)) & 0xff; |
|||
return (h << 4) | (pos & 0xf); |
|||
} |
|||
|
|||
uint SwizzleOffset(uvec2 pos) { |
|||
pos = pos & SWIZZLE_MASK; |
|||
return SwizzleTable(pos.y * 64u + pos.x); |
|||
} |
|||
|
|||
uvec4 ReadTexel(uint offset) { |
|||
switch (pc.bytes_per_block_log2) { |
|||
case 2u: |
|||
return uvec4(u32data[offset / 4u], 0u, 0u, 0u); |
|||
case 3u: |
|||
return uvec4(u64data[offset / 8u], 0u, 0u); |
|||
case 4u: |
|||
return u128data[offset / 16u]; |
|||
} |
|||
return uvec4(0u); |
|||
} |
|||
|
|||
void main() { |
|||
uvec3 coord = gl_GlobalInvocationID; |
|||
if (coord.x >= pc.dim.x || coord.y >= pc.dim.y || coord.z >= pc.dim.z) { |
|||
return; |
|||
} |
|||
|
|||
uvec3 pos = coord + pc.origin; |
|||
pos.x <<= pc.bytes_per_block_log2; |
|||
|
|||
uint swizzle = SwizzleOffset(pos.xy); |
|||
uint block_y = pos.y >> GOB_SIZE_Y_SHIFT; |
|||
|
|||
uint offset = 0u; |
|||
offset += pos.z * pc.layer_stride; |
|||
offset += (block_y >> pc.block_height) * pc.block_size; |
|||
offset += (block_y & pc.block_height_mask) << GOB_SIZE_SHIFT; |
|||
offset += (pos.x >> GOB_SIZE_X_SHIFT) << pc.x_shift; |
|||
offset += swizzle; |
|||
|
|||
uvec4 texel = ReadTexel(offset); |
|||
|
|||
uint words = 1u << (pc.bytes_per_block_log2 - 2u); |
|||
uint linear_index = coord.x + coord.y * pc.dim.x + coord.z * pc.dim.x * pc.dim.y; |
|||
uint out_idx = linear_index * words; |
|||
|
|||
out_u32[out_idx] = texel.x; |
|||
if (words > 1u) { |
|||
out_u32[out_idx + 1u] = texel.y; |
|||
} |
|||
if (words > 2u) { |
|||
out_u32[out_idx + 2u] = texel.z; |
|||
out_u32[out_idx + 3u] = texel.w; |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#version 430 |
|||
|
|||
#define BINDING_INPUT_BUFFER 0 |
|||
#define BINDING_OUTPUT_BUFFER 1 |
|||
|
|||
layout(push_constant) uniform PushConstants { |
|||
uvec3 dim; |
|||
uint bytes_per_block_log2; |
|||
|
|||
uvec3 origin; |
|||
uint slice_size; |
|||
|
|||
uint block_size; |
|||
uint x_shift; |
|||
uint block_height; |
|||
uint block_height_mask; |
|||
|
|||
uint block_depth; |
|||
uint block_depth_mask; |
|||
} pc; |
|||
|
|||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; }; |
|||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; }; |
|||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; }; |
|||
|
|||
layout(binding = BINDING_OUTPUT_BUFFER, std430) writeonly buffer OutputBuffer { |
|||
uint out_u32[]; |
|||
}; |
|||
|
|||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 4) in; |
|||
|
|||
const uint GOB_SIZE_X = 64; |
|||
const uint GOB_SIZE_Y = 8; |
|||
|
|||
const uint GOB_SIZE_X_SHIFT = 6; |
|||
const uint GOB_SIZE_Y_SHIFT = 3; |
|||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT; |
|||
|
|||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1u, GOB_SIZE_Y - 1u); |
|||
|
|||
uint SwizzleTable(uint pos) { |
|||
const uint t[8] = uint[]( |
|||
0x12100200, 0x13110301, 0x16140604, 0x17150705, |
|||
0x1a180a08, 0x1b190b09, 0x1e1c0e0c, 0x1f1d0f0d |
|||
); |
|||
const uint i = pos >> 4; |
|||
const uint h = (t[i / 4] >> ((i % 4) * 8)) & 0xff; |
|||
return (h << 4) | (pos & 0xf); |
|||
} |
|||
|
|||
uint SwizzleOffset(uvec2 pos) { |
|||
pos = pos & SWIZZLE_MASK; |
|||
return SwizzleTable(pos.y * 64u + pos.x); |
|||
} |
|||
|
|||
uvec4 ReadTexel(uint offset) { |
|||
switch (pc.bytes_per_block_log2) { |
|||
case 2u: |
|||
return uvec4(u32data[offset / 4u], 0u, 0u, 0u); |
|||
case 3u: |
|||
return uvec4(u64data[offset / 8u], 0u, 0u); |
|||
case 4u: |
|||
return u128data[offset / 16u]; |
|||
} |
|||
return uvec4(0u); |
|||
} |
|||
|
|||
void main() { |
|||
uvec3 coord = gl_GlobalInvocationID; |
|||
if (coord.x >= pc.dim.x || coord.y >= pc.dim.y || coord.z >= pc.dim.z) { |
|||
return; |
|||
} |
|||
|
|||
uvec3 pos = coord + pc.origin; |
|||
pos.x <<= pc.bytes_per_block_log2; |
|||
|
|||
uint swizzle = SwizzleOffset(pos.xy); |
|||
uint block_y = pos.y >> GOB_SIZE_Y_SHIFT; |
|||
|
|||
uint offset = 0u; |
|||
offset += (pos.z >> pc.block_depth) * pc.slice_size; |
|||
offset += (pos.z & pc.block_depth_mask) << (GOB_SIZE_SHIFT + pc.block_height); |
|||
offset += (block_y >> pc.block_height) * pc.block_size; |
|||
offset += (block_y & pc.block_height_mask) << GOB_SIZE_SHIFT; |
|||
offset += (pos.x >> GOB_SIZE_X_SHIFT) << pc.x_shift; |
|||
offset += swizzle; |
|||
|
|||
uvec4 texel = ReadTexel(offset); |
|||
|
|||
uint words = 1u << (pc.bytes_per_block_log2 - 2u); |
|||
uint linear_index = coord.x + coord.y * pc.dim.x + coord.z * pc.dim.x * pc.dim.y; |
|||
uint out_idx = linear_index * words; |
|||
|
|||
out_u32[out_idx] = texel.x; |
|||
if (words > 1u) { |
|||
out_u32[out_idx + 1u] = texel.y; |
|||
} |
|||
if (words > 2u) { |
|||
out_u32[out_idx + 2u] = texel.z; |
|||
out_u32[out_idx + 3u] = texel.w; |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue