mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
graphics: support PS5 1D color render targets
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#include "graphics/host_gpu/vulkanCommon.h"
|
#include "graphics/host_gpu/vulkanCommon.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
namespace Libs::Graphics {
|
namespace Libs::Graphics {
|
||||||
@@ -143,12 +144,23 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
|
|||||||
uint32_t pitch = 0;
|
uint32_t pitch = 0;
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
bool tile = false;
|
bool tile = false;
|
||||||
const bool volume = rt.attrib3.dimension == 2;
|
static constexpr std::array image_types {Prospero::ImageType::kColor1D,
|
||||||
if (rt.attrib3.dimension != 1 && !volume) {
|
Prospero::ImageType::kColor2D,
|
||||||
|
Prospero::ImageType::kColor3D};
|
||||||
|
if (rt.attrib3.dimension >= image_types.size()) {
|
||||||
EXIT("unsupported render-target dimension: %u\n", rt.attrib3.dimension);
|
EXIT("unsupported render-target dimension: %u\n", rt.attrib3.dimension);
|
||||||
}
|
}
|
||||||
|
const auto image_type = image_types[rt.attrib3.dimension];
|
||||||
|
const bool is_1d = image_type == Prospero::ImageType::kColor1D;
|
||||||
|
const bool volume = image_type == Prospero::ImageType::kColor3D;
|
||||||
|
if (is_1d && rt.attrib2.height != 0) {
|
||||||
|
EXIT("1D render target has nonzero height: %u\n", rt.attrib2.height);
|
||||||
|
}
|
||||||
if (!volume && rt.attrib3.depth != 0) {
|
if (!volume && rt.attrib3.depth != 0) {
|
||||||
EXIT("2D render target has nonzero depth: %u\n", rt.attrib3.depth);
|
EXIT("non-3D render target has nonzero depth: %u\n", rt.attrib3.depth);
|
||||||
|
}
|
||||||
|
if (is_1d && samples != 1) {
|
||||||
|
EXIT("multisampled 1D render targets are unsupported\n");
|
||||||
}
|
}
|
||||||
if (volume && samples != 1) {
|
if (volume && samples != 1) {
|
||||||
EXIT("multisampled 3D render targets are unsupported\n");
|
EXIT("multisampled 3D render targets are unsupported\n");
|
||||||
@@ -325,7 +337,7 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
|
|||||||
desc.info.data = {rt.base.addr, backing_size};
|
desc.info.data = {rt.base.addr, backing_size};
|
||||||
desc.info.pixel_format = target_format.format;
|
desc.info.pixel_format = target_format.format;
|
||||||
desc.info.guest_format = transfer_format;
|
desc.info.guest_format = transfer_format;
|
||||||
desc.info.type = volume ? Prospero::ImageType::kColor3D : Prospero::ImageType::kColor2D;
|
desc.info.type = image_type;
|
||||||
desc.info.extent = {width, height, depth};
|
desc.info.extent = {width, height, depth};
|
||||||
desc.info.resources = {levels, volume ? 1u : view.image_layers};
|
desc.info.resources = {levels, volume ? 1u : view.image_layers};
|
||||||
desc.info.pitch = pitch;
|
desc.info.pitch = pitch;
|
||||||
@@ -364,8 +376,13 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
desc.view_info.format = target_format.format;
|
desc.view_info.format = target_format.format;
|
||||||
desc.view_info.type =
|
if (is_1d) {
|
||||||
view.layer_count == 1 ? vk::ImageViewType::e2D : vk::ImageViewType::e2DArray;
|
desc.view_info.type =
|
||||||
|
view.layer_count == 1 ? vk::ImageViewType::e1D : vk::ImageViewType::e1DArray;
|
||||||
|
} else {
|
||||||
|
desc.view_info.type =
|
||||||
|
view.layer_count == 1 ? vk::ImageViewType::e2D : vk::ImageViewType::e2DArray;
|
||||||
|
}
|
||||||
desc.view_info.aspect = vk::ImageAspectFlagBits::eColor;
|
desc.view_info.aspect = vk::ImageAspectFlagBits::eColor;
|
||||||
desc.view_info.base_level = rt.view.current_mip_level;
|
desc.view_info.base_level = rt.view.current_mip_level;
|
||||||
desc.view_info.level_count = 1;
|
desc.view_info.level_count = 1;
|
||||||
|
|||||||
@@ -6997,6 +6997,106 @@ public:
|
|||||||
std::printf("[gpu] %-32s ok\n", name);
|
std::printf("[gpu] %-32s ok\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckRenderExecutorColor1DDiscovery() {
|
||||||
|
constexpr const char *name = "RenderExecutorColor1DDiscovery";
|
||||||
|
constexpr uintptr_t base = 0x0000000203c00000ull;
|
||||||
|
constexpr uint32_t width = 512;
|
||||||
|
constexpr uint32_t height = 1;
|
||||||
|
constexpr uint32_t bytes_per_element = 4;
|
||||||
|
constexpr uint64_t allocation_alignment = 0x10000;
|
||||||
|
EnsureRuntimeContext();
|
||||||
|
|
||||||
|
const auto pitch =
|
||||||
|
TileGetRenderTargetPitch(width, bytes_per_element, 0);
|
||||||
|
TileSizeAlign layout{};
|
||||||
|
Require(name, "tile layout",
|
||||||
|
pitch != 0 && TileGetRenderTargetSize(
|
||||||
|
width, height, pitch, bytes_per_element, layout, 0),
|
||||||
|
"1D render-target layout is unavailable");
|
||||||
|
const auto allocation_size =
|
||||||
|
std::max<uint64_t>(layout.size, allocation_alignment);
|
||||||
|
|
||||||
|
int64_t direct_offset = -1;
|
||||||
|
Require(name, "direct allocation",
|
||||||
|
Libs::LibKernel::Memory::KernelAllocateDirectMemory(
|
||||||
|
0, Libs::LibKernel::Memory::KernelGetDirectMemorySize(),
|
||||||
|
allocation_size, allocation_alignment, 0, &direct_offset) == 0,
|
||||||
|
"1D color direct-memory allocation failed");
|
||||||
|
void *mapped = reinterpret_cast<void *>(base);
|
||||||
|
Require(name, "direct mapping",
|
||||||
|
Libs::LibKernel::Memory::KernelMapDirectMemory(
|
||||||
|
&mapped, allocation_size, 0x3, 0x10, direct_offset,
|
||||||
|
allocation_alignment) == 0 &&
|
||||||
|
mapped == reinterpret_cast<void *>(base),
|
||||||
|
"1D color fixed mapping failed");
|
||||||
|
std::memset(mapped, 0, allocation_size);
|
||||||
|
|
||||||
|
{
|
||||||
|
RenderContext context(m_runtime_context);
|
||||||
|
auto &scheduler = context.GetCommandScheduler();
|
||||||
|
HW::Context registers{};
|
||||||
|
HW::UserConfig user_config{};
|
||||||
|
HW::Shader shaders{};
|
||||||
|
registers.SetColorBase(0, {.addr = base});
|
||||||
|
registers.SetColorInfo(
|
||||||
|
0, {.format = Prospero::ChannelLayout::k8_8_8_8,
|
||||||
|
.channel_type = Prospero::ChannelType::kSrgb,
|
||||||
|
.channel_order = Prospero::ChannelOrder::kStandard});
|
||||||
|
registers.SetColorAttrib2(0, {.height = height - 1, .width = width - 1});
|
||||||
|
registers.SetColorAttrib3(0,
|
||||||
|
{.tile_mode = Prospero::TileMode::kRenderTarget,
|
||||||
|
.dimension = 0,
|
||||||
|
.cmask_pipe_aligned = true,
|
||||||
|
.dcc_pipe_aligned = true});
|
||||||
|
registers.SetRenderTargetMask(0x0f);
|
||||||
|
scheduler.Begin(registers, user_config, shaders);
|
||||||
|
|
||||||
|
auto &resources = context.GetGpuResources();
|
||||||
|
auto &texture_cache = resources.GetTextureCache();
|
||||||
|
auto &executor = context.GetRenderExecutor();
|
||||||
|
resources.MapMemory(base, allocation_size);
|
||||||
|
|
||||||
|
RenderColorInfo color{};
|
||||||
|
RenderExecutorTestAccess::ResolveRenderColorTarget(
|
||||||
|
executor, 1, scheduler.Current(), color, 0);
|
||||||
|
const auto attachment =
|
||||||
|
texture_cache.FindRenderTarget(color.image_id, color.desc);
|
||||||
|
const auto &image = texture_cache.GetImage(color.image_id);
|
||||||
|
RenderDepthInfo no_depth{};
|
||||||
|
const auto rendering = RenderExecutorTestAccess::AcquireRenderTargets(
|
||||||
|
executor, scheduler.Current(), &color, 1, no_depth);
|
||||||
|
scheduler.Current().BeginRendering(rendering);
|
||||||
|
scheduler.Current().EndRendering();
|
||||||
|
Require(name, "captured 1D target",
|
||||||
|
color.image_id && attachment != nullptr &&
|
||||||
|
color.image_view != nullptr &&
|
||||||
|
color.desc.info.type == Prospero::ImageType::kColor1D &&
|
||||||
|
color.desc.info.extent == vk::Extent3D{width, height, 1} &&
|
||||||
|
color.desc.info.resources == ImageSubresources{1, 1} &&
|
||||||
|
color.desc.info.pitch == pitch &&
|
||||||
|
color.desc.info.data.size == layout.size &&
|
||||||
|
color.desc.view_info.type == vk::ImageViewType::e1D &&
|
||||||
|
image.backing.image_type == vk::ImageType::e1D &&
|
||||||
|
rendering.width == width && rendering.height == height &&
|
||||||
|
rendering.num_layers == 1 &&
|
||||||
|
rendering.num_color_attachments == 1,
|
||||||
|
"SDK dimension=0 did not create a 512x1 Vulkan attachment");
|
||||||
|
|
||||||
|
RenderExecutorTestAccess::ResetBindings(executor);
|
||||||
|
resources.UnmapMemory(base, allocation_size);
|
||||||
|
scheduler.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
Require(name, "unmap direct backing",
|
||||||
|
Libs::LibKernel::Memory::KernelMunmap(base, allocation_size) == 0,
|
||||||
|
"1D color direct mapping release failed");
|
||||||
|
Require(name, "release direct backing",
|
||||||
|
Libs::LibKernel::Memory::KernelReleaseDirectMemory(
|
||||||
|
direct_offset, allocation_size) == 0,
|
||||||
|
"1D color direct-memory allocation release failed");
|
||||||
|
std::printf("[gpu] %-32s ok\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
void CheckRenderExecutorColorVolumeDiscovery() {
|
void CheckRenderExecutorColorVolumeDiscovery() {
|
||||||
constexpr const char *name = "RenderExecutorColorVolumeDiscovery";
|
constexpr const char *name = "RenderExecutorColorVolumeDiscovery";
|
||||||
constexpr uintptr_t base = 0x0000000203e00000ull;
|
constexpr uintptr_t base = 0x0000000203e00000ull;
|
||||||
@@ -24237,6 +24337,7 @@ int main(int argc, char **argv) {
|
|||||||
CheckDepthAttachmentWrites();
|
CheckDepthAttachmentWrites();
|
||||||
CheckDynamicRenderingState();
|
CheckDynamicRenderingState();
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
|
vulkan.CheckRenderExecutorColor1DDiscovery();
|
||||||
vulkan.CheckRenderExecutorColorVolumeDiscovery();
|
vulkan.CheckRenderExecutorColorVolumeDiscovery();
|
||||||
vulkan.CheckRenderExecutorColorDepthTileDiscovery();
|
vulkan.CheckRenderExecutorColorDepthTileDiscovery();
|
||||||
vulkan.CheckRenderExecutorStencilBindingDiscovery();
|
vulkan.CheckRenderExecutorStencilBindingDiscovery();
|
||||||
@@ -24411,6 +24512,7 @@ int main(int argc, char **argv) {
|
|||||||
vulkan.CheckStreamBufferRing();
|
vulkan.CheckStreamBufferRing();
|
||||||
vulkan.CheckGpuTilerCpuParity();
|
vulkan.CheckGpuTilerCpuParity();
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
|
vulkan.CheckRenderExecutorColor1DDiscovery();
|
||||||
vulkan.CheckRenderExecutorColorVolumeDiscovery();
|
vulkan.CheckRenderExecutorColorVolumeDiscovery();
|
||||||
vulkan.CheckRenderExecutorColorStandard4TileDiscovery();
|
vulkan.CheckRenderExecutorColorStandard4TileDiscovery();
|
||||||
vulkan.CheckRenderExecutorColorDepthTileDiscovery();
|
vulkan.CheckRenderExecutorColorDepthTileDiscovery();
|
||||||
|
|||||||
Reference in New Issue
Block a user