preserve DB_DEPTH_SIZE_XY and add tiled readback
This commit is contained in:
parent
42d42e3258
commit
f136c46519
|
|
@ -4138,7 +4138,7 @@ void GraphicsInitJmpTablesCxIndirect() {
|
|||
HW::DepthDepthSizeXY r;
|
||||
r.x_max = KYTY_PM4_GET(value, DB_DEPTH_SIZE_XY, X_MAX);
|
||||
r.y_max = KYTY_PM4_GET(value, DB_DEPTH_SIZE_XY, Y_MAX);
|
||||
r.valid = (r.x_max != 0 || r.y_max != 0);
|
||||
r.valid = true;
|
||||
cp->GetCtx()->SetDepthDepthSizeXY(r);
|
||||
};
|
||||
g_hw_ctx_indirect_func[Pm4::DB_DEPTH_SIZE] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
|
||||
|
|
|
|||
|
|
@ -1793,6 +1793,32 @@ static void TileConvertTiledToLinearStandard64KB64Elements(
|
|||
}
|
||||
}
|
||||
|
||||
static void TileConvertLinearToTiledStandard64KB64Elements(
|
||||
void* dst, const void* src, uint32_t width_elements, uint32_t height_elements,
|
||||
uint32_t pitch_elements, uint64_t size, uint64_t dst_size, uint32_t dst_x, uint32_t dst_y) {
|
||||
if (width_elements > pitch_elements) {
|
||||
EXIT("invalid linear-to-Standard64KB64 tail conversion, extent=%ux%u pitch=%u "
|
||||
"size=0x%016" PRIx64 " dst_size=0x%016" PRIx64 " dst=%u,%u\n",
|
||||
width_elements, height_elements, pitch_elements, size, dst_size, dst_x, dst_y);
|
||||
}
|
||||
auto* dst64 = static_cast<uint64_t*>(dst);
|
||||
const auto* src64 = static_cast<const uint64_t*>(src);
|
||||
const auto& tables = GetStandard64KB64Tables();
|
||||
const auto size_words = size >> 3u;
|
||||
const auto dst_size_words = dst_size >> 3u;
|
||||
for (uint32_t y = 0; y < height_elements; y++) {
|
||||
const uint64_t src_row = static_cast<uint64_t>(y) * pitch_elements;
|
||||
const uint64_t dst_row = tables.y_words[dst_y + y];
|
||||
for (uint32_t x = 0; x < width_elements; x++) {
|
||||
const uint64_t src_index = src_row + x;
|
||||
const uint64_t dst_index = dst_row + tables.x_words[dst_x + x];
|
||||
if (src_index < size_words && dst_index < dst_size_words) {
|
||||
dst64[dst_index] = src64[src_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TileConvertTiledToLinearStandard64KB128Elements(
|
||||
void* dst, const void* src, uint32_t width_elements, uint32_t height_elements,
|
||||
uint32_t pitch_elements, uint64_t size, uint64_t src_size, uint32_t src_x, uint32_t src_y) {
|
||||
|
|
@ -2474,8 +2500,20 @@ void TileConvertTiledToLinearRenderTarget(void* dst, const void* src, uint32_t w
|
|||
|
||||
void TileConvertLinearToTiledRenderTarget(void* dst, const void* src, uint32_t width,
|
||||
uint32_t height, uint32_t pitch,
|
||||
uint32_t bytes_per_element, uint64_t size) {
|
||||
uint32_t bytes_per_element, uint64_t size,
|
||||
uint64_t dst_size, uint32_t dst_x, uint32_t dst_y) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
const bool tail_block = dst_size != 0 && (dst_x != 0 || dst_y != 0 || size < dst_size);
|
||||
if (tail_block) {
|
||||
//Not sure about this at all
|
||||
if (bytes_per_element != 8) {
|
||||
EXIT("unsupported linear-to-tiled render-target tail element size: %u\n",
|
||||
bytes_per_element);
|
||||
}
|
||||
TileConvertLinearToTiledStandard64KB64Elements(dst, src, width, height, pitch, size,
|
||||
dst_size, dst_x, dst_y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dst == nullptr || src == nullptr || width == 0 || height == 0 || pitch == 0 ||
|
||||
width > pitch || bytes_per_element == 0 || size == 0 || size % bytes_per_element != 0) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,9 @@ void TileConvertTiledToLinearRenderTarget(void* dst, const void* src, uint32_t w
|
|||
uint32_t src_y = 0);
|
||||
void TileConvertLinearToTiledRenderTarget(void* dst, const void* src, uint32_t width,
|
||||
uint32_t height, uint32_t pitch,
|
||||
uint32_t bytes_per_element, uint64_t size);
|
||||
uint32_t bytes_per_element, uint64_t size,
|
||||
uint64_t dst_size = 0, uint32_t dst_x = 0,
|
||||
uint32_t dst_y = 0);
|
||||
void TileConvertTiledToLinearStandard64KB(void* dst, const void* src, uint32_t format,
|
||||
uint32_t width, uint32_t height, uint32_t pitch,
|
||||
uint64_t size, uint64_t src_size = 0, uint32_t src_x = 0,
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ struct TextureVulkanImage: public GpuTextureVulkanImage {
|
|||
};
|
||||
|
||||
struct StorageTextureVulkanImage: public GpuTextureVulkanImage {
|
||||
struct StorageView {
|
||||
uint32_t base_level = 0;
|
||||
VkImageView view = nullptr;
|
||||
};
|
||||
struct SampledView {
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
uint32_t swizzle = 0;
|
||||
|
|
@ -141,6 +145,8 @@ struct StorageTextureVulkanImage: public GpuTextureVulkanImage {
|
|||
StorageTextureVulkanImage(): GpuTextureVulkanImage(VulkanImageType::StorageTexture) {}
|
||||
std::mutex sampled_view_mutex;
|
||||
std::vector<SampledView> sampled_views;
|
||||
std::mutex storage_view_mutex;
|
||||
std::vector<StorageView> storage_views;
|
||||
};
|
||||
|
||||
struct RenderTextureVulkanImage: public VulkanImage {
|
||||
|
|
|
|||
|
|
@ -126,7 +126,10 @@ void ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer* buffer, const H
|
|||
z.htile_surface.prefetch_height == 0 && z.htile_surface.dst_outside_zero_to_one == 0 &&
|
||||
z.z_read_base_addr == 0 && z.z_write_base_addr == 0 && z.stencil_read_base_addr == 0 &&
|
||||
z.stencil_write_base_addr == 0 && z.htile_data_base_addr == 0 &&
|
||||
!z.z_info.tile_surface_enable && !z.size.valid && !z.width_height_valid &&
|
||||
// DB_DEPTH_SIZE_XY is independent state and may remain programmed after the attachment
|
||||
// formats and addresses are unbound. A zero encoding is the valid 1x1 value, so its
|
||||
// presence alone must not manufacture a depth attachment.
|
||||
!z.z_info.tile_surface_enable && !z.width_height_valid &&
|
||||
!z.pitch_height_valid && z.size.x_max == 0 && z.size.y_max == 0 &&
|
||||
z.pitch_div8_minus1 == 0 && z.height_div8_minus1 == 0 && z.slice_div64_minus1 == 0 &&
|
||||
z.width == 0 && z.height == 0;
|
||||
|
|
@ -215,7 +218,7 @@ void ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer* buffer, const H
|
|||
} else if (z.htile_data_base_addr != 0) {
|
||||
DepthFatal("HTile address without an enabled tile surface");
|
||||
}
|
||||
const bool size_xy_valid = z.size.valid && (z.size.x_max != 0 || z.size.y_max != 0);
|
||||
const bool size_xy_valid = z.size.valid;
|
||||
const bool wh_valid = z.width_height_valid && z.width != 0 && z.height != 0;
|
||||
if (!size_xy_valid && !wh_valid) {
|
||||
DepthFatal("missing depth extent");
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "common/assert.h"
|
||||
#include "graphics/guest_gpu/gpu_defs.h"
|
||||
#include "graphics/guest_gpu/gpu_format.h"
|
||||
#include "graphics/guest_gpu/tile.h"
|
||||
#include "graphics/host_gpu/graphicContext.h"
|
||||
#include "graphics/host_gpu/objects/textureCommon.h"
|
||||
|
|
@ -170,6 +171,38 @@ void Tiler::TileImage(void* dst, const void* src, const RenderTargetInfo& info)
|
|||
}
|
||||
}
|
||||
|
||||
void Tiler::TileImage(void* dst, const void* src, const ImageInfo& info) const {
|
||||
const bool image_2d = info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
|
||||
info.depth == 1;
|
||||
const auto bytes_per_element = Prospero::RenderTargetBytesPerElement(info.format);
|
||||
if (!image_2d || info.levels == 0 || info.levels > 16 ||
|
||||
info.tile != Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) ||
|
||||
bytes_per_element == 0) {
|
||||
EXIT("Tiler: unsupported storage-texture tile, addr=0x%016" PRIx64
|
||||
"+0x%016" PRIx64 " extent=%ux%ux%u levels=%u tile=%u format=%u\n",
|
||||
info.address, info.size, info.width, info.height, info.depth, info.levels, info.tile,
|
||||
info.format);
|
||||
}
|
||||
auto layout = TextureCalcUploadLayout(info.format, info.width, info.height, info.levels,
|
||||
info.depth, info.pitch, info.tile, info.size, true, false,
|
||||
false, "StorageTextureReadback");
|
||||
auto regions = TextureBuildUploadRegions(
|
||||
layout, Prospero::SurfaceFormat(info.format), info.width, info.height, info.depth,
|
||||
info.levels, false, false, TextureUploadDestination::MipLevels,
|
||||
TextureUploadSliceLayout::MipChainPerSlice);
|
||||
std::memset(dst, 0, info.size);
|
||||
for (uint32_t level = 0; level < info.levels; level++) {
|
||||
const auto& level_size = layout.level_sizes[level];
|
||||
const auto guest_offset = level_size.src_size != 0 ? level_size.src_offset
|
||||
: level_size.offset;
|
||||
auto* guest = static_cast<uint8_t*>(dst) + guest_offset;
|
||||
const auto* linear = static_cast<const uint8_t*>(src) + regions[level].offset;
|
||||
TileConvertLinearToTiledRenderTarget(
|
||||
guest, linear, regions[level].width, regions[level].height, regions[level].pitch,
|
||||
bytes_per_element, level_size.size, level_size.src_size, level_size.x, level_size.y);
|
||||
}
|
||||
}
|
||||
|
||||
void Tiler::TileImage(void* dst, const void* src, const DepthTargetInfo& info) const {
|
||||
if (info.stencil_address != 0 || info.stencil_size != 0 ||
|
||||
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) ||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public:
|
|||
const DepthTargetInfo& info, const BufferImageCopySource& source,
|
||||
bool refresh, uint32_t base_layer = 0) const;
|
||||
void TileImage(void* dst, const void* src, const RenderTargetInfo& info) const;
|
||||
void TileImage(void* dst, const void* src, const ImageInfo& info) const;
|
||||
void TileImage(void* dst, const void* src, const DepthTargetInfo& info) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue