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
10 changes: 7 additions & 3 deletions core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ class Texture {
// compute pass writing it and the next pass sampling it share one image and copy nothing.
// CanCopyFrom says whether the two descriptors address the same surface compatibly.
Texture(const Context& context, const std::shared_ptr<StorageTexture>& source, const GuestTextureResource& descriptor, VkComponentMapping components);
Texture(const Context& context, VkImage depthImage, VkFormat depthFormat, VkImageAspectFlags aspect, VkComponentMapping components);
Texture(const Context& context, VkImage depthImage, VkFormat depthFormat, VkImageAspectFlags aspect, VkComponentMapping components, VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D);
struct DepthCopyTag {};
Texture(const Context& context, const std::shared_ptr<StorageTexture>& source, const GuestTextureResource& descriptor, VkComponentMapping components, DepthCopyTag);
static VkFormat DepthCopyFormat(VkFormat colorFormat);
static bool CanDepthCopyFrom(const StorageTexture& source, const GuestTextureResource& descriptor);
bool IsDepthCopy() const { return depthCopy; }
bool IsDepthCopy() const { return perUseCopy == PerUseCopy::RefreshedOnReuse; }
bool RefreshDepthCopy();
struct DepthCopyCounts {
std::uint64_t textures;
Expand Down Expand Up @@ -99,6 +99,10 @@ class Texture {
// the source image's own (snapshots, views over other metadata); one per cache entry, so every
// object binding the texture shares it. Under GuestMemory::GpuMutex only.
DccKeyProof& KeyProof() const { return keyProof; }
enum class PerUseCopy : std::uint8_t { None, RefreshedOnReuse, RemadePerUse };
PerUseCopy CopyKind() const { return perUseCopy; }
bool RefreshedPerUse() const { return perUseCopy == PerUseCopy::RemadePerUse; }
void MarkRefreshedPerUse() { perUseCopy = PerUseCopy::RemadePerUse; }

private:
void release() noexcept;
Expand All @@ -125,7 +129,7 @@ class Texture {
std::shared_ptr<ResidentColor> source;
std::shared_ptr<StorageTexture> storageSource;
std::unique_ptr<CommandBatch> upload;
bool depthCopy = false;
PerUseCopy perUseCopy = PerUseCopy::None;
bool copiedOnce = false;
std::uint64_t copiedVersion = 0;
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
Expand Down
209 changes: 194 additions & 15 deletions core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,7 @@ void ShaderResources::noteReusable() {
reusable = false;
directRegions.clear();
if (guestMemory.HasCopiedWrites() || HoldsLease() || usesBda || (bda != nullptr && LoopGuardEnabled())) return;
if (std::any_of(textures.begin(), textures.end(), [](const std::shared_ptr<Texture>& texture) { return texture != nullptr && texture->RefreshedPerUse(); })) return;
if (TemplateDataRefresh() && std::any_of(allocations.begin(), allocations.end(), [](const Allocation& allocation) { return allocation.buffer != nullptr && !allocation.guest && allocation.size > MaxRefreshBytes; })) return;
const auto regions = guestMemory.DirectRegions();
if (!regions.has_value()) return;
Expand Down Expand Up @@ -3194,7 +3195,7 @@ bool ShaderResources::precollectImages() {
}

std::shared_ptr<Texture> ShaderResources::fastTexture(const ImageRecord& record) {
if (record.texture == nullptr) return nullptr;
if (record.texture == nullptr || record.texture->RefreshedPerUse()) return nullptr;
struct Outcome {
bool profile;
std::chrono::steady_clock::time_point start;
Expand Down
15 changes: 10 additions & 5 deletions core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ bool Texture::CanDepthCopyFrom(const StorageTexture& source, const GuestTextureR
return geometry.imageDepth == 1 && source.ImageDepth() == 1 && source.ImageLayers() >= geometry.imageLayers && source.Descriptor().mipCount >= descriptor.mipCount;
}

Texture::Texture(const Context& context, const std::shared_ptr<StorageTexture>& source, const GuestTextureResource& descriptor, VkComponentMapping components, DepthCopyTag) : context(context), storageSource(source), depthCopy(true) {
Texture::Texture(const Context& context, const std::shared_ptr<StorageTexture>& source, const GuestTextureResource& descriptor, VkComponentMapping components, DepthCopyTag) : context(context), storageSource(source), perUseCopy(PerUseCopy::RefreshedOnReuse) {
try {
Require(source != nullptr && CanDepthCopyFrom(*source, descriptor), "storage image cannot serve a depth copy of the sampled texture");
const auto colorFormat = ResolveTextureFormat(descriptor.format);
Expand Down Expand Up @@ -535,7 +535,7 @@ Texture::Texture(const Context& context, const std::shared_ptr<StorageTexture>&
}

bool Texture::RefreshDepthCopy() {
if (!depthCopy || storageSource == nullptr) return false;
if (perUseCopy != PerUseCopy::RefreshedOnReuse || storageSource == nullptr) return false;
if (copiedOnce && storageSource->Version() == copiedVersion) return false;
std::uint64_t linearBytes = 0;
for (std::uint32_t level = 0; level < copyLevels; ++level) linearBytes += static_cast<std::uint64_t>(std::max(copyWidth >> level, 1u)) * std::max(copyHeight >> level, 1u) * copyElementBytes * copyLayers;
Expand Down Expand Up @@ -660,17 +660,22 @@ Texture::Texture(const Context& context, const std::shared_ptr<StorageTexture>&
}
}

Texture::Texture(const Context& context, VkImage depthImage, VkFormat depthFormat, VkImageAspectFlags aspect, VkComponentMapping components) : context(context) {
Texture::Texture(const Context& context, VkImage depthImage, VkFormat depthFormat, VkImageAspectFlags aspect, VkComponentMapping components, VkImageViewType viewType) : context(context) {
layout = VK_IMAGE_LAYOUT_GENERAL;
VkImageViewCreateInfo viewInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
viewInfo.image = depthImage;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.viewType = viewType;
viewInfo.format = depthFormat;
viewFormat = depthFormat;
viewInfo.components = components;
viewInfo.subresourceRange = {aspect, 0, 1, 0, 1};
viewInfo.subresourceRange = {aspect, 0, 1, 0, viewType == VK_IMAGE_VIEW_TYPE_2D ? 1u : VK_REMAINING_ARRAY_LAYERS};
Check(context.Function<PFN_vkCreateImageView>("vkCreateImageView")(context.device, &viewInfo, nullptr, &view), "vkCreateImageView depth plane");
viewRange = {viewInfo.viewType, viewInfo.subresourceRange.levelCount, viewInfo.subresourceRange.layerCount};
if (viewType != VK_IMAGE_VIEW_TYPE_2D_ARRAY) return;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.subresourceRange.layerCount = 1;
Check(context.Function<PFN_vkCreateImageView>("vkCreateImageView")(context.device, &viewInfo, nullptr, &firstLayerView), "vkCreateImageView depth plane first layer");
firstLayerRange = {viewInfo.viewType, viewInfo.subresourceRange.levelCount, viewInfo.subresourceRange.layerCount};
}

Texture::~Texture() {
Expand Down
11 changes: 11 additions & 0 deletions core/libs/prx/libSceAgcDriver/tests/DepthSurfaceReuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ constexpr std::uint32_t FormatR32Uint = 20;
constexpr std::uint32_t FormatR32Float = 22;
constexpr std::uint32_t FormatR11G11B10Float = 36;
constexpr std::uint32_t FormatR8G8B8A8Unorm = 56;
constexpr std::uint32_t TileStandard64KB = 0x9;
constexpr std::uint32_t TileDepth64KB = 0x18;
constexpr std::uint32_t TileRenderTarget64KB = 0x1b;
constexpr std::uint32_t Type2D = 9;
Expand Down Expand Up @@ -181,6 +182,16 @@ void TestD16StencilFallback(const Context& context) {
Require(lookup(without, {d16s8Stencil, FormatR8Uint, 256, 256}) != nullptr, "an 8-bit view of the stencil plane of a D16 surface stored as D24 must sample it");
Require(HostDepthBiasConstant(without, VK_FORMAT_D16_UNORM_S8_UINT, 2.0f) == 512.0f, "a 16-bit depth bias must be scaled by 256 for D24 storage");
Require(HostDepthBiasConstant(without, VK_FORMAT_D32_SFLOAT_S8_UINT, 2.0f) == 2.0f, "a D32 depth bias must not be scaled");
const auto refused = [&](const View& view) {
try {
lookup(without, view);
} catch (const std::runtime_error& error) {
return std::string_view(error.what()).find("a depth plane that the device stores in another depth format is not implemented") != std::string_view::npos;
}
return false;
};
Require(refused({d16s8, FormatR16Unorm, 256, 256, TileDepth64KB, Type2DArray, 1}), "two slices of a D16 surface stored as D24 must be refused, as the plane copy would read the wider image as 16-bit texels");
Require(refused({d16s8, FormatR16Uint, 256, 256, TileStandard64KB}), "an R16_UINT view of a D16 surface stored as D24 must be refused");
ClearDepthSurfaces(without.device);

static int onlyTag = 0;
Expand Down
Loading
Loading