mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-15 22:54:00 +00:00
create vertex descriptor
This commit is contained in:
parent
0b12e22331
commit
5b9a9f3077
3 changed files with 209 additions and 8 deletions
|
@ -145,4 +145,172 @@ inline size_t GetTextureBytesPerRow(VideoCore::Surface::PixelFormat pixel_format
|
|||
format_info.bytes_per_block;
|
||||
}
|
||||
|
||||
inline MTL::VertexFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) {
|
||||
const MTL::VertexFormat format{([&]() {
|
||||
switch (type) {
|
||||
case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
|
||||
ASSERT_MSG(false, "Invalid vertex attribute type!");
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::UNorm:
|
||||
switch (size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_A8:
|
||||
return MTL::VertexFormatUCharNormalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8:
|
||||
case Maxwell::VertexAttribute::Size::Size_G8_R8:
|
||||
return MTL::VertexFormatUChar2Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
|
||||
return MTL::VertexFormatUChar3Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
|
||||
return MTL::VertexFormatUChar4Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
return MTL::VertexFormatUShortNormalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
return MTL::VertexFormatUShort2Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
return MTL::VertexFormatUShort3Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return MTL::VertexFormatUShort4Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
|
||||
return MTL::VertexFormatInvalid; // TODO: emulate
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::SNorm:
|
||||
switch (size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_A8:
|
||||
return MTL::VertexFormatCharNormalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8:
|
||||
case Maxwell::VertexAttribute::Size::Size_G8_R8:
|
||||
return MTL::VertexFormatChar2Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
|
||||
return MTL::VertexFormatChar3Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
|
||||
return MTL::VertexFormatChar4Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
return MTL::VertexFormatShortNormalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
return MTL::VertexFormatShort2Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
return MTL::VertexFormatShort3Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return MTL::VertexFormatShort4Normalized;
|
||||
case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
|
||||
return MTL::VertexFormatInvalid; // TODO: emulate
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::UInt:
|
||||
case Maxwell::VertexAttribute::Type::UScaled:
|
||||
switch (size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_A8:
|
||||
return MTL::VertexFormatUChar;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8:
|
||||
case Maxwell::VertexAttribute::Size::Size_G8_R8:
|
||||
return MTL::VertexFormatUChar2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
|
||||
return MTL::VertexFormatUChar3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
|
||||
return MTL::VertexFormatUChar4;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
return MTL::VertexFormatUShort;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
return MTL::VertexFormatUShort2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
return MTL::VertexFormatUShort3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return MTL::VertexFormatUShort4;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32:
|
||||
return MTL::VertexFormatUInt;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32:
|
||||
return MTL::VertexFormatUInt2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
|
||||
return MTL::VertexFormatUInt3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
|
||||
return MTL::VertexFormatUInt4;
|
||||
case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
|
||||
return MTL::VertexFormatInvalid; // TODO: emulate
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::SInt:
|
||||
case Maxwell::VertexAttribute::Type::SScaled:
|
||||
switch (size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_A8:
|
||||
return MTL::VertexFormatChar;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8:
|
||||
case Maxwell::VertexAttribute::Size::Size_G8_R8:
|
||||
return MTL::VertexFormatChar2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
|
||||
return MTL::VertexFormatChar3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
|
||||
return MTL::VertexFormatChar4;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
return MTL::VertexFormatShort;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
return MTL::VertexFormatShort2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
return MTL::VertexFormatShort3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return MTL::VertexFormatShort4;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32:
|
||||
return MTL::VertexFormatInt;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32:
|
||||
return MTL::VertexFormatInt2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
|
||||
return MTL::VertexFormatInt3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
|
||||
return MTL::VertexFormatInt4;
|
||||
case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
|
||||
return MTL::VertexFormatInvalid; // TODO: emulate
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::Float:
|
||||
switch (size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
return MTL::VertexFormatHalf;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
return MTL::VertexFormatHalf2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
return MTL::VertexFormatHalf3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return MTL::VertexFormatHalf4;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32:
|
||||
return MTL::VertexFormatFloat;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32:
|
||||
return MTL::VertexFormatFloat2;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
|
||||
return MTL::VertexFormatFloat3;
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
|
||||
return MTL::VertexFormatFloat4;
|
||||
case Maxwell::VertexAttribute::Size::Size_B10_G11_R11:
|
||||
return MTL::VertexFormatInvalid; // TODO: emulate
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return MTL::VertexFormatInvalid;
|
||||
})()};
|
||||
|
||||
if (format == MTL::VertexFormatInvalid) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented vertex format of type={} and size={}", type, size);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
} // namespace Metal::MaxwellToMTL
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "video_core/shader_notify.h"
|
||||
#include "video_core/texture_cache/texture_cache.h"
|
||||
#include "video_core/texture_cache/texture_cache_base.h"
|
||||
#include "video_core/renderer_metal/maxwell_to_mtl.h"
|
||||
|
||||
namespace Metal {
|
||||
namespace {
|
||||
|
@ -56,7 +57,6 @@ GraphicsPipeline::GraphicsPipeline(const Device& device_, CommandRecorder& comma
|
|||
LOG_DEBUG(Render_Metal, "framebuffer not available");
|
||||
return;
|
||||
}
|
||||
MakePipeline(framebuffer->GetHandle());
|
||||
}
|
||||
|
||||
void GraphicsPipeline::Configure(bool is_indexed) {
|
||||
|
@ -203,16 +203,47 @@ void GraphicsPipeline::Configure(bool is_indexed) {
|
|||
}
|
||||
command_recorder.BeginOrContinueRenderPass(framebuffer->GetHandle());
|
||||
|
||||
MakePipeline(framebuffer->GetHandle());
|
||||
command_recorder.SetRenderPipelineState(pipeline_state);
|
||||
}
|
||||
|
||||
void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
|
||||
MTL::RenderPipelineDescriptor* pipeline_descriptor =
|
||||
const auto& regs{maxwell3d->regs};
|
||||
|
||||
// Shader stages
|
||||
MTL::RenderPipelineDescriptor* desc =
|
||||
MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
pipeline_descriptor->setVertexFunction(functions[0]);
|
||||
pipeline_descriptor->setFragmentFunction(functions[4]);
|
||||
// pipeline_descriptor->setVertexDescriptor(vertex_descriptor);
|
||||
// TODO: get the attachment count from render pass descriptor
|
||||
desc->setVertexFunction(functions[0]);
|
||||
desc->setFragmentFunction(functions[4]);
|
||||
|
||||
// Vertex descriptor
|
||||
MTL::VertexDescriptor* vertex_descriptor = MTL::VertexDescriptor::alloc()->init();
|
||||
for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||
const auto& array = regs.vertex_streams[index];
|
||||
if (!array.enable)
|
||||
continue;
|
||||
|
||||
ASSERT(index < MAX_BUFFERS);
|
||||
|
||||
// TODO: instancing
|
||||
auto layout = vertex_descriptor->layouts()->object(index);
|
||||
layout->setStride(array.stride.Value());
|
||||
}
|
||||
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||
const auto& input = regs.vertex_attrib_format[index];
|
||||
// TODO: doesn't this need some special handling?
|
||||
if (input.constant)
|
||||
continue;
|
||||
|
||||
auto attribute = vertex_descriptor->attributes()->object(index);
|
||||
attribute->setBufferIndex(input.buffer);
|
||||
attribute->setOffset(input.offset);
|
||||
attribute->setFormat(MaxwellToMTL::VertexFormat(input.type.Value(), input.size.Value()));
|
||||
}
|
||||
desc->setVertexDescriptor(vertex_descriptor);
|
||||
vertex_descriptor->release();
|
||||
|
||||
// Color attachments
|
||||
for (u32 index = 0; index < NUM_RT; index++) {
|
||||
auto* render_pass_attachment = render_pass->colorAttachments()->object(index);
|
||||
// TODO: is this the correct way to check if the attachment is valid?
|
||||
|
@ -220,13 +251,14 @@ void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
|
|||
continue;
|
||||
}
|
||||
|
||||
auto* color_attachment = pipeline_descriptor->colorAttachments()->object(index);
|
||||
auto* color_attachment = desc->colorAttachments()->object(index);
|
||||
color_attachment->setPixelFormat(render_pass_attachment->texture()->pixelFormat());
|
||||
// TODO: provide blend information
|
||||
}
|
||||
|
||||
NS::Error* error = nullptr;
|
||||
pipeline_state = device.GetDevice()->newRenderPipelineState(pipeline_descriptor, &error);
|
||||
pipeline_state = device.GetDevice()->newRenderPipelineState(desc, &error);
|
||||
desc->release();
|
||||
if (error) {
|
||||
LOG_ERROR(Render_Metal, "failed to create pipeline state: {}",
|
||||
error->description()->cString(NS::ASCIIStringEncoding));
|
||||
|
|
|
@ -118,6 +118,7 @@ private:
|
|||
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
||||
// u32 num_textures{};
|
||||
|
||||
// TODO: cache pipelines if state changes
|
||||
MTL::RenderPipelineState* pipeline_state{nullptr};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue