mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-25 10:52:48 -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;
|
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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue