mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 13:16:43 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f801b5113b | |||
| a9c4c8aefd | |||
| a769505a45 |
@@ -5,11 +5,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <fmt/ranges.h>
|
#include <fmt/ranges.h>
|
||||||
|
|||||||
@@ -11,9 +11,8 @@
|
|||||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||||
#define END_PUSH_CONSTANTS };
|
#define END_PUSH_CONSTANTS };
|
||||||
#define UNIFORM(n)
|
#define UNIFORM(n)
|
||||||
#define BINDING_SWIZZLE_BUFFER 0
|
#define BINDING_INPUT_BUFFER 0
|
||||||
#define BINDING_INPUT_BUFFER 1
|
#define BINDING_OUTPUT_IMAGE 1
|
||||||
#define BINDING_OUTPUT_IMAGE 2
|
|
||||||
|
|
||||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||||
|
|
||||||
@@ -26,8 +25,7 @@
|
|||||||
#define BEGIN_PUSH_CONSTANTS
|
#define BEGIN_PUSH_CONSTANTS
|
||||||
#define END_PUSH_CONSTANTS
|
#define END_PUSH_CONSTANTS
|
||||||
#define UNIFORM(n) layout (location = n) uniform
|
#define UNIFORM(n) layout (location = n) uniform
|
||||||
#define BINDING_SWIZZLE_BUFFER 0
|
#define BINDING_INPUT_BUFFER 0
|
||||||
#define BINDING_INPUT_BUFFER 1
|
|
||||||
#define BINDING_OUTPUT_IMAGE 0
|
#define BINDING_OUTPUT_IMAGE 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -43,10 +41,6 @@ UNIFORM(6) uint block_height;
|
|||||||
UNIFORM(7) uint block_height_mask;
|
UNIFORM(7) uint block_height_mask;
|
||||||
END_PUSH_CONSTANTS
|
END_PUSH_CONSTANTS
|
||||||
|
|
||||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
|
||||||
uint swizzle_table[];
|
|
||||||
};
|
|
||||||
|
|
||||||
#if HAS_EXTENDED_TYPES
|
#if HAS_EXTENDED_TYPES
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||||
@@ -71,9 +65,19 @@ const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHI
|
|||||||
|
|
||||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
||||||
|
|
||||||
|
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) {
|
uint SwizzleOffset(uvec2 pos) {
|
||||||
pos = pos & SWIZZLE_MASK;
|
pos = pos & SWIZZLE_MASK;
|
||||||
return swizzle_table[pos.y * 64 + pos.x];
|
return SwizzleTable(pos.y * 64 + pos.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uvec4 ReadTexel(uint offset) {
|
uvec4 ReadTexel(uint offset) {
|
||||||
|
|||||||
@@ -11,9 +11,8 @@
|
|||||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||||
#define END_PUSH_CONSTANTS };
|
#define END_PUSH_CONSTANTS };
|
||||||
#define UNIFORM(n)
|
#define UNIFORM(n)
|
||||||
#define BINDING_SWIZZLE_BUFFER 0
|
#define BINDING_INPUT_BUFFER 0
|
||||||
#define BINDING_INPUT_BUFFER 1
|
#define BINDING_OUTPUT_IMAGE 1
|
||||||
#define BINDING_OUTPUT_IMAGE 2
|
|
||||||
|
|
||||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||||
|
|
||||||
@@ -26,8 +25,7 @@
|
|||||||
#define BEGIN_PUSH_CONSTANTS
|
#define BEGIN_PUSH_CONSTANTS
|
||||||
#define END_PUSH_CONSTANTS
|
#define END_PUSH_CONSTANTS
|
||||||
#define UNIFORM(n) layout (location = n) uniform
|
#define UNIFORM(n) layout (location = n) uniform
|
||||||
#define BINDING_SWIZZLE_BUFFER 0
|
#define BINDING_INPUT_BUFFER 0
|
||||||
#define BINDING_INPUT_BUFFER 1
|
|
||||||
#define BINDING_OUTPUT_IMAGE 0
|
#define BINDING_OUTPUT_IMAGE 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -45,10 +43,6 @@ UNIFORM(8) uint block_depth;
|
|||||||
UNIFORM(9) uint block_depth_mask;
|
UNIFORM(9) uint block_depth_mask;
|
||||||
END_PUSH_CONSTANTS
|
END_PUSH_CONSTANTS
|
||||||
|
|
||||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
|
||||||
uint swizzle_table[];
|
|
||||||
};
|
|
||||||
|
|
||||||
#if HAS_EXTENDED_TYPES
|
#if HAS_EXTENDED_TYPES
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||||
@@ -73,9 +67,19 @@ const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHI
|
|||||||
|
|
||||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
||||||
|
|
||||||
|
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) {
|
uint SwizzleOffset(uvec2 pos) {
|
||||||
pos = pos & SWIZZLE_MASK;
|
pos = pos & SWIZZLE_MASK;
|
||||||
return swizzle_table[pos.y * 64 + pos.x];
|
return SwizzleTable(pos.y * 64 + pos.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uvec4 ReadTexel(uint offset) {
|
uvec4 ReadTexel(uint offset) {
|
||||||
|
|||||||
@@ -10,9 +10,8 @@
|
|||||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||||
#define END_PUSH_CONSTANTS };
|
#define END_PUSH_CONSTANTS };
|
||||||
#define UNIFORM(n)
|
#define UNIFORM(n)
|
||||||
#define BINDING_SWIZZLE_BUFFER 0
|
#define BINDING_INPUT_BUFFER 0
|
||||||
#define BINDING_INPUT_BUFFER 1
|
#define BINDING_OUTPUT_BUFFER 1
|
||||||
#define BINDING_OUTPUT_BUFFER 2
|
|
||||||
#else
|
#else
|
||||||
#extension GL_NV_gpu_shader5 : enable
|
#extension GL_NV_gpu_shader5 : enable
|
||||||
#ifdef GL_NV_gpu_shader5
|
#ifdef GL_NV_gpu_shader5
|
||||||
@@ -23,7 +22,6 @@
|
|||||||
#define BEGIN_PUSH_CONSTANTS
|
#define BEGIN_PUSH_CONSTANTS
|
||||||
#define END_PUSH_CONSTANTS
|
#define END_PUSH_CONSTANTS
|
||||||
#define UNIFORM(n) layout(location = n) uniform
|
#define UNIFORM(n) layout(location = n) uniform
|
||||||
#define BINDING_SWIZZLE_BUFFER 0
|
|
||||||
#define BINDING_INPUT_BUFFER 1
|
#define BINDING_INPUT_BUFFER 1
|
||||||
#define BINDING_OUTPUT_BUFFER 0
|
#define BINDING_OUTPUT_BUFFER 0
|
||||||
#endif
|
#endif
|
||||||
@@ -66,13 +64,9 @@ END_PUSH_CONSTANTS
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// --- Buffers ---
|
// --- Buffers ---
|
||||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
|
||||||
uint swizzle_table[];
|
|
||||||
};
|
|
||||||
|
|
||||||
#if HAS_EXTENDED_TYPES
|
#if HAS_EXTENDED_TYPES
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||||
#endif
|
#endif
|
||||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
|
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 InputBufferU64 { uvec2 u64data[]; };
|
||||||
@@ -96,10 +90,20 @@ const uint GOB_SIZE_Z_SHIFT = 0;
|
|||||||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
|
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
|
||||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1u, GOB_SIZE_Y - 1u);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// --- Helpers ---
|
// --- Helpers ---
|
||||||
uint SwizzleOffset(uvec2 pos) {
|
uint SwizzleOffset(uvec2 pos) {
|
||||||
pos &= SWIZZLE_MASK;
|
pos &= SWIZZLE_MASK;
|
||||||
return swizzle_table[pos.y * 64u + pos.x];
|
return SwizzleTable(pos.y * 64u + pos.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uvec4 ReadTexel(uint offset) {
|
uvec4 ReadTexel(uint offset) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -56,10 +59,8 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
|
|||||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
|
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
|
||||||
convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)),
|
convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)),
|
||||||
convert_ms_to_nonms_program(MakeProgram(CONVERT_MSAA_TO_NON_MSAA_COMP)),
|
convert_ms_to_nonms_program(MakeProgram(CONVERT_MSAA_TO_NON_MSAA_COMP)),
|
||||||
convert_nonms_to_ms_program(MakeProgram(CONVERT_NON_MSAA_TO_MSAA_COMP)) {
|
convert_nonms_to_ms_program(MakeProgram(CONVERT_NON_MSAA_TO_MSAA_COMP))
|
||||||
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
|
{
|
||||||
swizzle_table_buffer.Create();
|
|
||||||
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UtilShaders::~UtilShaders() = default;
|
UtilShaders::~UtilShaders() = default;
|
||||||
@@ -116,13 +117,11 @@ void UtilShaders::ASTCDecode(Image& image, const StagingBufferMap& map,
|
|||||||
void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
|
void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
|
||||||
std::span<const SwizzleParameters> swizzles) {
|
std::span<const SwizzleParameters> swizzles) {
|
||||||
static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1};
|
static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1};
|
||||||
static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0;
|
static constexpr GLuint BINDING_INPUT_BUFFER = 0;
|
||||||
static constexpr GLuint BINDING_INPUT_BUFFER = 1;
|
|
||||||
static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
|
static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
|
||||||
|
|
||||||
program_manager.BindComputeProgram(block_linear_unswizzle_2d_program.handle);
|
program_manager.BindComputeProgram(block_linear_unswizzle_2d_program.handle);
|
||||||
glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
|
glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
|
|
||||||
|
|
||||||
const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format));
|
const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format));
|
||||||
for (const SwizzleParameters& swizzle : swizzles) {
|
for (const SwizzleParameters& swizzle : swizzles) {
|
||||||
@@ -153,14 +152,11 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
|
|||||||
void UtilShaders::BlockLinearUpload3D(Image& image, const StagingBufferMap& map,
|
void UtilShaders::BlockLinearUpload3D(Image& image, const StagingBufferMap& map,
|
||||||
std::span<const SwizzleParameters> swizzles) {
|
std::span<const SwizzleParameters> swizzles) {
|
||||||
static constexpr Extent3D WORKGROUP_SIZE{16, 8, 8};
|
static constexpr Extent3D WORKGROUP_SIZE{16, 8, 8};
|
||||||
|
static constexpr GLuint BINDING_INPUT_BUFFER = 0;
|
||||||
static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0;
|
|
||||||
static constexpr GLuint BINDING_INPUT_BUFFER = 1;
|
|
||||||
static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
|
static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
|
||||||
|
|
||||||
glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
|
glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
|
||||||
program_manager.BindComputeProgram(block_linear_unswizzle_3d_program.handle);
|
program_manager.BindComputeProgram(block_linear_unswizzle_3d_program.handle);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
|
|
||||||
|
|
||||||
const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format));
|
const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format));
|
||||||
for (const SwizzleParameters& swizzle : swizzles) {
|
for (const SwizzleParameters& swizzle : swizzles) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -45,9 +48,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ProgramManager& program_manager;
|
ProgramManager& program_manager;
|
||||||
|
|
||||||
OGLBuffer swizzle_table_buffer;
|
|
||||||
|
|
||||||
OGLProgram astc_decoder_program;
|
OGLProgram astc_decoder_program;
|
||||||
OGLProgram block_linear_unswizzle_2d_program;
|
OGLProgram block_linear_unswizzle_2d_program;
|
||||||
OGLProgram block_linear_unswizzle_3d_program;
|
OGLProgram block_linear_unswizzle_3d_program;
|
||||||
|
|||||||
@@ -653,71 +653,8 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
|
|||||||
scheduler.Finish();
|
scheduler.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 BL3D_BINDING_SWIZZLE_TABLE = 0;
|
constexpr u32 BL3D_BINDING_INPUT_BUFFER = 0;
|
||||||
constexpr u32 BL3D_BINDING_INPUT_BUFFER = 1;
|
constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 1;
|
||||||
constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 2;
|
|
||||||
|
|
||||||
constexpr std::array<VkDescriptorSetLayoutBinding, 3> BL3D_DESCRIPTOR_SET_BINDINGS{{
|
|
||||||
{
|
|
||||||
.binding = BL3D_BINDING_SWIZZLE_TABLE,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // swizzle_table[]
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
||||||
.pImmutableSamplers = nullptr,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.binding = BL3D_BINDING_INPUT_BUFFER,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // block-linear input
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
||||||
.pImmutableSamplers = nullptr,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.binding = BL3D_BINDING_OUTPUT_BUFFER,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
||||||
.pImmutableSamplers = nullptr,
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
|
|
||||||
constexpr DescriptorBankInfo BL3D_BANK_INFO{
|
|
||||||
.uniform_buffers = 0,
|
|
||||||
.storage_buffers = 3,
|
|
||||||
.texture_buffers = 0,
|
|
||||||
.image_buffers = 0,
|
|
||||||
.textures = 0,
|
|
||||||
.images = 0,
|
|
||||||
.score = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr std::array<VkDescriptorUpdateTemplateEntry, 3>
|
|
||||||
BL3D_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{
|
|
||||||
{
|
|
||||||
.dstBinding = BL3D_BINDING_SWIZZLE_TABLE,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
||||||
.offset = BL3D_BINDING_SWIZZLE_TABLE * sizeof(DescriptorUpdateEntry),
|
|
||||||
.stride = sizeof(DescriptorUpdateEntry),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.dstBinding = BL3D_BINDING_INPUT_BUFFER,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
||||||
.offset = BL3D_BINDING_INPUT_BUFFER * sizeof(DescriptorUpdateEntry),
|
|
||||||
.stride = sizeof(DescriptorUpdateEntry),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.dstBinding = BL3D_BINDING_OUTPUT_BUFFER,
|
|
||||||
.dstArrayElement = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
||||||
.offset = BL3D_BINDING_OUTPUT_BUFFER * sizeof(DescriptorUpdateEntry),
|
|
||||||
.stride = sizeof(DescriptorUpdateEntry),
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
struct alignas(16) BlockLinearUnswizzle3DPushConstants {
|
struct alignas(16) BlockLinearUnswizzle3DPushConstants {
|
||||||
u32 blocks_dim[3]; // Offset 0
|
u32 blocks_dim[3]; // Offset 0
|
||||||
@@ -745,11 +682,50 @@ BlockLinearUnswizzle3DPass::BlockLinearUnswizzle3DPass(
|
|||||||
DescriptorPool& descriptor_pool_,
|
DescriptorPool& descriptor_pool_,
|
||||||
StagingBufferPool& staging_buffer_pool_,
|
StagingBufferPool& staging_buffer_pool_,
|
||||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||||
: ComputePass(
|
: ComputePass(device_, scheduler_, descriptor_pool_,
|
||||||
device_, scheduler_, descriptor_pool_,
|
std::array<VkDescriptorSetLayoutBinding, 2>{{
|
||||||
BL3D_DESCRIPTOR_SET_BINDINGS,
|
{
|
||||||
BL3D_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY,
|
.binding = BL3D_BINDING_INPUT_BUFFER,
|
||||||
BL3D_BANK_INFO,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // block-linear input
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
.pImmutableSamplers = nullptr,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = BL3D_BINDING_OUTPUT_BUFFER,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
.pImmutableSamplers = nullptr,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
std::array<VkDescriptorUpdateTemplateEntry, 2>{{
|
||||||
|
{
|
||||||
|
.dstBinding = BL3D_BINDING_INPUT_BUFFER,
|
||||||
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.offset = BL3D_BINDING_INPUT_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||||
|
.stride = sizeof(DescriptorUpdateEntry),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dstBinding = BL3D_BINDING_OUTPUT_BUFFER,
|
||||||
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.offset = BL3D_BINDING_OUTPUT_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||||
|
.stride = sizeof(DescriptorUpdateEntry),
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
DescriptorBankInfo{
|
||||||
|
.uniform_buffers = 0,
|
||||||
|
.storage_buffers = 2,
|
||||||
|
.texture_buffers = 0,
|
||||||
|
.image_buffers = 0,
|
||||||
|
.textures = 0,
|
||||||
|
.images = 0,
|
||||||
|
.score = 2,
|
||||||
|
},
|
||||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(BlockLinearUnswizzle3DPushConstants)>,
|
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(BlockLinearUnswizzle3DPushConstants)>,
|
||||||
BLOCK_LINEAR_UNSWIZZLE_3D_BCN_COMP_SPV),
|
BLOCK_LINEAR_UNSWIZZLE_3D_BCN_COMP_SPV),
|
||||||
scheduler{scheduler_},
|
scheduler{scheduler_},
|
||||||
@@ -822,8 +798,6 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
|
|||||||
pc.blocks_dim[2] = z_count; // Only process the count
|
pc.blocks_dim[2] = z_count; // Only process the count
|
||||||
|
|
||||||
compute_pass_descriptor_queue.Acquire(scheduler, 3);
|
compute_pass_descriptor_queue.Acquire(scheduler, 3);
|
||||||
compute_pass_descriptor_queue.AddBuffer(*image.runtime->swizzle_table_buffer, 0,
|
|
||||||
image.runtime->swizzle_table_size);
|
|
||||||
compute_pass_descriptor_queue.AddBuffer(swizzled.buffer,
|
compute_pass_descriptor_queue.AddBuffer(swizzled.buffer,
|
||||||
sw.buffer_offset + swizzled.offset,
|
sw.buffer_offset + swizzled.offset,
|
||||||
image.guest_size_bytes - sw.buffer_offset);
|
image.guest_size_bytes - sw.buffer_offset);
|
||||||
|
|||||||
@@ -909,40 +909,6 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched
|
|||||||
bl3d_unswizzle_pass.emplace(device, scheduler, descriptor_pool,
|
bl3d_unswizzle_pass.emplace(device, scheduler, descriptor_pool,
|
||||||
staging_buffer_pool, compute_pass_descriptor_queue);
|
staging_buffer_pool, compute_pass_descriptor_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Create swizzle table buffer ---
|
|
||||||
{
|
|
||||||
auto table = Tegra::Texture::MakeSwizzleTable();
|
|
||||||
|
|
||||||
swizzle_table_size = static_cast<VkDeviceSize>(table.size() * sizeof(table[0]));
|
|
||||||
|
|
||||||
auto staging = staging_buffer_pool.Request(swizzle_table_size, MemoryUsage::Upload);
|
|
||||||
std::memcpy(staging.mapped_span.data(), table.data(), static_cast<size_t>(swizzle_table_size));
|
|
||||||
|
|
||||||
VkBufferCreateInfo ci{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
||||||
.size = swizzle_table_size,
|
|
||||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
||||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
||||||
};
|
|
||||||
swizzle_table_buffer = memory_allocator.CreateBuffer(ci, MemoryUsage::DeviceLocal);
|
|
||||||
|
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
|
||||||
scheduler.Record([staging_buf = staging.buffer,
|
|
||||||
dst_buf = *swizzle_table_buffer,
|
|
||||||
size = swizzle_table_size,
|
|
||||||
src_off = staging.offset](vk::CommandBuffer cmdbuf) {
|
|
||||||
|
|
||||||
const VkBufferCopy region{
|
|
||||||
.srcOffset = src_off,
|
|
||||||
.dstOffset = 0,
|
|
||||||
.size = size,
|
|
||||||
};
|
|
||||||
cmdbuf.CopyBuffer(staging_buf, dst_buf, region);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCacheRuntime::Finish() {
|
void TextureCacheRuntime::Finish() {
|
||||||
@@ -2484,18 +2450,13 @@ void TextureCacheRuntime::AccelerateImageUpload(
|
|||||||
|
|
||||||
if (!Settings::values.gpu_unswizzle_enabled.GetValue() || !bl3d_unswizzle_pass) {
|
if (!Settings::values.gpu_unswizzle_enabled.GetValue() || !bl3d_unswizzle_pass) {
|
||||||
if (IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D) {
|
if (IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D) {
|
||||||
ASSERT_MSG(false, "GPU unswizzle is disabled for BCn 3D texture");
|
ASSERT(false && "GPU unswizzle is disabled for BCn 3D texture");
|
||||||
}
|
}
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bl3d_unswizzle_pass &&
|
if (bl3d_unswizzle_pass && IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D && image.info.resources.levels == 1 && image.info.resources.layers == 1) {
|
||||||
IsPixelFormatBCn(image.info.format) &&
|
|
||||||
image.info.type == ImageType::e3D &&
|
|
||||||
image.info.resources.levels == 1 &&
|
|
||||||
image.info.resources.layers == 1) {
|
|
||||||
|
|
||||||
return bl3d_unswizzle_pass->Unswizzle(image, map, swizzles, z_start, z_count);
|
return bl3d_unswizzle_pass->Unswizzle(image, map, swizzles, z_start, z_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
@@ -130,9 +130,6 @@ public:
|
|||||||
std::optional<ASTCDecoderPass> astc_decoder_pass;
|
std::optional<ASTCDecoderPass> astc_decoder_pass;
|
||||||
|
|
||||||
std::optional<BlockLinearUnswizzle3DPass> bl3d_unswizzle_pass;
|
std::optional<BlockLinearUnswizzle3DPass> bl3d_unswizzle_pass;
|
||||||
vk::Buffer swizzle_table_buffer;
|
|
||||||
VkDeviceSize swizzle_table_size = 0;
|
|
||||||
|
|
||||||
std::optional<MSAACopyPass> msaa_copy_pass;
|
std::optional<MSAACopyPass> msaa_copy_pass;
|
||||||
const Settings::ResolutionScalingInfo& resolution;
|
const Settings::ResolutionScalingInfo& resolution;
|
||||||
std::array<std::vector<VkFormat>, VideoCore::Surface::MaxPixelFormat> view_formats;
|
std::array<std::vector<VkFormat>, VideoCore::Surface::MaxPixelFormat> view_formats;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -23,24 +26,6 @@ constexpr u32 GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_
|
|||||||
constexpr u32 SWIZZLE_X_BITS = 0b100101111;
|
constexpr u32 SWIZZLE_X_BITS = 0b100101111;
|
||||||
constexpr u32 SWIZZLE_Y_BITS = 0b011010000;
|
constexpr u32 SWIZZLE_Y_BITS = 0b011010000;
|
||||||
|
|
||||||
using SwizzleTable = std::array<std::array<u32, GOB_SIZE_X>, GOB_SIZE_Y>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This table represents the internal swizzle of a gob, in format 16 bytes x 2 sector packing.
|
|
||||||
* Calculates the offset of an (x, y) position within a swizzled texture.
|
|
||||||
* Taken from the Tegra X1 Technical Reference Manual. pages 1187-1188
|
|
||||||
*/
|
|
||||||
constexpr SwizzleTable MakeSwizzleTable() {
|
|
||||||
SwizzleTable table{};
|
|
||||||
for (u32 y = 0; y < table.size(); ++y) {
|
|
||||||
for (u32 x = 0; x < table[0].size(); ++x) {
|
|
||||||
table[y][x] = ((x % 64) / 32) * 256 + ((y % 8) / 2) * 64 + ((x % 32) / 16) * 32 +
|
|
||||||
(y % 2) * 16 + (x % 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unswizzles a block linear texture into linear memory.
|
/// Unswizzles a block linear texture into linear memory.
|
||||||
void UnswizzleTexture(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel,
|
void UnswizzleTexture(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel,
|
||||||
u32 width, u32 height, u32 depth, u32 block_height, u32 block_depth,
|
u32 width, u32 height, u32 depth, u32 block_height, u32 block_depth,
|
||||||
|
|||||||
Reference in New Issue
Block a user