| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #version 430
- #ifdef VULKAN
- #extension GL_EXT_shader_16bit_storage : require
- #extension GL_EXT_shader_8bit_storage : require
- #define HAS_EXTENDED_TYPES 1
- #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
- #define END_PUSH_CONSTANTS };
- #define UNIFORM(n)
- #define BINDING_INPUT_BUFFER 0
- #define BINDING_OUTPUT_IMAGE 1
- #else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
- #extension GL_NV_gpu_shader5 : enable
- #ifdef GL_NV_gpu_shader5
- #define HAS_EXTENDED_TYPES 1
- #else
- #define HAS_EXTENDED_TYPES 0
- #endif
- #define BEGIN_PUSH_CONSTANTS
- #define END_PUSH_CONSTANTS
- #define UNIFORM(n) layout (location = n) uniform
- #define BINDING_INPUT_BUFFER 0
- #define BINDING_OUTPUT_IMAGE 0
- #endif
- BEGIN_PUSH_CONSTANTS
- UNIFORM(0) uvec2 origin;
- UNIFORM(1) ivec2 destination;
- UNIFORM(2) uint bytes_per_block;
- UNIFORM(3) uint pitch;
- END_PUSH_CONSTANTS
- #if HAS_EXTENDED_TYPES
- layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU8 { uint8_t u8data[]; };
- layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU16 { uint16_t u16data[]; };
- #endif
- layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU32 { uint u32data[]; };
- layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU64 { uvec2 u64data[]; };
- layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU128 { uvec4 u128data[]; };
- layout(binding = BINDING_OUTPUT_IMAGE) writeonly uniform uimage2D output_image;
- layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
- uvec4 ReadTexel(uint offset) {
- switch (bytes_per_block) {
- #if HAS_EXTENDED_TYPES
- case 1:
- return uvec4(u8data[offset], 0, 0, 0);
- case 2:
- return uvec4(u16data[offset / 2], 0, 0, 0);
- #else
- case 1:
- return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
- case 2:
- return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
- #endif
- case 4:
- return uvec4(u32data[offset / 4], 0, 0, 0);
- case 8:
- return uvec4(u64data[offset / 8], 0, 0);
- case 16:
- return u128data[offset / 16];
- }
- return uvec4(0);
- }
- void main() {
- uvec2 pos = gl_GlobalInvocationID.xy + origin;
- uint offset = 0;
- offset += pos.x * bytes_per_block;
- offset += pos.y * pitch;
- const uvec4 texel = ReadTexel(offset);
- const ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + destination;
- imageStore(output_image, coord, texel);
- }
|