Merge pull request #8000 from liamwhite/hagi

Initial support for Wii Hagi emulator
This commit is contained in:
Fernando S 2022-03-15 00:08:05 +01:00 committed by GitHub
commit f9e1f559b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 3 deletions

View File

@ -7,6 +7,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
#include "video_core/memory_manager.h" #include "video_core/memory_manager.h"
@ -208,6 +209,14 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
return ProcessCBBind(4); return ProcessCBBind(4);
case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): case MAXWELL3D_REG_INDEX(draw.vertex_end_gl):
return DrawArrays(); return DrawArrays();
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(topology_override):
use_topology_override = true;
return;
case MAXWELL3D_REG_INDEX(clear_buffers): case MAXWELL3D_REG_INDEX(clear_buffers):
return ProcessClearBuffers(); return ProcessClearBuffers();
case MAXWELL3D_REG_INDEX(query.query_get): case MAXWELL3D_REG_INDEX(query.query_get):
@ -360,6 +369,35 @@ 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:
topology = regs.draw.topology;
break;
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<PrimitiveTopology>(regs.topology_override);
break;
}
if (use_topology_override) {
regs.draw.topology.Assign(topology);
}
}
void Maxwell3D::FlushMMEInlineDraw() { void Maxwell3D::FlushMMEInlineDraw() {
LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
regs.vertex_buffer.count); regs.vertex_buffer.count);
@ -370,6 +408,8 @@ void Maxwell3D::FlushMMEInlineDraw() {
ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont,
"Illegal combination of instancing parameters"); "Illegal combination of instancing parameters");
ProcessTopologyOverride();
const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed; const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed;
if (ShouldExecute()) { if (ShouldExecute()) {
rasterizer->Draw(is_indexed, true); rasterizer->Draw(is_indexed, true);
@ -529,6 +569,8 @@ void Maxwell3D::DrawArrays() {
ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont,
"Illegal combination of instancing parameters"); "Illegal combination of instancing parameters");
ProcessTopologyOverride();
if (regs.draw.instance_next) { if (regs.draw.instance_next) {
// Increment the current instance *before* drawing. // Increment the current instance *before* drawing.
state.current_instance += 1; state.current_instance += 1;

View File

@ -367,6 +367,22 @@ public:
Patches = 0xe, 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,
Lines = 0x2,
LineStrip = 0x3,
Triangles = 0x4,
TriangleStrip = 0x5,
LinesAdjacency = 0xa,
LineStripAdjacency = 0xb,
TrianglesAdjacency = 0xc,
TriangleStripAdjacency = 0xd,
Patches = 0xe,
};
enum class IndexFormat : u32 { enum class IndexFormat : u32 {
UnsignedByte = 0x0, UnsignedByte = 0x0,
UnsignedShort = 0x1, UnsignedShort = 0x1,
@ -1200,7 +1216,12 @@ public:
} }
} index_array; } 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); INSERT_PADDING_WORDS_NOINIT(0x1F);
@ -1244,7 +1265,11 @@ public:
BitField<11, 1, u32> depth_clamp_disabled; BitField<11, 1, u32> depth_clamp_disabled;
} view_volume_clip_control; } view_volume_clip_control;
INSERT_PADDING_WORDS_NOINIT(0x1F); INSERT_PADDING_WORDS_NOINIT(0xC);
PrimitiveTopologyOverride topology_override;
INSERT_PADDING_WORDS_NOINIT(0x12);
u32 depth_bounds_enable; u32 depth_bounds_enable;
@ -1531,6 +1556,9 @@ private:
/// Handles a write to the VERTEX_END_GL register, triggering a draw. /// Handles a write to the VERTEX_END_GL register, triggering a draw.
void DrawArrays(); 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 // Handles a instance drawcall from MME
void StepInstance(MMEDrawMode expected_mode, u32 count); void StepInstance(MMEDrawMode expected_mode, u32 count);
@ -1569,6 +1597,7 @@ private:
Upload::State upload_state; Upload::State upload_state;
bool execute_on{true}; bool execute_on{true};
bool use_topology_override{false};
}; };
#define ASSERT_REG_POSITION(field_name, position) \ #define ASSERT_REG_POSITION(field_name, position) \
@ -1685,6 +1714,7 @@ ASSERT_REG_POSITION(draw, 0x585);
ASSERT_REG_POSITION(primitive_restart, 0x591); ASSERT_REG_POSITION(primitive_restart, 0x591);
ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1); ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1);
ASSERT_REG_POSITION(index_array, 0x5F2); ASSERT_REG_POSITION(index_array, 0x5F2);
ASSERT_REG_POSITION(small_index, 0x5F9);
ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F); ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F);
ASSERT_REG_POSITION(instanced_arrays, 0x620); ASSERT_REG_POSITION(instanced_arrays, 0x620);
ASSERT_REG_POSITION(vp_point_size, 0x644); ASSERT_REG_POSITION(vp_point_size, 0x644);
@ -1694,6 +1724,7 @@ ASSERT_REG_POSITION(cull_face, 0x648);
ASSERT_REG_POSITION(pixel_center_integer, 0x649); ASSERT_REG_POSITION(pixel_center_integer, 0x649);
ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B); ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B);
ASSERT_REG_POSITION(view_volume_clip_control, 0x64F); ASSERT_REG_POSITION(view_volume_clip_control, 0x64F);
ASSERT_REG_POSITION(topology_override, 0x65C);
ASSERT_REG_POSITION(depth_bounds_enable, 0x66F); ASSERT_REG_POSITION(depth_bounds_enable, 0x66F);
ASSERT_REG_POSITION(logic_op, 0x671); ASSERT_REG_POSITION(logic_op, 0x671);
ASSERT_REG_POSITION(clear_buffers, 0x674); ASSERT_REG_POSITION(clear_buffers, 0x674);

View File

@ -1067,7 +1067,8 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im
} }
break; break;
case PixelFormat::A8B8G8R8_UNORM: 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); return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view);
} }
break; break;