Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/libs/prx/libSceAgcDriver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ add_custom_command(
VERBATIM
)

set(agcTextureRepackShaderSource ${CMAKE_CURRENT_SOURCE_DIR}/Graphics/shaders/TextureRepack.comp)
set(agcTextureRepackShaderSpv ${agcTextureDetileGeneratedDir}/TextureRepack.spv)
set(agcTextureRepackShaderHeader ${agcTextureDetileGeneratedDir}/TextureRepack_spv.h)
add_custom_command(
OUTPUT "${agcTextureRepackShaderHeader}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${agcTextureDetileGeneratedDir}"
COMMAND "$<TARGET_FILE:glslang-standalone>" -V --target-env vulkan1.1 -o "${agcTextureRepackShaderSpv}" "${agcTextureRepackShaderSource}"
COMMAND ${CMAKE_COMMAND} -DINPUT=${agcTextureRepackShaderSpv} -DOUTPUT=${agcTextureRepackShaderHeader}
-DSYMBOL=TEXTURE_REPACK_SPV -P "${CMAKE_CURRENT_SOURCE_DIR}/embed_spirv.cmake"
DEPENDS "${agcTextureRepackShaderSource}" glslang-standalone
VERBATIM
)

set(agcSampleCounterShaderSource ${CMAKE_CURRENT_SOURCE_DIR}/Graphics/shaders/SampleCounter.comp)
set(agcSampleCounterShaderSpv ${agcTextureDetileGeneratedDir}/SampleCounter.spv)
set(agcSampleCounterShaderHeader ${agcTextureDetileGeneratedDir}/SampleCounter_spv.h)
Expand Down Expand Up @@ -233,6 +246,7 @@ set(agcDriverSources
${agcCmaskClearShaderHeader}
${agcMeshArgumentsShaderHeader}
${agcTextureDetileImageShaderHeader}
${agcTextureRepackShaderHeader}
${agcSampleCounterShaderHeader}
${agcSampleDumpsShaderHeader}
${agcPresentationShaderHeaders}
Expand Down
4 changes: 4 additions & 0 deletions core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class Texture {
struct BlockCopyTag {};
Texture(const Context& context, const std::shared_ptr<StorageTexture>& source, const GuestTextureResource& descriptor, VkComponentMapping components, BlockCopyTag);
static bool CanBlockCopyFrom(const StorageTexture& source, const GuestTextureResource& descriptor);
struct RepackCopyTag {};
Texture(const Context& context, const std::shared_ptr<StorageTexture>& source, const GuestTextureResource& descriptor, VkComponentMapping components, RepackCopyTag);
static bool CanRepackCopyFrom(const StorageTexture& source, const GuestTextureResource& descriptor);
bool IsDepthCopy() const { return perUseCopy == PerUseCopy::RefreshedOnReuse; }
bool RefreshDepthCopy();
struct DepthCopyCounts {
Expand Down Expand Up @@ -147,6 +150,7 @@ class Texture {
std::uint64_t copiedVersion = 0;
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
VkFormat blockFormat = VK_FORMAT_UNDEFINED;
bool repackCopy = false;
std::uint32_t copyWidth = 0, copyHeight = 0, copyLevels = 0, copyLayers = 0, copyElementBytes = 0;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace AgcDriver::Graphics {
// leaving the other elements of both buffers alone.
void Dispatch(VkCommandBuffer commands, TextureTileMode tileMode, std::uint32_t elementBytes, VkBuffer source, std::uint64_t sourceOffset, VkBuffer destination, std::uint64_t destinationOffset, const TileMipLayout& layout, bool retile = false, std::uint32_t slice = 0, bool thick = false, const DetileWindow& window = {});
void DispatchImage(VkCommandBuffer commands, TextureTileMode tileMode, std::uint32_t elementBytes, VkBuffer tiled, std::uint64_t tiledOffset, VkImageView view, const TileMipLayout& layout, bool retile = false, std::uint32_t slice = 0, const DetileWindow& window = {});
void DispatchRepack(VkCommandBuffer commands, VkBuffer source, std::uint64_t sourceOffset, VkBuffer destination, std::uint64_t destinationOffset, std::uint64_t bytes);
static VkFormat ImageElementFormat(std::uint32_t elementBytes);
// Recycles the descriptor sets of the previous batch; call before recording a new command batch.
void BeginBatch();
Expand Down Expand Up @@ -83,6 +84,8 @@ namespace AgcDriver::Graphics {
VkDescriptorSetLayout imageDescriptorLayout = VK_NULL_HANDLE;
VkPipelineLayout imagePipelineLayout = VK_NULL_HANDLE;
VkShaderModule imageModule = VK_NULL_HANDLE;
VkShaderModule repackModule = VK_NULL_HANDLE;
VkPipeline repackPipeline = VK_NULL_HANDLE;
DescriptorRing imageDescriptorSets;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ std::optional<std::uint32_t> FindGuestTextureFormat(VkFormat format, std::uint32
std::optional<std::uint32_t> FindGuestColorTargetFormat(VkFormat format, std::uint32_t elementBytes);
std::uint32_t BytesPerElement(std::uint32_t guestFormat);
bool IsConvertedTextureFormat(std::uint32_t guestFormat);
bool IsRepackedTextureFormat(std::uint32_t guestFormat);
std::uint32_t RepackTextureWord(std::uint32_t word);
bool IsBlockCompressed(std::uint32_t guestFormat);
std::uint32_t BlockWidth(std::uint32_t guestFormat);
std::uint32_t BlockHeight(std::uint32_t guestFormat);
Expand Down
20 changes: 20 additions & 0 deletions core/libs/prx/libSceAgcDriver/Graphics/shaders/TextureRepack.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#version 450

layout(local_size_x = 64) in;

layout(std430, set = 0, binding = 0) readonly buffer Source { uint source[]; };
layout(std430, set = 0, binding = 1) buffer Destination { uint destination[]; };

layout(push_constant) uniform Push {
uint sourceBase;
uint destinationBase;
uint words;
uint rowWords;
} push;

void main() {
const uint index = gl_GlobalInvocationID.y * push.rowWords + gl_GlobalInvocationID.x;
if (gl_GlobalInvocationID.x >= push.rowWords || index >= push.words) return;
const uint word = source[push.sourceBase / 4u + index];
destination[push.destinationBase / 4u + index] = ((word >> 21u) & 0x7ffu) | (((word >> 10u) & 0x7ffu) << 11u) | ((word & 0x3ffu) << 22u);
}
14 changes: 12 additions & 2 deletions core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ VkComponentSwizzle ComponentSwizzleFor(std::uint8_t dstSel) {
}

VkComponentMapping ViewComponents(const GuestTextureResource& resource) {
if (IsConvertedTextureFormat(resource.format)) return {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
if (IsConvertedTextureFormat(resource.format) && !IsRepackedTextureFormat(resource.format)) return {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
const auto channel = [&](std::uint8_t dstSel) { return TextureComponentChannel(resource.format, ComponentSwizzleFor(dstSel)); };
return {channel(resource.dstSelX), channel(resource.dstSelY), channel(resource.dstSelZ), channel(resource.dstSelW)};
}
Expand Down Expand Up @@ -609,7 +609,8 @@ std::shared_ptr<Texture> cachedTexture(const Context& context, std::span<const s
const bool depthCopy = depthCompare && guestBytes >= DepthCopyMinBytes() && Texture::DepthCopyFormat(ResolveTextureFormat(resource.format)) != VK_FORMAT_UNDEFINED && resource.dimension != TextureDimension::k3D;
auto source = StorageTexture::FindPending(address, guestBytes);
const bool blockCopy = source != nullptr && !depthCompare && Texture::CanBlockCopyFrom(*source, resource);
if (source != nullptr && !blockCopy && (depthCompare ? !depthCopy || !Texture::CanDepthCopyFrom(*source, resource) : !Texture::CanCopyFrom(*source, resource))) source.reset();
const bool repackCopy = source != nullptr && !depthCompare && Texture::CanRepackCopyFrom(*source, resource);
if (source != nullptr && !blockCopy && !repackCopy && (depthCompare ? !depthCopy || !Texture::CanDepthCopyFrom(*source, resource) : !Texture::CanCopyFrom(*source, resource))) source.reset();
if (source != nullptr && MetadataMoved(*source, resource)) source.reset();
std::optional<DccKeys> keys;
bool clearThroughKeys = false;
Expand Down Expand Up @@ -653,6 +654,7 @@ std::shared_ptr<Texture> cachedTexture(const Context& context, std::span<const s
// The lookup's Refresh may have flushed another image's results over the memory (which
// marks the keys uncompressed): a surface that stays a snapshot re-reads them behind that
// flush, as it does behind its own. APS5_NO_KEYS_RESCAN=1 keeps the keys scanned above.
if (source != nullptr && IsRepackedTextureFormat(resource.format) && !Texture::CanRepackCopyFrom(*source, resource)) source.reset();
static const bool rescan = std::getenv("APS5_NO_KEYS_RESCAN") == nullptr;
if (rescan && source == nullptr) keys.reset();
}
Expand Down Expand Up @@ -695,6 +697,11 @@ std::shared_ptr<Texture> cachedTexture(const Context& context, std::span<const s
texture->RefreshDepthCopy();
return texture;
}
if (source != nullptr && IsRepackedTextureFormat(resource.format)) {
auto texture = std::make_shared<Texture>(context, source, resource, components, Texture::RepackCopyTag{});
texture->RefreshDepthCopy();
return texture;
}
if (source != nullptr) return std::make_shared<Texture>(context, source, resource, components);
std::vector<std::byte> snapshot(bytes);
ReadTextureSurface(resource, *keys, snapshot);
Expand Down Expand Up @@ -773,6 +780,9 @@ std::shared_ptr<Texture> cachedTexture(const Context& context, std::span<const s
} else if (blockCopy) {
entry.texture = std::make_shared<Texture>(context, source, resource, components, Texture::BlockCopyTag{});
entry.texture->RefreshDepthCopy();
} else if (IsRepackedTextureFormat(resource.format)) {
entry.texture = std::make_shared<Texture>(context, source, resource, components, Texture::RepackCopyTag{});
entry.texture->RefreshDepthCopy();
} else {
entry.texture = std::make_shared<Texture>(context, source, resource, components);
}
Expand Down
Loading
Loading