draw properly

This commit is contained in:
Samuliak 2024-10-06 10:03:53 +02:00
parent 5b9a9f3077
commit 62168ca0f0
No known key found for this signature in database
5 changed files with 104 additions and 33 deletions

View file

@ -313,4 +313,33 @@ inline MTL::VertexFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwe
return format; return format;
} }
inline MTL::IndexType IndexType(Maxwell::IndexFormat format) {
switch (format) {
// TODO: UnsignedByte
case Maxwell::IndexFormat::UnsignedShort:
return MTL::IndexTypeUInt16;
case Maxwell::IndexFormat::UnsignedInt:
return MTL::IndexTypeUInt32;
default:
UNIMPLEMENTED_MSG("Unimplemented index format {}", format);
}
return MTL::IndexTypeUInt16;
}
inline size_t IndexSize(Maxwell::IndexFormat format) {
switch (format) {
case Maxwell::IndexFormat::UnsignedByte:
return 1;
case Maxwell::IndexFormat::UnsignedShort:
return 2;
case Maxwell::IndexFormat::UnsignedInt:
return 4;
default:
UNIMPLEMENTED_MSG("Unimplemented index format {}", format);
}
return 0;
}
} // namespace Metal::MaxwellToMTL } // namespace Metal::MaxwellToMTL

View file

@ -7,6 +7,7 @@
#include <QuartzCore/QuartzCore.hpp> #include <QuartzCore/QuartzCore.hpp>
#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h"
#include "video_core/renderer_metal/maxwell_to_mtl.h"
namespace Metal { namespace Metal {
@ -37,10 +38,11 @@ struct BoundSamplerState {
struct BoundIndexBuffer { struct BoundIndexBuffer {
MTL::Buffer* buffer{nullptr}; MTL::Buffer* buffer{nullptr};
size_t offset{0}; size_t offset{0};
MTL::IndexType index_format; MTL::IndexType index_type;
MTL::PrimitiveType primitive_topology; size_t index_size;
u32 num_indices; //MTL::PrimitiveType primitive_topology;
u32 base_vertex; //u32 num_indices;
//u32 base_vertex;
}; };
struct RenderState { struct RenderState {
@ -140,8 +142,13 @@ public:
u32 base_vertex) { u32 base_vertex) {
// TODO: convert parameters to Metal enums // TODO: convert parameters to Metal enums
render_state.bound_index_buffer = { render_state.bound_index_buffer = {
buffer, offset, MTL::IndexTypeUInt32, MTL::PrimitiveTypeTriangle, buffer, offset, MaxwellToMTL::IndexType(index_format), MaxwellToMTL::IndexSize(index_format)/*, MTL::PrimitiveTypeTriangle,
num_indices, base_vertex}; num_indices, base_vertex*/};
}
// Getters
const BoundIndexBuffer& GetBoundIndexBuffer() const {
return render_state.bound_index_buffer;
} }
private: private:

View file

@ -226,7 +226,7 @@ void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
ASSERT(index < MAX_BUFFERS); ASSERT(index < MAX_BUFFERS);
// TODO: instancing // TODO: instancing
auto layout = vertex_descriptor->layouts()->object(index); auto layout = vertex_descriptor->layouts()->object(MAX_BUFFERS - 1 - index);
layout->setStride(array.stride.Value()); layout->setStride(array.stride.Value());
} }
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
@ -236,7 +236,7 @@ void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
continue; continue;
auto attribute = vertex_descriptor->attributes()->object(index); auto attribute = vertex_descriptor->attributes()->object(index);
attribute->setBufferIndex(input.buffer); attribute->setBufferIndex(MAX_BUFFERS - 1 - input.buffer);
attribute->setOffset(input.offset); attribute->setOffset(input.offset);
attribute->setFormat(MaxwellToMTL::VertexFormat(input.type.Value(), input.size.Value())); attribute->setFormat(MaxwellToMTL::VertexFormat(input.type.Value(), input.size.Value()));
} }

View file

