mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-07 15:46:01 +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) {
|
u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
|
||||||
// Emulate QuadList primitive type with CPU made index buffer.
|
// Emulate QuadList primitive type with CPU made index buffer.
|
||||||
const auto& regs = liverpool->regs;
|
const auto& regs = liverpool->regs;
|
||||||
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) {
|
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList && !is_indexed) {
|
||||||
is_indexed = true;
|
is_indexed = true;
|
||||||
|
|
||||||
// Emit indices.
|
// Emit indices.
|
||||||
|
@ -262,6 +262,32 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
|
||||||
VAddr index_address = regs.index_base_address.Address<VAddr>();
|
VAddr index_address = regs.index_base_address.Address<VAddr>();
|
||||||
index_address += index_offset * index_size;
|
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.
|
// Bind index buffer.
|
||||||
const u32 index_buffer_size = regs.num_indices * index_size;
|
const u32 index_buffer_size = regs.num_indices * index_size;
|
||||||
const auto [vk_buffer, offset] = ObtainBuffer(index_address, index_buffer_size, false);
|
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;
|
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) {
|
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
|
||||||
const auto comp_swap = color_buffer.info.comp_swap.Value();
|
const auto comp_swap = color_buffer.info.comp_swap.Value();
|
||||||
const auto format = color_buffer.info.format.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);
|
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) {
|
static inline vk::Format PromoteFormatToDepth(vk::Format fmt) {
|
||||||
if (fmt == vk::Format::eR32Sfloat) {
|
if (fmt == vk::Format::eR32Sfloat) {
|
||||||
|
|
Loading…
Reference in a new issue