Compare commits

..

1 Commits

Author SHA1 Message Date
xbzk f342aac4de [cmake] Fix CI package cache keys 2026-06-30 22:47:05 -03:00
13 changed files with 222 additions and 188 deletions
+5 -1
View File
@@ -370,6 +370,7 @@ function(AddPackage)
URL
KEY
SOURCE_SUBDIR
BUNDLED_PACKAGE
FORCE_BUNDLED_PACKAGE
@@ -434,7 +435,9 @@ function(AddPackage)
cpm_utils_message(DEBUG ${PKG_ARGS_NAME} "Download URL is ${pkg_url}")
if(DEFINED PKG_ARGS_SHA)
if(DEFINED PKG_ARGS_KEY AND NOT PKG_ARGS_KEY STREQUAL "")
set(pkg_key ${PKG_ARGS_KEY})
elseif(DEFINED PKG_ARGS_SHA)
string(SUBSTRING ${PKG_ARGS_SHA} 0 4 pkg_key)
elseif(DEFINED PKG_ARGS_VERSION)
set(pkg_key ${PKG_ARGS_VERSION})
@@ -717,6 +720,7 @@ function(AddCIPackage)
TAG "v${ARTIFACT_VERSION}"
MIN_VERSION ${ARTIFACT_VERSION}
ARTIFACT ${ARTIFACT}
KEY "${pkgname}-${ARTIFACT_VERSION}"
HASH ${sha512sum_hash}
FORCE_BUNDLED_PACKAGE ON
${EXTRA_ARGS})
+33 -75
View File
@@ -58,24 +58,16 @@ endif()
if (PLATFORM_PS4 OR PLATFORM_MANAGARM)
# Doesn't support VA-API, don't go thru the embarrassment of trying to enable it
list(APPEND FFmpeg_HWACCEL_FLAGS
--disable-vaapi
--disnable-cuvid
--disnable-ffnvcodec
--disnable-nvdec
--disable-vulkan
--disable-libdrm)
elseif (UNIX)
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING AND NOT ANDROID)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
pkg_check_modules(CUDA cuda)
pkg_check_modules(FFNVCODEC ffnvcodec)
pkg_check_modules(VDPAU vdpau)
# X11 is "optional", some distros may opt for a super-fully wayland install...
find_package(X11)
if(X11_FOUND)
# Include X11 if possible, some APIs such as VDPAU heavily depend
# upon it's existence!
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${X11_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${X11_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${X11_LDFLAGS})
if (NOT APPLE)
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
if(PLATFORM_SUN)
@@ -84,37 +76,32 @@ elseif (UNIX)
"${CMAKE_SYSROOT}/usr/lib/xorg/amd64/libdrm.so")
else()
pkg_check_modules(LIBDRM libdrm REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${LIBDRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${LIBDRM_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${LIBDRM_LDFLAGS})
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${LIBDRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS})
endif()
list(APPEND FFmpeg_HWACCEL_FLAGS --enable-libdrm)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm)
endif()
pkg_check_modules(LIBVA libva)
if(LIBVA_FOUND)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${LIBVA_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${LIBVA_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${LIBVA_LDFLAGS})
# Logically, they can only exist if libva itself exists
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
if (LIBVA-DRM_FOUND)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${LIBVA-DRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${LIBVA-DRM_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${LIBVA-DRM_LDFLAGS})
endif()
if (LIBVA-X11_FOUND)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${LIBVA-X11_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${LIBVA-X11_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${LIBVA-X11_LDFLAGS})
endif()
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${X11_LIBRARIES}
${LIBVA-DRM_LIBRARIES}
${LIBVA-X11_LIBRARIES}
${LIBVA_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-hwaccel=h264_vaapi
--enable-hwaccel=vp8_vaapi
--enable-hwaccel=vp9_vaapi)
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${X11_INCLUDE_DIRS}
${LIBVA-DRM_INCLUDE_DIRS}
${LIBVA-X11_INCLUDE_DIRS}
${LIBVA_INCLUDE_DIRS}
)
message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found")
else()
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
@@ -125,12 +112,6 @@ elseif (UNIX)
message(WARNING "ffmpeg: X11 libraries not found, disabling VA-API...")
endif()
pkg_check_modules(CUDA cuda)
pkg_check_modules(FFNVCODEC ffnvcodec)
pkg_check_modules(VDPAU vdpau)
pkg_check_modules(VULKAN vulkan)
find_package(spirv-headers)
if (FFNVCODEC_FOUND)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-cuvid
@@ -138,7 +119,8 @@ elseif (UNIX)
--enable-nvdec
--enable-hwaccel=h264_nvdec
--enable-hwaccel=vp8_nvdec
--enable-hwaccel=vp9_nvdec)
--enable-hwaccel=vp9_nvdec
)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${FFNVCODEC_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${FFNVCODEC_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${FFNVCODEC_LDFLAGS})
@@ -159,7 +141,8 @@ elseif (UNIX)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-vdpau
--enable-hwaccel=h264_vdpau
--enable-hwaccel=vp9_vdpau)
--enable-hwaccel=vp9_vdpau
)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
@@ -168,24 +151,6 @@ elseif (UNIX)
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
message(WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)...")
endif()
if (VULKAN_FOUND AND NOT APPLE)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-vulkan
--enable-hwaccel=h264_vulkan
--enable-hwaccel=vp9_vulkan)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VULKAN_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VULKAN_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VULKAN_LDFLAGS})
message(STATUS "ffmpeg: vulkan libraries version ${VULKAN_VERSION} found")
endif()
if (SPIRV_HEADERS_FOUND)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${SPIRV_HEADERS_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${SPIRV_HEADERS_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${SPIRV_HEADERS_LDFLAGS})
message(STATUS "ffmpeg: spirv-headers libraries version ${SPIRV_HEADERS_VERSION} found")
endif()
endif()
if (PLATFORM_PS4)
@@ -204,7 +169,7 @@ if (PLATFORM_PS4)
)
elseif (PLATFORM_MANAGARM)
# Required for proper stuff
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
--disable-pthreads
--extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}"
)
@@ -282,14 +247,8 @@ else()
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
# `--disable-vdpau` is needed to avoid linking issues
set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
set(FFmpeg_CXX ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER})
if (FFmpeg_IS_CROSS_COMPILING)
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --ld=${CMAKE_LINKER})
endif ()
# TODO: This is a bit fragile, it depends on FFmpeg_HWACCEL_LDFLAGS being a list
# whereas CMAKE_C_FLAGS (and likewise) is meant to NOT be a list, but rather
# an elongated piece of string
set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
set(FFmpeg_CXX ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER})
add_custom_command(
OUTPUT
${FFmpeg_MAKEFILE}
@@ -303,7 +262,6 @@ else()
--disable-ffprobe
--disable-network
--disable-swresample
--disable-iconv
--enable-decoder=h264
--enable-decoder=vp8
--enable-decoder=vp9
@@ -311,9 +269,10 @@ else()
--enable-pic
--cc=${FFmpeg_CC}
--cxx=${FFmpeg_CXX}
--ld=${CMAKE_LINKER}
--extra-cflags=${CMAKE_C_FLAGS}
--extra-cxxflags=${CMAKE_CXX_FLAGS}
--extra-ldflags="${FFmpeg_HWACCEL_LDFLAGS}"
--extra-ldflags=${CMAKE_C_LINK_FLAGS}
${FFmpeg_HWACCEL_FLAGS}
${FFmpeg_CROSS_COMPILE_FLAGS}
WORKING_DIRECTORY
@@ -321,7 +280,6 @@ else()
)
unset(FFmpeg_CC)
unset(FFmpeg_CXX)
unset(FFmpeg_LD)
unset(FFmpeg_HWACCEL_FLAGS)
unset(FFmpeg_CROSS_COMPILE_FLAGS)
@@ -336,7 +294,7 @@ else()
set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
# BSD make or Solaris make don't support ffmpeg make-j8
if (DEFINED SYSTEM_THREADS AND (PLATFORM_LINUX OR ANDROID OR APPLE OR WIN32 OR PLATFORM_FREEBSD))
if (PLATFORM_LINUX OR ANDROID OR APPLE OR WIN32 OR PLATFORM_FREEBSD)
set(FFmpeg_MAKE_ARGS -j${SYSTEM_THREADS})
else()
set(FFmpeg_MAKE_ARGS "")
@@ -11,8 +11,9 @@
#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
#define BINDING_SWIZZLE_BUFFER 0
#define BINDING_INPUT_BUFFER 1
#define BINDING_OUTPUT_IMAGE 2
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
@@ -25,7 +26,8 @@
#define BEGIN_PUSH_CONSTANTS
#define END_PUSH_CONSTANTS
#define UNIFORM(n) layout (location = n) uniform
#define BINDING_INPUT_BUFFER 0
#define BINDING_SWIZZLE_BUFFER 0
#define BINDING_INPUT_BUFFER 1
#define BINDING_OUTPUT_IMAGE 0
#endif
@@ -41,6 +43,10 @@ UNIFORM(6) uint block_height;
UNIFORM(7) uint block_height_mask;
END_PUSH_CONSTANTS
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
uint swizzle_table[];
};
#if HAS_EXTENDED_TYPES
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
@@ -65,19 +71,9 @@ 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);
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 * 64 + pos.x);
return swizzle_table[pos.y * 64 + pos.x];
}
uvec4 ReadTexel(uint offset) {
@@ -11,8 +11,9 @@
#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
#define BINDING_SWIZZLE_BUFFER 0
#define BINDING_INPUT_BUFFER 1
#define BINDING_OUTPUT_IMAGE 2
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
@@ -25,7 +26,8 @@
#define BEGIN_PUSH_CONSTANTS
#define END_PUSH_CONSTANTS
#define UNIFORM(n) layout (location = n) uniform
#define BINDING_INPUT_BUFFER 0
#define BINDING_SWIZZLE_BUFFER 0
#define BINDING_INPUT_BUFFER 1
#define BINDING_OUTPUT_IMAGE 0
#endif
@@ -43,6 +45,10 @@ UNIFORM(8) uint block_depth;
UNIFORM(9) uint block_depth_mask;
END_PUSH_CONSTANTS
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
uint swizzle_table[];
};
#if HAS_EXTENDED_TYPES
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
@@ -67,19 +73,9 @@ 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);
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 * 64 + pos.x);
return swizzle_table[pos.y * 64 + pos.x];
}
uvec4 ReadTexel(uint offset) {
@@ -10,8 +10,9 @@
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
#define END_PUSH_CONSTANTS };
#define UNIFORM(n)
#define BINDING_INPUT_BUFFER 0
#define BINDING_OUTPUT_BUFFER 1
#define BINDING_SWIZZLE_BUFFER 0
#define BINDING_INPUT_BUFFER 1
#define BINDING_OUTPUT_BUFFER 2
#else
#extension GL_NV_gpu_shader5 : enable
#ifdef GL_NV_gpu_shader5
@@ -22,6 +23,7 @@
#define BEGIN_PUSH_CONSTANTS
#define END_PUSH_CONSTANTS
#define UNIFORM(n) layout(location = n) uniform
#define BINDING_SWIZZLE_BUFFER 0
#define BINDING_INPUT_BUFFER 1
#define BINDING_OUTPUT_BUFFER 0
#endif
@@ -64,9 +66,13 @@ END_PUSH_CONSTANTS
#endif
// --- Buffers ---
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
uint swizzle_table[];
};
#if HAS_EXTENDED_TYPES
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 InputBufferU8 { uint8_t u8data[]; };
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
#endif
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
@@ -90,20 +96,10 @@ 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 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 ---
uint SwizzleOffset(uvec2 pos) {
pos &= SWIZZLE_MASK;
return SwizzleTable(pos.y * 64u + pos.x);
return swizzle_table[pos.y * 64u + pos.x];
}
uvec4 ReadTexel(uint offset) {
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -59,8 +56,10 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_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;
@@ -117,11 +116,13 @@ void UtilShaders::ASTCDecode(Image& image, const StagingBufferMap& map,
void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
std::span<const SwizzleParameters> swizzles) {
static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1};
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;
program_manager.BindComputeProgram(block_linear_unswizzle_2d_program.handle);
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));
for (const SwizzleParameters& swizzle : swizzles) {
@@ -152,11 +153,14 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
void UtilShaders::BlockLinearUpload3D(Image& image, const StagingBufferMap& map,
std::span<const SwizzleParameters> swizzles) {
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;
glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
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));
for (const SwizzleParameters& swizzle : swizzles) {
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -48,6 +45,9 @@ public:
private:
ProgramManager& program_manager;
OGLBuffer swizzle_table_buffer;
OGLProgram astc_decoder_program;
OGLProgram block_linear_unswizzle_2d_program;
OGLProgram block_linear_unswizzle_3d_program;
@@ -203,11 +203,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
const VideoCommon::ImageViewId image_view_id{(views++)->id};
const VideoCommon::SamplerId sampler_id{*(samplers++)};
ImageView& image_view{texture_cache.GetImageView(image_view_id)};
VkImageView vk_image_view{image_view.Handle(desc.type)};
if (vk_image_view == VK_NULL_HANDLE) {
const VkImageView null_image_view{texture_cache.GetImageView(VideoCommon::NULL_IMAGE_VIEW_ID).Handle(desc.type)};
if (null_image_view != VK_NULL_HANDLE) vk_image_view = null_image_view;
}
const VkImageView vk_image_view{image_view.Handle(desc.type)};
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
!image_view.SupportsAnisotropy()};
@@ -653,8 +653,71 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
scheduler.Finish();
}
constexpr u32 BL3D_BINDING_INPUT_BUFFER = 0;
constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 1;
constexpr u32 BL3D_BINDING_SWIZZLE_TABLE = 0;
constexpr u32 BL3D_BINDING_INPUT_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 {
u32 blocks_dim[3]; // Offset 0
@@ -682,50 +745,11 @@ BlockLinearUnswizzle3DPass::BlockLinearUnswizzle3DPass(
DescriptorPool& descriptor_pool_,
StagingBufferPool& staging_buffer_pool_,
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
: ComputePass(device_, scheduler_, descriptor_pool_,
std::array<VkDescriptorSetLayoutBinding, 2>{{
{
.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,
},
}},
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,
},
: ComputePass(
device_, scheduler_, descriptor_pool_,
BL3D_DESCRIPTOR_SET_BINDINGS,
BL3D_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY,
BL3D_BANK_INFO,
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(BlockLinearUnswizzle3DPushConstants)>,
BLOCK_LINEAR_UNSWIZZLE_3D_BCN_COMP_SPV),
scheduler{scheduler_},
@@ -798,6 +822,8 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
pc.blocks_dim[2] = z_count; // Only process the count
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,
sw.buffer_offset + swizzled.offset,
image.guest_size_bytes - sw.buffer_offset);
@@ -909,6 +909,40 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched
bl3d_unswizzle_pass.emplace(device, scheduler, descriptor_pool,
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() {
@@ -2450,13 +2484,18 @@ void TextureCacheRuntime::AccelerateImageUpload(
if (!Settings::values.gpu_unswizzle_enabled.GetValue() || !bl3d_unswizzle_pass) {
if (IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D) {
ASSERT(false && "GPU unswizzle is disabled for BCn 3D texture");
ASSERT_MSG(false, "GPU unswizzle is disabled for BCn 3D texture");
}
ASSERT(false);
return;
}
if (bl3d_unswizzle_pass && IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D && image.info.resources.levels == 1 && image.info.resources.layers == 1) {
if (bl3d_unswizzle_pass &&
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);
}
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
@@ -130,6 +130,9 @@ public:
std::optional<ASTCDecoderPass> astc_decoder_pass;
std::optional<BlockLinearUnswizzle3DPass> bl3d_unswizzle_pass;
vk::Buffer swizzle_table_buffer;
VkDeviceSize swizzle_table_size = 0;
std::optional<MSAACopyPass> msaa_copy_pass;
const Settings::ResolutionScalingInfo& resolution;
std::array<std::vector<VkFormat>, VideoCore::Surface::MaxPixelFormat> view_formats;
+3 -2
View File
@@ -255,7 +255,8 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
static constexpr u64 SELF_BRANCH_A = 0xE2400FFFFF87000FULL;
static constexpr u64 SELF_BRANCH_B = 0xE2400FFFFF07000FULL;
static constexpr u64 EXIT_VALUE = 0xE30000000007000FULL;
static constexpr u64 MESA_EXIT_MASK = 0xFFF00000000F001FULL;
static constexpr u64 MESA_EXIT_VALUE = (0xE30ULL << 52) | (0x7ULL << 16) | 0xFULL;
code.resize(MAXIMUM_SIZE / INST_SIZE);
@@ -270,7 +271,7 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
if (inst == SELF_BRANCH_A || inst == SELF_BRANCH_B) {
return offset + index;
}
if (!is_proprietary_driver && inst == EXIT_VALUE) {
if ((inst & MESA_EXIT_MASK) == MESA_EXIT_VALUE) {
return offset + index + INST_SIZE;
}
}
+18 -3
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -26,6 +23,24 @@ 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_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.
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,