mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-06 07:06:00 +00:00
renderer_vulkan: Add support for indexed QuadList draw. (#1661)
This commit is contained in:
parent
be9c797003
commit
f8041b8446
|
@ -236,7 +236,7 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
|
|||
u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
|
||||
// Emulate QuadList primitive type with CPU made index buffer.
|
||||
const auto& regs = liverpool->regs;
|
||||
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) {
|
||||
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList && !is_indexed) {
|
||||
is_indexed = true;
|
||||
|
||||
// Emit indices.
|
||||
|
@ -262,6 +262,32 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
|
|||
VAddr index_address = regs.index_base_address.Address<VAddr>();
|
||||
index_address += index_offset * index_size;
|
||||
|
||||
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) {
|
||||
// Convert indices.
|
||||
const u32 new_index_size = regs.num_indices * index_size * 6 / 4;
|
||||
const auto [data, offset] = stream_buffer.Map(new_index_size);
|
||||
const auto index_ptr = reinterpret_cast<u8*>(index_address);
|
||||
switch (index_type) {
|
||||
case vk::IndexType::eUint16:
|
||||
Vulkan::LiverpoolToVK::ConvertQuadToTriangleListIndices<u16>(data, index_ptr,
|
||||
regs.num_indices);
|
||||
break;
|
||||
case vk::IndexType::eUint32:
|
||||
Vulkan::LiverpoolToVK::ConvertQuadToTriangleListIndices<u32>(data, index_ptr,
|
||||
regs.num_indices);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Unsupported QuadList index type {}", vk::to_string(index_type));
|
||||
break;
|
||||
}
|
||||
stream_buffer.Commit();
|
||||
|
||||
// Bind index buffer.
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, index_type);
|
||||
return new_index_size / index_size;
|
||||
}
|
||||
|
||||
// Bind index buffer.
|
||||
const u32 index_buffer_size = regs.num_indices * index_size;
|
||||
const auto [vk_buffer, offset] = ObtainBuffer(index_address, index_buffer_size, false);
|
||||
|
|
|
@ -726,19 +726,6 @@ vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat
|
|||
return format->vk_format;
|
||||
}
|
||||
|
||||
void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
|
||||
static constexpr u16 NumVerticesPerQuad = 4;
|
||||
u16* out_data = reinterpret_cast<u16*>(out_ptr);
|
||||
for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) {
|
||||
*out_data++ = i;
|
||||
*out_data++ = i + 1;
|
||||
*out_data++ = i + 2;
|
||||
*out_data++ = i;
|
||||
*out_data++ = i + 2;
|
||||
*out_data++ = i + 3;
|
||||
}
|
||||
}
|
||||
|
||||
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
|
||||
const auto comp_swap = color_buffer.info.comp_swap.Value();
|
||||
const auto format = color_buffer.info.format.Value();
|
||||
|
|
|
@ -68,7 +68,33 @@ vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color
|
|||
|
||||
vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags);
|
||||
|
||||
void EmitQuadToTriangleListIndices(u8* out_indices, u32 num_vertices);
|
||||
static constexpr u16 NumVerticesPerQuad = 4;
|
||||
|
||||
inline void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
|
||||
u16* out_data = reinterpret_cast<u16*>(out_ptr);
|
||||
for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) {
|
||||
*out_data++ = i;
|
||||
*out_data++ = i + 1;
|
||||
*out_data++ = i + 2;
|
||||
*out_data++ = i;
|
||||
*out_data++ = i + 2;
|
||||
*out_data++ = i + 3;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ConvertQuadToTriangleListIndices(u8* out_ptr, const u8* in_ptr, u32 num_vertices) {
|
||||
T* out_data = reinterpret_cast<T*>(out_ptr);
|
||||
const T* in_data = reinterpret_cast<const T*>(in_ptr);
|
||||
for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) {
|
||||
*out_data++ = in_data[i];
|
||||
*out_data++ = in_data[i + 1];
|
||||
*out_data++ = in_data[i + 2];
|
||||
*out_data++ = in_data[i];
|
||||
*out_data++ = in_data[i + 2];
|
||||
*out_data++ = in_data[i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
static inline vk::Format PromoteFormatToDepth(vk::Format fmt) {
|
||||
if (fmt == vk::Format::eR32Sfloat) {
|
||||
|
|
Loading…
Reference in a new issue