mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-25 19:02:45 -06: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;
|
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
|
} // namespace Metal::MaxwellToMTL
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "video_core/shader_notify.h"
|
#include "video_core/shader_notify.h"
|
||||||
#include "video_core/texture_cache/texture_cache.h"
|
#include "video_core/texture_cache/texture_cache.h"
|
||||||
#include "video_core/texture_cache/texture_cache_base.h"
|
#include "video_core/texture_cache/texture_cache_base.h"
|
||||||
|
#include "video_core/renderer_metal/maxwell_to_mtl.h"
|
||||||
|
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -56,7 +57,6 @@ GraphicsPipeline::GraphicsPipeline(const Device& device_, CommandRecorder& comma
|
||||||
LOG_DEBUG(Render_Metal, "framebuffer not available");
|
LOG_DEBUG(Render_Metal, "framebuffer not available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MakePipeline(framebuffer->GetHandle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPipeline::Configure(bool is_indexed) {
|
void GraphicsPipeline::Configure(bool is_indexed) {
|
||||||
|
@ -203,16 +203,47 @@ void GraphicsPipeline::Configure(bool is_indexed) {
|
||||||
}
|
}
|
||||||
command_recorder.BeginOrContinueRenderPass(framebuffer->GetHandle());
|
command_recorder.BeginOrContinueRenderPass(framebuffer->GetHandle());
|
||||||
|
|
||||||
|
MakePipeline(framebuffer->GetHandle());
|
||||||
command_recorder.SetRenderPipelineState(pipeline_state);
|
command_recorder.SetRenderPipelineState(pipeline_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
|
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();
|
MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
pipeline_descriptor->setVertexFunction(functions[0]);
|
desc->setVertexFunction(functions[0]);
|
||||||
pipeline_descriptor->setFragmentFunction(functions[4]);
|
desc->setFragmentFunction(functions[4]);
|
||||||
// pipeline_descriptor->setVertexDescriptor(vertex_descriptor);
|
|
||||||
// TODO: get the attachment count from render pass descriptor
|
// 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++) {
|
for (u32 index = 0; index < NUM_RT; index++) {
|
||||||
auto* render_pass_attachment = render_pass->colorAttachments()->object(index);
|
auto* render_pass_attachment = render_pass->colorAttachments()->object(index);
|
||||||
// TODO: is this the correct way to check if the attachment is valid?
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* color_attachment = pipeline_descriptor->colorAttachments()->object(index);
|
auto* color_attachment = desc->colorAttachments()->object(index);
|
||||||
color_attachment->setPixelFormat(render_pass_attachment->texture()->pixelFormat());
|
color_attachment->setPixelFormat(render_pass_attachment->texture()->pixelFormat());
|
||||||
// TODO: provide blend information
|
// TODO: provide blend information
|
||||||
}
|
}
|
||||||
|
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
pipeline_state = device.GetDevice()->newRenderPipelineState(pipeline_descriptor, &error);
|
pipeline_state = device.GetDevice()->newRenderPipelineState(desc, &error);
|
||||||
|
desc->release();
|
||||||
if (error) {
|
if (error) {
|
||||||
LOG_ERROR(Render_Metal, "failed to create pipeline state: {}",
|
LOG_ERROR(Render_Metal, "failed to create pipeline state: {}",
|
||||||
error->description()->cString(NS::ASCIIStringEncoding));
|
error->description()->cString(NS::ASCIIStringEncoding));
|
||||||
|
|
|
@ -118,6 +118,7 @@ private:
|
||||||
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
||||||
// u32 num_textures{};
|
// u32 num_textures{};
|
||||||
|
|
||||||
|
// TODO: cache pipelines if state changes
|
||||||
MTL::RenderPipelineState* pipeline_state{nullptr};
|
MTL::RenderPipelineState* pipeline_state{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue