mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
refactor(graphics)
This commit is contained in:
@@ -693,11 +693,12 @@ Image::Image(GraphicContext& graphics, CommandScheduler& scheduler, const ImageI
|
||||
}
|
||||
|
||||
uint64_t Image::HashGuestEdges() const {
|
||||
constexpr uint64_t page_mask = TRACKER_PAGE_SIZE - 1;
|
||||
std::array<uint8_t, TRACKER_PAGE_SIZE * 2> bytes {};
|
||||
const auto range = info.data;
|
||||
const uint64_t head_end = std::min(range.End(), (range.address + page_mask) & ~page_mask);
|
||||
const uint64_t tail_begin = std::max(range.address, range.End() & ~page_mask);
|
||||
const uint64_t head_end =
|
||||
std::min(range.End(), Common::AlignUp(range.address, TRACKER_PAGE_SIZE));
|
||||
const uint64_t tail_begin =
|
||||
std::max(range.address, Common::AlignDown(range.End(), TRACKER_PAGE_SIZE));
|
||||
const uint64_t head_size = head_end - range.address;
|
||||
const uint64_t tail_address = tail_begin < head_end ? head_end : tail_begin;
|
||||
const uint64_t tail_size = range.End() - tail_address;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_IMAGE_H_
|
||||
#define EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_IMAGE_H_
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/slotVector.h"
|
||||
#include "graphics/host_gpu/graphicContext.h"
|
||||
@@ -133,7 +134,7 @@ public:
|
||||
}
|
||||
[[nodiscard]] bool IsTracked() const noexcept { return track_addr != 0 && track_addr_end != 0; }
|
||||
[[nodiscard]] uint64_t AccountedSize() const noexcept {
|
||||
return backing.image == nullptr ? 0 : (info.data.size + 1023) & ~uint64_t {1023};
|
||||
return backing.image == nullptr ? 0 : Common::AlignUp(info.data.size, 1024);
|
||||
}
|
||||
[[nodiscard]] uint64_t HashGuestEdges() const;
|
||||
|
||||
|
||||
@@ -82,9 +82,6 @@ struct ImageInfo {
|
||||
[[nodiscard]] constexpr bool IsVolume() const noexcept {
|
||||
return type == Prospero::ImageType::kColor3D;
|
||||
}
|
||||
[[nodiscard]] constexpr bool IsLayered() const noexcept {
|
||||
return !IsVolume() && resources.layers > 1;
|
||||
}
|
||||
[[nodiscard]] constexpr uint32_t TransferLayers() const noexcept {
|
||||
return IsVolume() ? extent.depth : resources.layers;
|
||||
}
|
||||
@@ -342,14 +339,6 @@ ClassifyVideoOutCompression(bool compressed, uint64_t metadata_address, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr bool
|
||||
CanUseVideoOutNativeWithoutUpload(VideoOutCompression compression, bool render_target,
|
||||
bool gpu_modified, bool guest_modified) noexcept {
|
||||
return compression != VideoOutCompression::Uncompressed &&
|
||||
compression != VideoOutCompression::Unsupported && !guest_modified &&
|
||||
(render_target || gpu_modified);
|
||||
}
|
||||
|
||||
struct VideoOutPixelFormatInfo {
|
||||
vk::Format format = vk::Format::eUndefined;
|
||||
Prospero::BufferFormat guest_format = Prospero::BufferFormat::kInvalid;
|
||||
@@ -400,32 +389,6 @@ inline constexpr std::array<VideoOutFormatPolicy, 6> VIDEO_OUT_FORMAT_POLICIES {
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr bool
|
||||
IsSupportedDisplayRenderTargetTileMode(Prospero::TileMode tile_mode) noexcept {
|
||||
return tile_mode == Prospero::TileMode::kRenderTarget;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr bool IsSupportedStandard64RenderTarget(const ImageInfo& info) {
|
||||
if (info.tile_mode != Prospero::TileMode::kStandard64KB || info.data.address == 0 ||
|
||||
(info.data.address & 0xffffu) != 0 || info.extent.width == 0 || info.extent.height == 0 ||
|
||||
info.bytes_per_block != 4 || info.resources.levels != 1 || info.resources.layers != 1 ||
|
||||
info.samples != 1) {
|
||||
return false;
|
||||
}
|
||||
const auto expected_pitch =
|
||||
(static_cast<uint64_t>(info.extent.width) + 127u) & ~uint64_t {127u};
|
||||
const auto padded_height =
|
||||
(static_cast<uint64_t>(info.extent.height) + 127u) & ~uint64_t {127u};
|
||||
return expected_pitch <= UINT32_MAX && info.pitch == expected_pitch &&
|
||||
expected_pitch <= UINT64_MAX / padded_height / info.bytes_per_block &&
|
||||
info.data.size == expected_pitch * padded_height * info.bytes_per_block;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr bool IsTiledRenderTarget(const ImageInfo& info) noexcept {
|
||||
return info.tile_mode == Prospero::TileMode::kRenderTarget ||
|
||||
IsSupportedStandard64RenderTarget(info);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool DecodePackedColorClear(vk::Format format, uint32_t packed,
|
||||
vk::ClearColorValue& clear) {
|
||||
vk::ClearColorValue next {};
|
||||
|
||||
@@ -322,6 +322,12 @@ vk::ImageView Image::FindView(const ImageViewInfo& view_info) {
|
||||
normalized.aspect = vk::ImageAspectFlagBits::eStencil;
|
||||
}
|
||||
normalized.usage = is_storage ? vk::ImageUsageFlagBits::eStorage : vk::ImageUsageFlags {};
|
||||
for (const auto& cached: views) {
|
||||
if (cached.info == normalized) {
|
||||
return cached.view;
|
||||
}
|
||||
}
|
||||
|
||||
const bool format_compatible = normalized.format != vk::Format::eUndefined &&
|
||||
ImageViewOps::FormatsCompatible(image.format, normalized.format);
|
||||
const bool slice_view =
|
||||
@@ -351,12 +357,6 @@ vk::ImageView Image::FindView(const ImageViewInfo& view_info) {
|
||||
image.layers);
|
||||
}
|
||||
|
||||
for (const auto& cached: views) {
|
||||
if (cached.info == normalized) {
|
||||
return cached.view;
|
||||
}
|
||||
}
|
||||
|
||||
vk::ImageViewUsageCreateInfo usage {};
|
||||
usage.usage = image.usage;
|
||||
if (!is_storage) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "graphics/host_gpu/renderer/image/textureCommon.h"
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "graphics/guest_gpu/gpu_defs.h"
|
||||
#include "graphics/guest_gpu/gpu_format.h"
|
||||
@@ -260,12 +261,10 @@ std::vector<vk::BufferImageCopy> TextureBuildImageCopies(const TextureUploadLayo
|
||||
region.bufferRowLength = layout.mips[mip_level].row_length;
|
||||
region.bufferImageHeight = layout.mips[mip_level].image_height;
|
||||
} else {
|
||||
const auto texel_width = layout.surface.texture.texel_width;
|
||||
const auto align_to_texel = [texel_width](uint32_t dimension) {
|
||||
return ((dimension + texel_width - 1u) / texel_width) * texel_width;
|
||||
};
|
||||
const auto aligned_pitch = align_to_texel(mip_pitch);
|
||||
region.bufferRowLength = aligned_pitch > align_to_texel(mip_width) ? aligned_pitch : 0;
|
||||
const auto texel_width = layout.surface.texture.texel_width;
|
||||
const auto aligned_pitch = Common::AlignUp(mip_pitch, texel_width);
|
||||
region.bufferRowLength =
|
||||
aligned_pitch > Common::AlignUp(mip_width, texel_width) ? aligned_pitch : 0;
|
||||
}
|
||||
for (uint32_t slice_index = 0; slice_index < mip_depth; ++slice_index) {
|
||||
region.bufferOffset = layout.mips[mip_level].offset + slice_index * layout.slice_stride;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "graphics/host_gpu/renderer/image/tiler.h"
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "gpu_tiler_shaders/gpu_tiler_demote_d16_spv.h"
|
||||
#include "gpu_tiler_shaders/gpu_tiler_depth_spv.h"
|
||||
@@ -221,7 +222,7 @@ void TileManager::Prepare(bool tile, uint64_t tiled_capacity, uint64_t linear_ca
|
||||
|
||||
const uint64_t uniform_alignment =
|
||||
std::max<uint64_t>(limits.minUniformBufferOffsetAlignment, 1);
|
||||
const uint64_t stride = (sizeof(Push) + uniform_alignment - 1) & ~(uniform_alignment - 1);
|
||||
const uint64_t stride = Common::AlignUp<uint64_t>(sizeof(Push), uniform_alignment);
|
||||
EXIT_NOT_IMPLEMENTED(dispatches.size() > UINT64_MAX / stride);
|
||||
const uint64_t bytes = dispatches.size() * stride;
|
||||
auto [mapped, offset] = m_stream_buffer.Map(bytes, uniform_alignment);
|
||||
@@ -287,12 +288,12 @@ void TileManager::Record(vk::Buffer source, uint64_t source_offset,
|
||||
const auto& limits = m_graphics.GetPhysicalDeviceProperties().limits;
|
||||
const uint64_t descriptor_alignment =
|
||||
std::max<uint64_t>(limits.minStorageBufferOffsetAlignment, 4);
|
||||
const uint64_t source_descriptor_offset = source_offset & ~(descriptor_alignment - 1);
|
||||
const uint64_t target_descriptor_offset = target_offset & ~(descriptor_alignment - 1);
|
||||
const uint64_t source_descriptor_offset = Common::AlignDown(source_offset, descriptor_alignment);
|
||||
const uint64_t target_descriptor_offset = Common::AlignDown(target_offset, descriptor_alignment);
|
||||
const uint64_t source_base = source_offset - source_descriptor_offset;
|
||||
const uint64_t target_base = target_offset - target_descriptor_offset;
|
||||
const uint64_t source_range = (source_base + source_capacity + 3u) & ~uint64_t {3};
|
||||
const uint64_t target_range = (target_base + target_capacity + 3u) & ~uint64_t {3};
|
||||
const uint64_t source_range = Common::AlignUp(source_base + source_capacity, 4);
|
||||
const uint64_t target_range = Common::AlignUp(target_base + target_capacity, 4);
|
||||
EXIT_NOT_IMPLEMENTED(source_range > limits.maxStorageBufferRange ||
|
||||
target_range > limits.maxStorageBufferRange || target_offset % 4 != 0 ||
|
||||
target_capacity % 4 != 0);
|
||||
@@ -372,7 +373,7 @@ TileManager::Result TileManager::Detile(vk::Buffer tiled, uint64_t tiled_offset,
|
||||
const uint64_t source_base = tiled_offset & (descriptor_alignment - 1);
|
||||
std::vector<Dispatch> dispatches;
|
||||
Prepare(false, tiled_capacity, linear_capacity, infos, source_base, 0, dispatches);
|
||||
auto scratch = AllocateScratch((linear_capacity + 3u) & ~uint64_t {3});
|
||||
auto scratch = AllocateScratch(Common::AlignUp(linear_capacity, 4));
|
||||
DeferDestroy(scratch);
|
||||
Record(tiled, tiled_offset, tiled_capacity, scratch.buffer, 0, scratch.size, dispatches,
|
||||
true);
|
||||
@@ -406,7 +407,7 @@ void TileManager::TileImage(Image& image, std::span<const vk::BufferImageCopy> r
|
||||
// Reserve all stream parameters before creating a scheduler-lived scratch dependency:
|
||||
// StreamBuffer::Map is allowed to submit the current tick when it wraps.
|
||||
Prepare(true, tiled_capacity, linear_capacity, infos, 0, target_base, dispatches);
|
||||
auto linear = AllocateScratch((linear_capacity + 3u) & ~uint64_t {3});
|
||||
auto linear = AllocateScratch(Common::AlignUp(linear_capacity, 4));
|
||||
DeferDestroy(linear);
|
||||
image.Download(regions, linear.buffer, 0, linear.size);
|
||||
Result source {linear.buffer, 0, linear.size};
|
||||
@@ -418,7 +419,7 @@ void TileManager::TileImage(Image& image, std::span<const vk::BufferImageCopy> r
|
||||
}
|
||||
|
||||
TileManager::Result TileManager::GetScratchBuffer(uint64_t size) {
|
||||
auto scratch = AllocateScratch((size + 3u) & ~uint64_t {3});
|
||||
auto scratch = AllocateScratch(Common::AlignUp(size, 4));
|
||||
DeferDestroy(scratch);
|
||||
return {scratch.buffer, 0, scratch.size};
|
||||
}
|
||||
@@ -426,11 +427,11 @@ TileManager::Result TileManager::GetScratchBuffer(uint64_t size) {
|
||||
TileManager::StorageBinding TileManager::BindStorage(Result buffer, uint64_t size) const {
|
||||
const auto& limits = m_graphics.GetPhysicalDeviceProperties().limits;
|
||||
const auto alignment = std::max<uint64_t>(limits.minStorageBufferOffsetAlignment, 4);
|
||||
const auto descriptor_offset = buffer.offset - buffer.offset % alignment;
|
||||
const auto descriptor_offset = Common::AlignDown(buffer.offset, alignment);
|
||||
const auto base = buffer.offset - descriptor_offset;
|
||||
EXIT_IF(buffer.buffer == nullptr || size == 0 || buffer.size < size || base > UINT32_MAX ||
|
||||
size > UINT64_MAX - base || base + size > UINT64_MAX - 3);
|
||||
const auto range = (base + size + 3) & ~uint64_t {3};
|
||||
const auto range = Common::AlignUp(base + size, 4);
|
||||
EXIT_IF(range > limits.maxStorageBufferRange || range > UINT32_MAX);
|
||||
return {{buffer.buffer, descriptor_offset, range}, static_cast<uint32_t>(base)};
|
||||
}
|
||||
@@ -512,8 +513,8 @@ void TileManager::ConvertD16(Result source, Result target, D16Direction directio
|
||||
const auto target_required = required(layout.height, layout.layers, layout.target_row_stride,
|
||||
layout.target_slice_stride, target_active);
|
||||
EXIT_IF(source_required > UINT64_MAX - 3 || target_required > UINT64_MAX - 3);
|
||||
const auto source_barrier_size = (source_required + 3) & ~uint64_t {3};
|
||||
const auto target_barrier_size = (target_required + 3) & ~uint64_t {3};
|
||||
const auto source_barrier_size = Common::AlignUp(source_required, 4);
|
||||
const auto target_barrier_size = Common::AlignUp(target_required, 4);
|
||||
EXIT_IF(source.size < source_barrier_size || target.size < target_barrier_size);
|
||||
|
||||
m_scheduler.EndRendering();
|
||||
|
||||
Reference in New Issue
Block a user