mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-20 19:44:46 +00:00
renderer_vulkan: initial CMask support
This commit is contained in:
parent
ac6a60d809
commit
2b5983844d
4 changed files with 81 additions and 3 deletions
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "video_core/amdgpu/pixel_format.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
|
||||
namespace Vulkan::LiverpoolToVK {
|
||||
|
@ -381,6 +382,13 @@ vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
|||
case vk::Format::eB8G8R8A8Srgb:
|
||||
return is_vo_surface ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
||||
}
|
||||
} else {
|
||||
if (is_vo_surface && base_format == vk::Format::eR8G8B8A8Srgb) {
|
||||
return vk::Format::eR8G8B8A8Unorm;
|
||||
}
|
||||
if (is_vo_surface && base_format == vk::Format::eB8G8R8A8Srgb) {
|
||||
return vk::Format::eB8G8R8A8Unorm;
|
||||
}
|
||||
}
|
||||
return base_format;
|
||||
}
|
||||
|
@ -422,4 +430,56 @@ void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
|
|||
}
|
||||
}
|
||||
|
||||
static constexpr float U8ToUnorm(u8 v) {
|
||||
static constexpr auto c = 1.0f / 255.0f;
|
||||
return float(v * c);
|
||||
}
|
||||
|
||||
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
|
||||
const auto comp_swap = color_buffer.info.comp_swap.Value();
|
||||
ASSERT_MSG(comp_swap == Liverpool::ColorBuffer::SwapMode::Standard ||
|
||||
comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate,
|
||||
"Unsupported component swap mode {}", static_cast<u32>(comp_swap));
|
||||
|
||||
const bool comp_swap_alt = comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate;
|
||||
|
||||
const auto& c0 = color_buffer.clear_word0;
|
||||
const auto& c1 = color_buffer.clear_word1;
|
||||
const auto num_bits = AmdGpu::NumBits(color_buffer.info.format);
|
||||
|
||||
vk::ClearColorValue color{};
|
||||
switch (color_buffer.info.number_type) {
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
[[fallthrough]];
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
[[fallthrough]];
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
[[fallthrough]];
|
||||
case AmdGpu::NumberFormat::Srgb: {
|
||||
switch (num_bits) {
|
||||
case 32: {
|
||||
color.float32 = std::array{
|
||||
U8ToUnorm((c0 >> (comp_swap_alt ? 16 : 0)) & 0xff),
|
||||
U8ToUnorm((c0 >> 8) & 0xff),
|
||||
U8ToUnorm((c0 >> (comp_swap_alt ? 0 : 16)) & 0xff),
|
||||
U8ToUnorm((c0 >> 24) & 0xff),
|
||||
};
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ERROR(Render_Vulkan, "Missing clear color conversion for bits {}", num_bits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ERROR(Render_Vulkan, "Missing clear color conversion for type {}",
|
||||
color_buffer.info.number_type.Value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {.color = color};
|
||||
}
|
||||
|
||||
} // namespace Vulkan::LiverpoolToVK
|
||||
|
|
|
@ -46,6 +46,10 @@ vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
|||
vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format,
|
||||
Liverpool::DepthBuffer::StencilFormat stencil_format);
|
||||
|
||||
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer);
|
||||
|
||||
vk::ClearValue DepthClearValue();
|
||||
|
||||
void EmitQuadToTriangleListIndices(u8* out_indices, u32 num_vertices);
|
||||
|
||||
} // namespace Vulkan::LiverpoolToVK
|
||||
|
|
|
@ -109,6 +109,15 @@ void ComputePipeline::BindResources(Core::MemoryManager* memory, StreamBuffer& s
|
|||
: vk::DescriptorType::eUniformBuffer,
|
||||
.pBufferInfo = &buffer_infos.back(),
|
||||
});
|
||||
|
||||
if (buffer.is_storage) {
|
||||
// In most of the cases we can skip the whole dispatch when meta is written
|
||||
texture_cache.TouchMeta(addr, true);
|
||||
} else {
|
||||
if (texture_cache.IsMeta(addr)) {
|
||||
LOG_WARNING(Render_Vulkan, "Unexpected meta data read by a CS shader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& image : info.images) {
|
||||
|
|
|
@ -44,8 +44,6 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
|||
|
||||
boost::container::static_vector<vk::RenderingAttachmentInfo, Liverpool::NumColorBuffers>
|
||||
color_attachments{};
|
||||
vk::RenderingAttachmentInfo depth_attachment{};
|
||||
u32 num_depth_attachments{};
|
||||
for (auto col_buf_id = 0u; col_buf_id < Liverpool::NumColorBuffers; ++col_buf_id) {
|
||||
const auto& col_buf = regs.color_buffers[col_buf_id];
|
||||
if (!col_buf) {
|
||||
|
@ -55,13 +53,20 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
|||
const auto& hint = liverpool->last_cb_extent[col_buf_id];
|
||||
const auto& image_view = texture_cache.RenderTarget(col_buf, hint);
|
||||
|
||||
const bool is_clear = texture_cache.IsMetaCleared(col_buf.CmaskAddress());
|
||||
color_attachments.push_back({
|
||||
.imageView = *image_view.image_view,
|
||||
.imageLayout = vk::ImageLayout::eGeneral,
|
||||
.loadOp = vk::AttachmentLoadOp::eLoad,
|
||||
.loadOp = is_clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad,
|
||||
.storeOp = vk::AttachmentStoreOp::eStore,
|
||||
.clearValue =
|
||||
is_clear ? LiverpoolToVK::ColorBufferClearValue(col_buf) : vk::ClearValue{},
|
||||
});
|
||||
texture_cache.TouchMeta(col_buf.CmaskAddress(), false);
|
||||
}
|
||||
|
||||
vk::RenderingAttachmentInfo depth_attachment{};
|
||||
u32 num_depth_attachments{};
|
||||
if (pipeline->IsDepthEnabled() && regs.depth_buffer.Address() != 0) {
|
||||
const bool is_clear = regs.depth_render_control.depth_clear_enable;
|
||||
const auto& image_view =
|
||||
|
|
Loading…
Add table
Reference in a new issue