mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-24 18:32:49 -06:00
draw properly
This commit is contained in:
parent
5b9a9f3077
commit
62168ca0f0
5 changed files with 104 additions and 33 deletions
|
@ -313,4 +313,33 @@ inline MTL::VertexFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwe
|
|||
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
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <QuartzCore/QuartzCore.hpp>
|
||||
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
#include "video_core/renderer_metal/maxwell_to_mtl.h"
|
||||
|
||||
namespace Metal {
|
||||
|
||||
|
@ -37,10 +38,11 @@ struct BoundSamplerState {
|
|||
struct BoundIndexBuffer {
|
||||
MTL::Buffer* buffer{nullptr};
|
||||
size_t offset{0};
|
||||
MTL::IndexType index_format;
|
||||
MTL::PrimitiveType primitive_topology;
|
||||
u32 num_indices;
|
||||
u32 base_vertex;
|
||||
MTL::IndexType index_type;
|
||||
size_t index_size;
|
||||
//MTL::PrimitiveType primitive_topology;
|
||||
//u32 num_indices;
|
||||
//u32 base_vertex;
|
||||
};
|
||||
|
||||
struct RenderState {
|
||||
|
@ -140,8 +142,13 @@ public:
|
|||
u32 base_vertex) {
|
||||
// TODO: convert parameters to Metal enums
|
||||
render_state.bound_index_buffer = {
|
||||
buffer, offset, MTL::IndexTypeUInt32, MTL::PrimitiveTypeTriangle,
|
||||
num_indices, base_vertex};
|
||||
buffer, offset, MaxwellToMTL::IndexType(index_format), MaxwellToMTL::IndexSize(index_format)/*, MTL::PrimitiveTypeTriangle,
|
||||
num_indices, base_vertex*/};
|
||||
}
|
||||
|
||||
// Getters
|
||||
const BoundIndexBuffer& GetBoundIndexBuffer() const {
|
||||
return render_state.bound_index_buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -226,7 +226,7 @@ void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
|
|||
ASSERT(index < MAX_BUFFERS);
|
||||
|
||||
// TODO: instancing
|
||||
auto layout = vertex_descriptor->layouts()->object(index);
|
||||
auto layout = vertex_descriptor->layouts()->object(MAX_BUFFERS - 1 - index);
|
||||
layout->setStride(array.stride.Value());
|
||||
}
|
||||
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||
|
@ -236,7 +236,7 @@ void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
|
|||
continue;
|
||||
|
||||
auto attribute = vertex_descriptor->attributes()->object(index);
|
||||
attribute->setBufferIndex(input.buffer);
|
||||
attribute->setBufferIndex(MAX_BUFFERS - 1 - input.buffer);
|
||||
attribute->setOffset(input.offset);
|
||||
attribute->setFormat(MaxwellToMTL::VertexFormat(input.type.Value(), input.size.Value()));
|
||||
}
|
||||
|
|
|
@ -332,6 +332,8 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const
|
|||
if (pipeline->IsBuilt()) {
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
// TODO: what
|
||||
const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
|
||||
if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) {
|
||||
return pipeline;
|
||||
|
|
|
@ -16,6 +16,49 @@
|
|||
|
||||
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;
|
||||
|
||||
bool AccelerateDMA::BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) {
|
||||
|
@ -41,41 +84,33 @@ RasterizerMetal::RasterizerMetal(Tegra::GPU& gpu_,
|
|||
RasterizerMetal::~RasterizerMetal() = default;
|
||||
|
||||
void RasterizerMetal::Draw(bool is_indexed, u32 instance_count) {
|
||||
LOG_DEBUG(Render_Metal, "called");
|
||||
|
||||
// Bind the current graphics pipeline
|
||||
GraphicsPipeline* const pipeline{pipeline_cache.CurrentGraphicsPipeline()};
|
||||
if (!pipeline) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the engine
|
||||
pipeline->SetEngine(maxwell3d, gpu_memory);
|
||||
pipeline->Configure(is_indexed);
|
||||
|
||||
// HACK: dummy draw call
|
||||
command_recorder.GetRenderCommandEncoder()->drawPrimitives(MTL::PrimitiveTypeTriangle,
|
||||
NS::UInteger(0), NS::UInteger(3));
|
||||
const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
|
||||
const DrawParams draw_params{MakeDrawParams(draw_state, instance_count, is_indexed)};
|
||||
|
||||
// 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) {
|
||||
LOG_DEBUG(Render_Metal, "indexed");
|
||||
/*[command_buffer drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
indexCount:draw_params.num_indices
|
||||
indexType:MTLIndexTypeUInt32
|
||||
indexBuffer:draw_state.index_buffer
|
||||
indexBufferOffset:draw_params.first_index * sizeof(u32)
|
||||
instanceCount:draw_params.num_instances
|
||||
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);
|
||||
auto& index_buffer = command_recorder.GetBoundIndexBuffer();
|
||||
size_t index_buffer_offset = index_buffer.offset + draw_params.first_index * index_buffer.index_size;
|
||||
|
||||
ASSERT(index_buffer_offset % 4 == 0);
|
||||
|
||||
command_recorder.GetRenderCommandEncoder()->drawIndexedPrimitives(primitiveType, draw_params.num_vertices, index_buffer.index_type, index_buffer.buffer, index_buffer_offset, draw_params.num_instances,
|
||||
draw_params.base_vertex, draw_params.base_instance);
|
||||
} else {
|
||||
LOG_DEBUG(Render_Metal, "not indexed");
|
||||
// cmdbuf.Draw(draw_params.num_vertices, draw_params.num_instances,
|
||||
// draw_params.base_vertex, draw_params.base_instance);
|
||||
command_recorder.GetRenderCommandEncoder()->drawPrimitives(primitiveType,
|
||||
draw_params.base_vertex, draw_params.num_vertices, draw_params.num_instances, draw_params.base_instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,8 +127,6 @@ void RasterizerMetal::Clear(u32 layer_count) {
|
|||
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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue