mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-14 02:45:14 +00:00
renderer_vulkan: add support for Polygon draws (#1798)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
This commit is contained in:
parent
39fed1f469
commit
8d8bb05055
|
@ -235,25 +235,44 @@ bool BufferCache::BindVertexBuffers(
|
||||||
}
|
}
|
||||||
|
|
||||||
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 and Polygon primitive types with CPU made index buffer.
|
||||||
const auto& regs = liverpool->regs;
|
const auto& regs = liverpool->regs;
|
||||||
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList && !is_indexed) {
|
if (!is_indexed) {
|
||||||
is_indexed = true;
|
bool needs_index_buffer = false;
|
||||||
|
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList ||
|
||||||
|
regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
|
||||||
|
needs_index_buffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needs_index_buffer) {
|
||||||
|
return regs.num_indices;
|
||||||
|
}
|
||||||
|
|
||||||
// Emit indices.
|
// Emit indices.
|
||||||
const u32 index_size = 3 * regs.num_indices;
|
const u32 index_size = 3 * regs.num_indices;
|
||||||
const auto [data, offset] = stream_buffer.Map(index_size);
|
const auto [data, offset] = stream_buffer.Map(index_size);
|
||||||
Vulkan::LiverpoolToVK::EmitQuadToTriangleListIndices(data, regs.num_indices);
|
|
||||||
|
switch (regs.primitive_type) {
|
||||||
|
case AmdGpu::PrimitiveType::QuadList:
|
||||||
|
Vulkan::LiverpoolToVK::EmitQuadToTriangleListIndices(data, regs.num_indices);
|
||||||
|
break;
|
||||||
|
case AmdGpu::PrimitiveType::Polygon:
|
||||||
|
Vulkan::LiverpoolToVK::EmitPolygonToTriangleListIndices(data, regs.num_indices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
stream_buffer.Commit();
|
stream_buffer.Commit();
|
||||||
|
|
||||||
// Bind index buffer.
|
// Bind index buffer.
|
||||||
|
is_indexed = true;
|
||||||
|
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, vk::IndexType::eUint16);
|
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, vk::IndexType::eUint16);
|
||||||
return index_size / sizeof(u16);
|
return index_size / sizeof(u16);
|
||||||
}
|
}
|
||||||
if (!is_indexed) {
|
|
||||||
return regs.num_indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out index type and size.
|
// Figure out index type and size.
|
||||||
const bool is_index16 =
|
const bool is_index16 =
|
||||||
|
@ -288,6 +307,9 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
|
||||||
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, index_type);
|
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, index_type);
|
||||||
return new_index_size / index_size;
|
return new_index_size / index_size;
|
||||||
}
|
}
|
||||||
|
if (regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
|
@ -117,6 +117,7 @@ vk::PrimitiveTopology PrimitiveType(AmdGpu::PrimitiveType type) {
|
||||||
case AmdGpu::PrimitiveType::PatchPrimitive:
|
case AmdGpu::PrimitiveType::PatchPrimitive:
|
||||||
return vk::PrimitiveTopology::ePatchList;
|
return vk::PrimitiveTopology::ePatchList;
|
||||||
case AmdGpu::PrimitiveType::QuadList:
|
case AmdGpu::PrimitiveType::QuadList:
|
||||||
|
case AmdGpu::PrimitiveType::Polygon:
|
||||||
// Needs to generate index buffer on the fly.
|
// Needs to generate index buffer on the fly.
|
||||||
return vk::PrimitiveTopology::eTriangleList;
|
return vk::PrimitiveTopology::eTriangleList;
|
||||||
case AmdGpu::PrimitiveType::RectList:
|
case AmdGpu::PrimitiveType::RectList:
|
||||||
|
|
|
@ -98,6 +98,15 @@ void ConvertQuadToTriangleListIndices(u8* out_ptr, const u8* in_ptr, u32 num_ver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void EmitPolygonToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
|
||||||
|
u16* out_data = reinterpret_cast<u16*>(out_ptr);
|
||||||
|
for (u16 i = 1; i < num_vertices - 1; i++) {
|
||||||
|
*out_data++ = 0;
|
||||||
|
*out_data++ = i;
|
||||||
|
*out_data++ = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
return vk::Format::eD32Sfloat;
|
return vk::Format::eD32Sfloat;
|
||||||
|
|
|
@ -246,11 +246,12 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& regs = liverpool->regs;
|
const auto& regs = liverpool->regs;
|
||||||
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) {
|
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList ||
|
||||||
// For QuadList we use generated index buffer to convert quads to triangles. Since it
|
regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
|
||||||
|
// We use a generated index buffer to convert quad lists and polygons to triangles. Since it
|
||||||
// changes type of the draw, arguments are not valid for this case. We need to run a
|
// changes type of the draw, arguments are not valid for this case. We need to run a
|
||||||
// conversion pass to repack the indirect arguments buffer first.
|
// conversion pass to repack the indirect arguments buffer first.
|
||||||
LOG_WARNING(Render_Vulkan, "QuadList primitive type is not supported for indirect draw");
|
LOG_WARNING(Render_Vulkan, "Primitive type is not supported for indirect draw");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue