pitch_unswizzle.comp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #version 430
  4. #ifdef VULKAN
  5. #extension GL_EXT_shader_16bit_storage : require
  6. #extension GL_EXT_shader_8bit_storage : require
  7. #define HAS_EXTENDED_TYPES 1
  8. #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
  9. #define END_PUSH_CONSTANTS };
  10. #define UNIFORM(n)
  11. #define BINDING_INPUT_BUFFER 0
  12. #define BINDING_OUTPUT_IMAGE 1
  13. #else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
  14. #extension GL_NV_gpu_shader5 : enable
  15. #ifdef GL_NV_gpu_shader5
  16. #define HAS_EXTENDED_TYPES 1
  17. #else
  18. #define HAS_EXTENDED_TYPES 0
  19. #endif
  20. #define BEGIN_PUSH_CONSTANTS
  21. #define END_PUSH_CONSTANTS
  22. #define UNIFORM(n) layout (location = n) uniform
  23. #define BINDING_INPUT_BUFFER 0
  24. #define BINDING_OUTPUT_IMAGE 0
  25. #endif
  26. BEGIN_PUSH_CONSTANTS
  27. UNIFORM(0) uvec2 origin;
  28. UNIFORM(1) ivec2 destination;
  29. UNIFORM(2) uint bytes_per_block;
  30. UNIFORM(3) uint pitch;
  31. END_PUSH_CONSTANTS
  32. #if HAS_EXTENDED_TYPES
  33. layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU8 { uint8_t u8data[]; };
  34. layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU16 { uint16_t u16data[]; };
  35. #endif
  36. layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU32 { uint u32data[]; };
  37. layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU64 { uvec2 u64data[]; };
  38. layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU128 { uvec4 u128data[]; };
  39. layout(binding = BINDING_OUTPUT_IMAGE) writeonly uniform uimage2D output_image;
  40. layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
  41. uvec4 ReadTexel(uint offset) {
  42. switch (bytes_per_block) {
  43. #if HAS_EXTENDED_TYPES
  44. case 1:
  45. return uvec4(u8data[offset], 0, 0, 0);
  46. case 2:
  47. return uvec4(u16data[offset / 2], 0, 0, 0);
  48. #else
  49. case 1:
  50. return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
  51. case 2:
  52. return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
  53. #endif
  54. case 4:
  55. return uvec4(u32data[offset / 4], 0, 0, 0);
  56. case 8:
  57. return uvec4(u64data[offset / 8], 0, 0);
  58. case 16:
  59. return u128data[offset / 16];
  60. }
  61. return uvec4(0);
  62. }
  63. void main() {
  64. uvec2 pos = gl_GlobalInvocationID.xy + origin;
  65. uint offset = 0;
  66. offset += pos.x * bytes_per_block;
  67. offset += pos.y * pitch;
  68. const uvec4 texel = ReadTexel(offset);
  69. const ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + destination;
  70. imageStore(output_image, coord, texel);
  71. }