From f1521183f8c029e45a707e9127bccf33a05cc366 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 10 Mar 2022 19:21:04 -0500 Subject: [PATCH 1/7] Maxwell3D: read small-index draw and primitive topology override registers This allows Galaxy and Sunshine to render for the first time. --- src/video_core/engines/maxwell_3d.cpp | 14 ++++++++++++++ src/video_core/engines/maxwell_3d.h | 18 ++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 5d6d217bb..2d640bd43 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -208,6 +208,10 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume return ProcessCBBind(4); case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): return DrawArrays(); + case MAXWELL3D_REG_INDEX(small_index): + regs.index_array.count = regs.small_index.count; + regs.index_array.first = regs.small_index.first; + return DrawArrays(); case MAXWELL3D_REG_INDEX(clear_buffers): return ProcessClearBuffers(); case MAXWELL3D_REG_INDEX(query.query_get): @@ -360,6 +364,12 @@ void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) { } } +void Maxwell3D::ProcessTopologyOverride() { + if (regs.draw.topology != regs.topology_override) { + regs.draw.topology.Assign(regs.topology_override); + } +} + void Maxwell3D::FlushMMEInlineDraw() { LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), regs.vertex_buffer.count); @@ -370,6 +380,8 @@ void Maxwell3D::FlushMMEInlineDraw() { ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, "Illegal combination of instancing parameters"); + ProcessTopologyOverride(); + const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed; if (ShouldExecute()) { rasterizer->Draw(is_indexed, true); @@ -529,6 +541,8 @@ void Maxwell3D::DrawArrays() { ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, "Illegal combination of instancing parameters"); + ProcessTopologyOverride(); + if (regs.draw.instance_next) { // Increment the current instance *before* drawing. state.current_instance += 1; diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index dc9df6c8b..e28937b01 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1200,7 +1200,12 @@ public: } } index_array; - INSERT_PADDING_WORDS_NOINIT(0x7); + union { + BitField<0, 16, u32> first; + BitField<16, 16, u32> count; + } small_index; + + INSERT_PADDING_WORDS_NOINIT(0x6); INSERT_PADDING_WORDS_NOINIT(0x1F); @@ -1244,7 +1249,11 @@ public: BitField<11, 1, u32> depth_clamp_disabled; } view_volume_clip_control; - INSERT_PADDING_WORDS_NOINIT(0x1F); + INSERT_PADDING_WORDS_NOINIT(0xC); + + PrimitiveTopology topology_override; + + INSERT_PADDING_WORDS_NOINIT(0x12); u32 depth_bounds_enable; @@ -1531,6 +1540,9 @@ private: /// Handles a write to the VERTEX_END_GL register, triggering a draw. void DrawArrays(); + /// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro) + void ProcessTopologyOverride(); + // Handles a instance drawcall from MME void StepInstance(MMEDrawMode expected_mode, u32 count); @@ -1685,6 +1697,7 @@ ASSERT_REG_POSITION(draw, 0x585); ASSERT_REG_POSITION(primitive_restart, 0x591); ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1); ASSERT_REG_POSITION(index_array, 0x5F2); +ASSERT_REG_POSITION(small_index, 0x5F9); ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F); ASSERT_REG_POSITION(instanced_arrays, 0x620); ASSERT_REG_POSITION(vp_point_size, 0x644); @@ -1694,6 +1707,7 @@ ASSERT_REG_POSITION(cull_face, 0x648); ASSERT_REG_POSITION(pixel_center_integer, 0x649); ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B); ASSERT_REG_POSITION(view_volume_clip_control, 0x64F); +ASSERT_REG_POSITION(topology_override, 0x65C); ASSERT_REG_POSITION(depth_bounds_enable, 0x66F); ASSERT_REG_POSITION(logic_op, 0x671); ASSERT_REG_POSITION(clear_buffers, 0x674); From 82c3042c0f0a4e0c4fdefd64c2f2b5b3b2a31e3b Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 10 Mar 2022 19:44:25 -0500 Subject: [PATCH 2/7] TextureCacheRuntime: allow converting D24S8 to ABGR8 I can't see how this would be useful, but Galaxy uses it. --- src/video_core/renderer_vulkan/vk_texture_cache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 0f62779de..ca6019a3a 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1067,7 +1067,8 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im } break; case PixelFormat::A8B8G8R8_UNORM: - if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { + if (src_view.format == PixelFormat::S8_UINT_D24_UNORM || + src_view.format == PixelFormat::D24_UNORM_S8_UINT) { return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view); } break; From 70e632f1537d2e087af0b055c80e9124e0aa7c85 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 11 Mar 2022 08:47:01 -0500 Subject: [PATCH 3/7] Maxwell3D: mark index buffers as dirty after updating counts --- src/video_core/engines/maxwell_3d.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2d640bd43..94711ad6b 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -7,6 +7,7 @@ #include "common/assert.h" #include "core/core.h" #include "core/core_timing.h" +#include "video_core/dirty_flags.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/gpu.h" #include "video_core/memory_manager.h" @@ -211,6 +212,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume case MAXWELL3D_REG_INDEX(small_index): regs.index_array.count = regs.small_index.count; regs.index_array.first = regs.small_index.first; + dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; return DrawArrays(); case MAXWELL3D_REG_INDEX(clear_buffers): return ProcessClearBuffers(); From 56c646d82cdb78557cac7a527247bb46c6028e97 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 11 Mar 2022 17:16:56 -0500 Subject: [PATCH 4/7] Maxwell3D: Restrict topology override effect to after the register is set --- src/video_core/engines/maxwell_3d.cpp | 5 ++++- src/video_core/engines/maxwell_3d.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 94711ad6b..92baba4e8 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -214,6 +214,9 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume regs.index_array.first = regs.small_index.first; dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; return DrawArrays(); + case MAXWELL3D_REG_INDEX(topology_override): + use_topology_override = true; + return; case MAXWELL3D_REG_INDEX(clear_buffers): return ProcessClearBuffers(); case MAXWELL3D_REG_INDEX(query.query_get): @@ -367,7 +370,7 @@ void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) { } void Maxwell3D::ProcessTopologyOverride() { - if (regs.draw.topology != regs.topology_override) { + if (use_topology_override) { regs.draw.topology.Assign(regs.topology_override); } } diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index e28937b01..eefb7a4dd 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1581,6 +1581,7 @@ private: Upload::State upload_state; bool execute_on{true}; + bool use_topology_override{false}; }; #define ASSERT_REG_POSITION(field_name, position) \ From 37aa472269df2e66af151c36822d0d248bec1a40 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 14 Mar 2022 10:11:28 -0400 Subject: [PATCH 5/7] Maxwell3D: Use override constants from nouveau This fixes some incorrect rendering in Sunshine --- src/video_core/engines/maxwell_3d.cpp | 23 ++++++++++++++++++++++- src/video_core/engines/maxwell_3d.h | 16 +++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 92baba4e8..aa88984d4 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -370,8 +370,29 @@ void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) { } void Maxwell3D::ProcessTopologyOverride() { + using PrimitiveTopology = Maxwell3D::Regs::PrimitiveTopology; + using PrimitiveTopologyOverride = Maxwell3D::Regs::PrimitiveTopologyOverride; + + PrimitiveTopology topology{}; + + switch (regs.topology_override) { + case PrimitiveTopologyOverride::None: + case PrimitiveTopologyOverride::Points: + topology = PrimitiveTopology::Points; + break; + case PrimitiveTopologyOverride::Lines: + topology = PrimitiveTopology::Lines; + break; + case PrimitiveTopologyOverride::LineStrip: + topology = PrimitiveTopology::LineStrip; + break; + default: + topology = static_cast(regs.topology_override); + break; + } + if (use_topology_override) { - regs.draw.topology.Assign(regs.topology_override); + regs.draw.topology.Assign(topology); } } diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index eefb7a4dd..513a9d5df 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -367,6 +367,20 @@ public: Patches = 0xe, }; + enum class PrimitiveTopologyOverride : u32 { + None = 0x0, + Points = 0x1, + Lines = 0x2, + LineStrip = 0x3, + Triangles = 0x4, + TriangleStrip = 0x5, + LinesAdjacency = 0xa, + LineStripAdjacency = 0xb, + TrianglesAdjacency = 0xc, + TriangleStripAdjacency = 0xd, + Patches = 0xe, + }; + enum class IndexFormat : u32 { UnsignedByte = 0x0, UnsignedShort = 0x1, @@ -1251,7 +1265,7 @@ public: INSERT_PADDING_WORDS_NOINIT(0xC); - PrimitiveTopology topology_override; + PrimitiveTopologyOverride topology_override; INSERT_PADDING_WORDS_NOINIT(0x12); From 364c67e49b8a90ad67fcf492c6b06661a8764e47 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Mon, 14 Mar 2022 10:37:51 -0400 Subject: [PATCH 6/7] Maxwell3D: restore original topology when topology overrides are disabled --- src/video_core/engines/maxwell_3d.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index aa88984d4..8f2fd28c2 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -377,6 +377,8 @@ void Maxwell3D::ProcessTopologyOverride() { switch (regs.topology_override) { case PrimitiveTopologyOverride::None: + topology = regs.draw.topology; + break; case PrimitiveTopologyOverride::Points: topology = PrimitiveTopology::Points; break; From be0e6a2bb456cc5b3c431d5b9f18573a26f611ec Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Mon, 14 Mar 2022 11:06:25 -0400 Subject: [PATCH 7/7] Maxwell3D: Link to override constant definition in nouveau --- src/video_core/engines/maxwell_3d.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 513a9d5df..6d34da046 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -367,6 +367,8 @@ public: Patches = 0xe, }; + // Constants as from NVC0_3D_UNK1970_D3D + // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h#L1598 enum class PrimitiveTopologyOverride : u32 { None = 0x0, Points = 0x1,