Skip to content

Commit 011551b

Browse files
polybiusproxyXcedf
authored andcommitted
renderer_vulkan: add support for Polygon draws (shadps4-emu#1798)
1 parent c1a8922 commit 011551b

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

src/video_core/buffer_cache/buffer_cache.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,25 +235,44 @@ bool BufferCache::BindVertexBuffers(
235235
}
236236

237237
u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
238-
// Emulate QuadList primitive type with CPU made index buffer.
238+
// Emulate QuadList and Polygon primitive types with CPU made index buffer.
239239
const auto& regs = liverpool->regs;
240-
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList && !is_indexed) {
241-
is_indexed = true;
240+
if (!is_indexed) {
241+
bool needs_index_buffer = false;
242+
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList ||
243+
regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
244+
needs_index_buffer = true;
245+
}
246+
247+
if (!needs_index_buffer) {
248+
return regs.num_indices;
249+
}
242250

243251
// Emit indices.
244252
const u32 index_size = 3 * regs.num_indices;
245253
const auto [data, offset] = stream_buffer.Map(index_size);
246-
Vulkan::LiverpoolToVK::EmitQuadToTriangleListIndices(data, regs.num_indices);
254+
255+
switch (regs.primitive_type) {
256+
case AmdGpu::PrimitiveType::QuadList:
257+
Vulkan::LiverpoolToVK::EmitQuadToTriangleListIndices(data, regs.num_indices);
258+
break;
259+
case AmdGpu::PrimitiveType::Polygon:
260+
Vulkan::LiverpoolToVK::EmitPolygonToTriangleListIndices(data, regs.num_indices);
261+
break;
262+
default:
263+
UNREACHABLE();
264+
break;
265+
}
266+
247267
stream_buffer.Commit();
248268

249269
// Bind index buffer.
270+
is_indexed = true;
271+
250272
const auto cmdbuf = scheduler.CommandBuffer();
251273
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, vk::IndexType::eUint16);
252274
return index_size / sizeof(u16);
253275
}
254-
if (!is_indexed) {
255-
return regs.num_indices;
256-
}
257276

258277
// Figure out index type and size.
259278
const bool is_index16 =
@@ -288,6 +307,9 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) {
288307
cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, index_type);
289308
return new_index_size / index_size;
290309
}
310+
if (regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
311+
UNREACHABLE();
312+
}
291313

292314
// Bind index buffer.
293315
const u32 index_buffer_size = regs.num_indices * index_size;

src/video_core/renderer_vulkan/liverpool_to_vk.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ vk::PrimitiveTopology PrimitiveType(AmdGpu::PrimitiveType type) {
117117
case AmdGpu::PrimitiveType::PatchPrimitive:
118118
return vk::PrimitiveTopology::ePatchList;
119119
case AmdGpu::PrimitiveType::QuadList:
120+
case AmdGpu::PrimitiveType::Polygon:
120121
// Needs to generate index buffer on the fly.
121122
return vk::PrimitiveTopology::eTriangleList;
122123
case AmdGpu::PrimitiveType::RectList:

src/video_core/renderer_vulkan/liverpool_to_vk.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ void ConvertQuadToTriangleListIndices(u8* out_ptr, const u8* in_ptr, u32 num_ver
9898
}
9999
}
100100

101+
inline void EmitPolygonToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
102+
u16* out_data = reinterpret_cast<u16*>(out_ptr);
103+
for (u16 i = 1; i < num_vertices - 1; i++) {
104+
*out_data++ = 0;
105+
*out_data++ = i;
106+
*out_data++ = i + 1;
107+
}
108+
}
109+
101110
static inline vk::Format PromoteFormatToDepth(vk::Format fmt) {
102111
if (fmt == vk::Format::eR32Sfloat) {
103112
return vk::Format::eD32Sfloat;

src/video_core/renderer_vulkan/vk_rasterizer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,12 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
138138
}
139139

140140
const auto& regs = liverpool->regs;
141-
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) {
142-
// For QuadList we use generated index buffer to convert quads to triangles. Since it
141+
if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList ||
142+
regs.primitive_type == AmdGpu::PrimitiveType::Polygon) {
143+
// We use a generated index buffer to convert quad lists and polygons to triangles. Since it
143144
// changes type of the draw, arguments are not valid for this case. We need to run a
144145
// conversion pass to repack the indirect arguments buffer first.
145-
LOG_WARNING(Render_Vulkan, "QuadList primitive type is not supported for indirect draw");
146+
LOG_WARNING(Render_Vulkan, "Primitive type is not supported for indirect draw");
146147
return;
147148
}
148149

0 commit comments

Comments
 (0)