@ -332,6 +332,8 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const
if (pipeline->IsBuilt()) { if (pipeline->IsBuilt()) {
return pipeline; return pipeline;
} }
// TODO: what
const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) { if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) {
return pipeline; return pipeline;

View file

@ -16,6 +16,49 @@
namespace Metal { namespace Metal {
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
using MaxwellDrawState = Tegra::Engines::DrawManager::State;
using VideoCommon::ImageViewId;
using VideoCommon::ImageViewType;
namespace {
struct DrawParams {
u32 base_instance;
u32 num_instances;
u32 base_vertex;
u32 num_vertices;
u32 first_index;
bool is_indexed;
};
DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances, bool is_indexed) {
DrawParams params{
.base_instance = draw_state.base_instance,
.num_instances = num_instances,
.base_vertex = is_indexed ? draw_state.base_index : draw_state.vertex_buffer.first,
.num_vertices = is_indexed ? draw_state.index_buffer.count : draw_state.vertex_buffer.count,
.first_index = is_indexed ? draw_state.index_buffer.first : 0,
.is_indexed = is_indexed,
};
// 6 triangle vertices per quad, base vertex is part of the index
// See BindQuadIndexBuffer for more details
if (draw_state.topology == Maxwell::PrimitiveTopology::Quads) {
params.num_vertices = (params.num_vertices / 4) * 6;
params.base_vertex = 0;
params.is_indexed = true;
} else if (draw_state.topology == Maxwell::PrimitiveTopology::QuadStrip) {
params.num_vertices = (params.num_vertices - 2) / 2 * 6;
params.base_vertex = 0;
params.is_indexed = true;
}
return params;
}
} // Anonymous namespace
AccelerateDMA::AccelerateDMA() = default; AccelerateDMA::AccelerateDMA() = default;
bool AccelerateDMA::BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) { bool AccelerateDMA::BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) {
@ -41,41 +84,33 @@ RasterizerMetal::RasterizerMetal(Tegra::GPU& gpu_,
RasterizerMetal::~RasterizerMetal() = default; RasterizerMetal::~RasterizerMetal() = default;
void RasterizerMetal::Draw(bool is_indexed, u32 instance_count) { void RasterizerMetal::Draw(bool is_indexed, u32 instance_count) {
LOG_DEBUG(Render_Metal, "called");
// Bind the current graphics pipeline // Bind the current graphics pipeline
GraphicsPipeline* const pipeline{pipeline_cache.CurrentGraphicsPipeline()}; GraphicsPipeline* const pipeline{pipeline_cache.CurrentGraphicsPipeline()};
if (!pipeline) { if (!pipeline) {
return; return;
} }
// Set the engine // Set the engine
pipeline->SetEngine(maxwell3d, gpu_memory); pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed); pipeline->Configure(is_indexed);
// HACK: dummy draw call const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
command_recorder.GetRenderCommandEncoder()->drawPrimitives(MTL::PrimitiveTypeTriangle, const DrawParams draw_params{MakeDrawParams(draw_state, instance_count, is_indexed)};
NS::UInteger(0), NS::UInteger(3));
// TODO: get the primitive type
MTL::PrimitiveType primitiveType = MTL::PrimitiveTypeTriangle;//MaxwellToMTL::PrimitiveType(draw_state.topology);
// TODO: uncomment
// command_recorder.CheckIfRenderPassIsActive();
// const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
if (is_indexed) { if (is_indexed) {
LOG_DEBUG(Render_Metal, "indexed"); auto& index_buffer = command_recorder.GetBoundIndexBuffer();
/*[command_buffer drawIndexedPrimitives:MTLPrimitiveTypeTriangle size_t index_buffer_offset = index_buffer.offset + draw_params.first_index * index_buffer.index_size;
indexCount:draw_params.num_indices
indexType:MTLIndexTypeUInt32 ASSERT(index_buffer_offset % 4 == 0);
indexBuffer:draw_state.index_buffer
indexBufferOffset:draw_params.first_index * sizeof(u32) command_recorder.GetRenderCommandEncoder()->drawIndexedPrimitives(primitiveType, draw_params.num_vertices, index_buffer.index_type, index_buffer.buffer, index_buffer_offset, draw_params.num_instances,
instanceCount:draw_params.num_instances draw_params.base_vertex, draw_params.base_instance);
baseVertex:draw_params.base_vertex
baseInstance:draw_params.base_instance];*/
// cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances,
// draw_params.first_index, draw_params.base_vertex,
// draw_params.base_instance);
} else { } else {
LOG_DEBUG(Render_Metal, "not indexed"); command_recorder.GetRenderCommandEncoder()->drawPrimitives(primitiveType,
// cmdbuf.Draw(draw_params.num_vertices, draw_params.num_instances, draw_params.base_vertex, draw_params.num_vertices, draw_params.num_instances, draw_params.base_instance);
// draw_params.base_vertex, draw_params.base_instance);
} }
} }
@ -92,8 +127,6 @@ void RasterizerMetal::Clear(u32 layer_count) {
return; return;
} }
// TODO: track the textures used by render pass and only begin the render pass if their contents
// are needed Begin render pass
command_recorder.BeginOrContinueRenderPass(framebuffer->GetHandle()); command_recorder.BeginOrContinueRenderPass(framebuffer->GetHandle());
} }