From 49f60adeb2d4e37dbfa91752f6113b78c9a7d568 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sat, 4 May 2024 21:09:30 +0200 Subject: [PATCH] fix: more msl errors --- .../backend/msl/emit_msl.cpp | 2 +- .../backend/msl/emit_msl_context_get_set.cpp | 16 +- .../backend/msl/emit_msl_control_flow.cpp | 2 +- .../backend/msl/emit_msl_image.cpp | 35 ++++- .../backend/msl/msl_emit_context.cpp | 137 +++++++++++------- .../backend/msl/msl_emit_context.h | 5 +- .../renderer_metal/mtl_graphics_pipeline.cpp | 4 +- .../renderer_metal/mtl_pipeline_cache.cpp | 8 +- 8 files changed, 139 insertions(+), 70 deletions(-) diff --git a/src/shader_recompiler/backend/msl/emit_msl.cpp b/src/shader_recompiler/backend/msl/emit_msl.cpp index 7a7502f9af..86d3008daa 100644 --- a/src/shader_recompiler/backend/msl/emit_msl.cpp +++ b/src/shader_recompiler/backend/msl/emit_msl.cpp @@ -155,7 +155,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { break; case IR::AbstractSyntaxNode::Type::Return: case IR::AbstractSyntaxNode::Type::Unreachable: - ctx.Add("return;"); + ctx.Add("return __out;"); break; case IR::AbstractSyntaxNode::Type::Loop: ctx.Add("for(;;){{"); diff --git a/src/shader_recompiler/backend/msl/emit_msl_context_get_set.cpp b/src/shader_recompiler/backend/msl/emit_msl_context_get_set.cpp index dd1b150109..3bae4c5cac 100644 --- a/src/shader_recompiler/backend/msl/emit_msl_context_get_set.cpp +++ b/src/shader_recompiler/backend/msl/emit_msl_context_get_set.cpp @@ -37,7 +37,7 @@ std::string_view OutputVertexIndex(EmitContext& ctx) { std::string ChooseCbuf(EmitContext& ctx, const IR::Value& binding, std::string_view index) { if (binding.IsImmediate()) { - return fmt::format("{}_cbuf{}[{}]", ctx.stage_name, binding.U32(), index); + return fmt::format("{}_cbuf{}.data[{}]", ctx.stage_name, binding.U32(), index); } else { const auto binding_var{ctx.var_alloc.Consume(binding)}; return fmt::format("GetCbufIndirect({},{})", binding_var, index); @@ -151,7 +151,7 @@ void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding const IR::Value& offset) { const auto cast{ctx.profile.has_gl_cbuf_ftou_bug ? "" : "as_type"}; if (offset.IsImmediate()) { - const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())}; + const auto cbuf{fmt::format("{}_cbuf{}.data", ctx.stage_name, binding.U32())}; static constexpr u32 cbuf_size{0x10000}; const u32 u32_offset{offset.U32()}; const s32 signed_offset{static_cast(offset.U32())}; @@ -213,7 +213,7 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, case IR::Attribute::PositionY: case IR::Attribute::PositionZ: case IR::Attribute::PositionW: { - ctx.AddF32("{}={}.{};", inst, "__out.position", swizzle); + ctx.AddF32("{}={}.{};", inst, "__in.position", swizzle); break; } case IR::Attribute::PointSpriteS: @@ -225,10 +225,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle); break; case IR::Attribute::InstanceId: - ctx.AddF32("{}=as_type(gl_InstanceID);", inst); + ctx.AddF32("{}=as_type(iid);", inst); break; case IR::Attribute::VertexId: - ctx.AddF32("{}=as_type(gl_VertexID);", inst); + ctx.AddF32("{}=as_type(vid);", inst); break; case IR::Attribute::FrontFace: ctx.AddF32("{}=as_type(gl_FrontFacing?-1:0);", inst); @@ -253,10 +253,10 @@ void EmitGetAttributeU32(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, s ctx.AddU32("{}=uint(gl_PrimitiveID);", inst); break; case IR::Attribute::InstanceId: - ctx.AddU32("{}=uint(gl_InstanceID);", inst); + ctx.AddU32("{}=uint(iid);", inst); break; case IR::Attribute::VertexId: - ctx.AddU32("{}=uint(gl_VertexID);", inst); + ctx.AddU32("{}=uint(vid);", inst); break; case IR::Attribute::BaseInstance: ctx.AddU32("{}=uint(gl_BaseInstance);", inst); @@ -396,7 +396,7 @@ void EmitSetPatch(EmitContext& ctx, IR::Patch patch, std::string_view value) { void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, std::string_view value) { const char swizzle{"xyzw"[component]}; - ctx.Add("frag_color{}.{}={};", index, swizzle, value); + ctx.Add("__out.color{}.{}={};", index, swizzle, value); } void EmitSetSampleMask(EmitContext& ctx, std::string_view value) { diff --git a/src/shader_recompiler/backend/msl/emit_msl_control_flow.cpp b/src/shader_recompiler/backend/msl/emit_msl_control_flow.cpp index e5d1e11a7f..db4b6b10d0 100644 --- a/src/shader_recompiler/backend/msl/emit_msl_control_flow.cpp +++ b/src/shader_recompiler/backend/msl/emit_msl_control_flow.cpp @@ -12,7 +12,7 @@ void EmitJoin(EmitContext&) { } void EmitDemoteToHelperInvocation(EmitContext& ctx) { - ctx.Add("discard;"); + ctx.Add("discard_fragment();"); } } // namespace Shader::Backend::MSL diff --git a/src/shader_recompiler/backend/msl/emit_msl_image.cpp b/src/shader_recompiler/backend/msl/emit_msl_image.cpp index efa9cf4017..7d0c945686 100644 --- a/src/shader_recompiler/backend/msl/emit_msl_image.cpp +++ b/src/shader_recompiler/backend/msl/emit_msl_image.cpp @@ -18,6 +18,26 @@ std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info, const IR: return fmt::format("tex{}{}", def.binding, index_offset); } +void TransformTextureCoords(const IR::TextureInstInfo& info, std::string_view& coords) { + // If the texture is array, the last component of the coords is the array index + if (info.type == TextureType::ColorArray1D) { + coords = fmt::format("{}.x,{}.y", coords, coords); + } + if (info.type == TextureType::ColorArray2D) { + coords = fmt::format("{}.xy,{}.z", coords, coords); + } + if (info.type == TextureType::ColorArrayCube) { + coords = fmt::format("{}.xyz,{}.w", coords, coords); + } +} + +std::string Sampler(EmitContext& ctx, const IR::TextureInstInfo& info, const IR::Value& index) { + const auto def{info.type == TextureType::Buffer ? ctx.texture_buffers.at(info.descriptor_index) + : ctx.textures.at(info.descriptor_index)}; + const auto index_offset{def.count > 1 ? fmt::format("[{}]", ctx.var_alloc.Consume(index)) : ""}; + return fmt::format("samp{}{}", def.binding, index_offset); +} + std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, const IR::Value& index) { const auto def{info.type == TextureType::Buffer ? ctx.image_buffers.at(info.descriptor_index) : ctx.images.at(info.descriptor_index)}; @@ -160,6 +180,7 @@ std::string ImageGatherSubpixelOffset(const IR::TextureInstInfo& info, std::stri } } // Anonymous namespace +// TODO void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, std::string_view coords, std::string_view bias_lc, const IR::Value& offset) { @@ -168,6 +189,8 @@ void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu throw NotImplementedException("EmitImageSampleImplicitLod Lod clamp samples"); } const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); + const auto sampler{Sampler(ctx, info, index)}; const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; const auto texel{ctx.var_alloc.Define(inst, MslVarType::F32x4)}; const auto sparse_inst{PrepareSparse(inst)}; @@ -186,9 +209,10 @@ void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu } } else { if (ctx.stage == Stage::Fragment) { - ctx.Add("{}=texture({},{}{});", texel, texture, coords, bias); + // TODO: is the array index correct + ctx.Add("{}={}.sample({},{}{});", texel, texture, sampler, coords, bias); } else { - ctx.Add("{}=textureLod({},{},0.0);", texel, texture, coords); + ctx.Add("{}={}.sampleLod({},{},0.0);", texel, texture, sampler, coords); } } return; @@ -213,6 +237,7 @@ void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu throw NotImplementedException("EmitImageSampleExplicitLod Lod clamp samples"); } const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const auto texel{ctx.var_alloc.Define(inst, MslVarType::F32x4)}; const auto sparse_inst{PrepareSparse(inst)}; const bool supports_sparse{ctx.profile.support_gl_sparse_textures}; @@ -254,6 +279,7 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: throw NotImplementedException("EmitImageSampleDrefImplicitLod Lod clamp samples"); } const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; const auto cast{needs_shadow_ext ? "float4" : "float3"}; @@ -309,6 +335,7 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); } const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext}; const auto cast{needs_shadow_ext ? "float3" : "float3"}; @@ -348,6 +375,7 @@ void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, std::string_view coords, const IR::Value& offset, const IR::Value& offset2) { const auto info{inst.Flags()}; const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const auto texel{ctx.var_alloc.Define(inst, MslVarType::F32x4)}; const auto sparse_inst{PrepareSparse(inst)}; const bool supports_sparse{ctx.profile.support_gl_sparse_textures}; @@ -402,6 +430,7 @@ void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde std::string_view dref) { const auto info{inst.Flags()}; const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const auto texel{ctx.var_alloc.Define(inst, MslVarType::F32x4)}; const auto sparse_inst{PrepareSparse(inst)}; const bool supports_sparse{ctx.profile.support_gl_sparse_textures}; @@ -459,6 +488,7 @@ void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, throw NotImplementedException("EmitImageFetch Lod clamp samples"); } const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const auto sparse_inst{PrepareSparse(inst)}; const auto texel{ctx.var_alloc.Define(inst, MslVarType::F32x4)}; const bool supports_sparse{ctx.profile.support_gl_sparse_textures}; @@ -552,6 +582,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, throw NotImplementedException("EmitImageGradient offset"); } const auto texture{Texture(ctx, info, index)}; + TransformTextureCoords(info, coords); const auto texel{ctx.var_alloc.Define(inst, MslVarType::F32x4)}; const bool multi_component{info.num_derivatives > 1 || info.has_lod_clamp}; const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; diff --git a/src/shader_recompiler/backend/msl/msl_emit_context.cpp b/src/shader_recompiler/backend/msl/msl_emit_context.cpp index 75716081ba..1027d3ff03 100644 --- a/src/shader_recompiler/backend/msl/msl_emit_context.cpp +++ b/src/shader_recompiler/backend/msl/msl_emit_context.cpp @@ -6,6 +6,7 @@ #include "shader_recompiler/backend/msl/msl_emit_context.h" #include "shader_recompiler/frontend/ir/program.h" #include "shader_recompiler/profile.h" + #include "shader_recompiler/runtime_info.h" namespace Shader::Backend::MSL { @@ -18,6 +19,8 @@ char Swizzle(size_t offset) { return "xyzw"[CbufIndex(offset)]; } +// TODO +/* std::string_view InterpDecorator(Interpolation interp) { switch (interp) { case Interpolation::Smooth: @@ -29,8 +32,10 @@ std::string_view InterpDecorator(Interpolation interp) { } throw InvalidArgument("Invalid interpolation {}", interp); } +*/ // TODO +/* std::string_view InputArrayDecorator(Stage stage) { switch (stage) { case Stage::Geometry: @@ -41,6 +46,7 @@ std::string_view InputArrayDecorator(Stage stage) { return ""; } } +*/ // TODO std::string OutputDecorator(Stage stage, u32 size) { @@ -208,13 +214,13 @@ std::string_view ImageFormatString(ImageFormat format) { std::string_view ImageAccessQualifier(bool is_written, bool is_read) { if (is_written && is_read) { - return "access::read, access::write"; + return ",access::read,access::write"; } if (is_written) { - return "access::write"; + return ",access::write"; } if (is_read) { - return "access::read"; + return ",access::read"; } return ""; } @@ -258,71 +264,98 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile // SetupOutPerVertex(*this, header); // SetupInPerVertex(*this, header); + // Stage input + bool has_stage_input{}; + header += "struct __Input {\n"; + if (stage == Stage::Fragment) { + header += "float4 position [[position]];\n"; + has_stage_input = true; + } for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { if (!info.loads.Generic(index) || !runtime_info.previous_stage_stores.Generic(index)) { continue; } - const auto qualifier{uses_geometry_passthrough ? "passthrough" - : fmt::format("location={}", index)}; - header += fmt::format("layout({}){}in vec4 in_attr{}{};", qualifier, - InterpDecorator(info.interpolation[index]), index, - InputArrayDecorator(stage)); + DefineStageInOut(index, program.invocations, true); + has_stage_input = true; } for (size_t index = 0; index < info.uses_patches.size(); ++index) { + // TODO: what is this if (!info.uses_patches[index]) { continue; } - const auto qualifier{stage == Stage::TessellationControl ? "out" : "in"}; - header += fmt::format("layout(location={})patch {} vec4 patch{};", index, qualifier, index); + // TODO: implement + } + header += "};\n"; + + if (has_stage_input) { + input_str = "__Input __in [[stage_in]]"; + has_at_least_one_input = true; + } + if (stage == Stage::VertexA || stage == Stage::VertexB) { + // TODO: don't always declare these + if (has_at_least_one_input) + input_str += ","; + input_str += "uint vid [[vertex_id]]"; + has_at_least_one_input = true; + + if (has_at_least_one_input) + input_str += ","; + input_str += "uint iid [[instance_id]]"; + has_at_least_one_input = true; + } + + // Stage output + header += "struct __Output {\n"; + if (stage == Stage::VertexB || stage == Stage::Geometry) { + header += "float4 position [[position]];\n"; } if (stage == Stage::Fragment) { for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) { continue; } - header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); + header += fmt::format("float4 color{} [[color({})]];", index, index); } } - header += "struct __Output {\n"; - if (stage == Stage::VertexB || stage == Stage::Geometry) { - header += "float4 position [[position]];\n"; - } for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { if (info.stores.Generic(index)) { - DefineGenericOutput(index, program.invocations); + DefineStageInOut(index, program.invocations, false); } } header += "};\n"; - bool added = DefineInputs(bindings); + DefineInputs(bindings); if (info.uses_rescaling_uniform) { - if (added) + if (has_at_least_one_input) input_str += ","; input_str += "constant float4& scaling"; - added = true; + has_at_least_one_input = true; } if (info.uses_render_area) { - if (added) + if (has_at_least_one_input) input_str += ","; input_str += "constant float4& render_area"; - added = true; + has_at_least_one_input = true; } DefineHelperFunctions(); DefineConstants(); } -bool EmitContext::DefineInputs(Bindings& bindings) { - bool added{false}; - +void EmitContext::DefineInputs(Bindings& bindings) { // Constant buffers for (const auto& desc : info.constant_buffer_descriptors) { const u32 cbuf_used_size{Common::DivCeil(info.constant_buffer_used_sizes[desc.index], 16U)}; const u32 cbuf_binding_size{info.uses_global_memory ? 0x1000U : cbuf_used_size}; - if (added) + + const std::string cbuf_struct_name{fmt::format("{}_cbuf{}_t", stage_name, desc.index)}; + header += + fmt::format("struct {} {{float4 data[{}];}};\n", cbuf_struct_name, cbuf_binding_size); + + if (has_at_least_one_input) input_str += ","; - input_str += fmt::format("constant float4& {}_cbuf{}[{}] [[buffer({})]]", stage_name, - desc.index, cbuf_binding_size, bindings.uniform_buffer); + input_str += fmt::format("constant {}& {}_cbuf{} [[buffer({})]]", cbuf_struct_name, + stage_name, desc.index, bindings.uniform_buffer); bindings.uniform_buffer += desc.count; - added = true; + has_at_least_one_input = true; } // Constant buffer indirect @@ -331,13 +364,14 @@ bool EmitContext::DefineInputs(Bindings& bindings) { // Storage space buffers u32 index{}; for (const auto& desc : info.storage_buffers_descriptors) { - if (added) + if (has_at_least_one_input) input_str += ","; - input_str += fmt::format("device uint& {}_ssbo{}[] [[buffer({})]]", stage_name, index, - bindings.storage_buffer); - bindings.storage_buffer += desc.count; + const std::string address_space{desc.is_written ? "device" : "constant"}; + input_str += fmt::format("{} uint* {}_ssbo{} [[buffer({})]]", address_space, stage_name, + index, bindings.uniform_buffer); + bindings.uniform_buffer += desc.count; index += desc.count; - added = true; + has_at_least_one_input = true; } // Images @@ -350,24 +384,24 @@ bool EmitContext::DefineInputs(Bindings& bindings) { const auto qualifier{ImageAccessQualifier(desc.is_written, desc.is_read)}; const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; input_str += fmt::format("layout(binding={}{}) uniform {}uimageBuffer img{}{};", - bindings.image, format, qualifier, bindings.image, array_decorator); - bindings.image += desc.count; + bindings.image, format, qualifier, bindings.image, + array_decorator); bindings.image += desc.count; } */ images.reserve(info.image_descriptors.size()); for (const auto& desc : info.image_descriptors) { - images.push_back({bindings.image, desc.count}); + images.push_back({bindings.texture, desc.count}); // TODO: do we need format? // const auto format{ImageFormatString(desc.format)}; const auto image_type{ImageType(desc.type)}; const auto qualifier{ImageAccessQualifier(desc.is_written, desc.is_read)}; const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; - if (added) + if (has_at_least_one_input) input_str += ","; - input_str += fmt::format("{}<{}> {}_img{}{} [[texture({})]]", qualifier, image_type, - stage_name, bindings.image, array_decorator, bindings.image); - bindings.image += desc.count; - added = true; + input_str += fmt::format("{} img{}{} [[texture({})]]", qualifier, image_type, + bindings.texture, array_decorator, bindings.texture); + bindings.texture += desc.count; + has_at_least_one_input = true; } // Textures @@ -389,28 +423,26 @@ bool EmitContext::DefineInputs(Bindings& bindings) { const auto texture_type{desc.is_depth ? DepthSamplerType(desc.type) : ColorSamplerType(desc.type, desc.is_multisample)}; const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; - if (added) + if (has_at_least_one_input) input_str += ","; - input_str += fmt::format("{} {}_tex{}{} [[texture({})]]", texture_type, stage_name, - bindings.texture, array_decorator, bindings.texture); - input_str += fmt::format(",sampler {}_samp{}{} [[sampler({})]]", stage_name, + input_str += fmt::format("{} tex{}{} [[texture({})]]", texture_type, bindings.texture, array_decorator, bindings.texture); + input_str += fmt::format(",sampler samp{}{} [[sampler({})]]", bindings.texture, + array_decorator, bindings.texture); bindings.texture += desc.count; - added = true; + has_at_least_one_input = true; } - - return added; } // TODO -void EmitContext::DefineGenericOutput(size_t index, u32 invocations) { +void EmitContext::DefineStageInOut(size_t index, u32 invocations, bool is_input) { const auto type{fmt::format("float{}", 4)}; std::string name{fmt::format("attr{}", index)}; header += fmt::format("{} {}{} [[user(locn{})]];\n", type, name, OutputDecorator(stage, invocations), index); const GenericElementInfo element_info{ - .name = "__out." + name, + .name = (is_input ? "__in." : "__out.") + name, .first_element = 0, .num_components = 4, }; @@ -418,6 +450,9 @@ void EmitContext::DefineGenericOutput(size_t index, u32 invocations) { } void EmitContext::DefineHelperFunctions() { + header += + "uint bitfieldExtract(uint value, int offset, int bits) {\nreturn (value >> offset) & " + "((1 << bits) - 1);\n}\n"; if (info.uses_global_increment || info.uses_shared_increment) { header += "uint CasIncrement(uint op_a,uint op_b){return op_a>=op_b?0u:(op_a+1u);}"; } @@ -497,7 +532,7 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { const auto& ssbo{info.storage_buffers_descriptors[index]}; const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; - const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)}; + const auto cbuf{fmt::format("{}_cbuf{}.data", stage_name, ssbo.cbuf_index)}; std::array addr_xy; std::array size_xy; for (size_t i = 0; i < addr_xy.size(); ++i) { diff --git a/src/shader_recompiler/backend/msl/msl_emit_context.h b/src/shader_recompiler/backend/msl/msl_emit_context.h index 830e97ce9a..df00489cc2 100644 --- a/src/shader_recompiler/backend/msl/msl_emit_context.h +++ b/src/shader_recompiler/backend/msl/msl_emit_context.h @@ -145,6 +145,7 @@ public: Stage stage{}; std::string_view stage_name = "invalid"; + bool has_at_least_one_input{}; std::vector texture_buffers; std::vector image_buffers; @@ -160,8 +161,8 @@ public: private: // TODO: break down into smaller functions - bool DefineInputs(Bindings& bindings); - void DefineGenericOutput(size_t index, u32 invocations); + void DefineInputs(Bindings& bindings); + void DefineStageInOut(size_t index, u32 invocations, bool is_input); void DefineHelperFunctions(); void DefineConstants(); std::string DefineGlobalMemoryFunctions(); diff --git a/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp b/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp index deb9c66109..91716d085a 100644 --- a/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp +++ b/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp @@ -139,9 +139,9 @@ void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) { MTL::RenderPipelineDescriptor* pipeline_descriptor = MTL::RenderPipelineDescriptor::alloc()->init(); pipeline_descriptor->setVertexFunction(functions[0]); - pipeline_descriptor->setFragmentFunction(functions[1]); + pipeline_descriptor->setFragmentFunction(functions[4]); // pipeline_descriptor->setVertexDescriptor(vertex_descriptor); - // TODO: get the attachment count from render pass descriptor + // TODO: get the attachment count from render pass descriptor 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? diff --git a/src/video_core/renderer_metal/mtl_pipeline_cache.cpp b/src/video_core/renderer_metal/mtl_pipeline_cache.cpp index b52da74356..012b58e017 100644 --- a/src/video_core/renderer_metal/mtl_pipeline_cache.cpp +++ b/src/video_core/renderer_metal/mtl_pipeline_cache.cpp @@ -268,6 +268,7 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( ConvertLegacyToGeneric(program, runtime_info); const std::string code{EmitMSL(profile, runtime_info, program, binding)}; // HACK + std::cout << "SHADER INDEX: " << index - 1 << std::endl; std::cout << code << std::endl; MTL::CompileOptions* compile_options = MTL::CompileOptions::alloc()->init(); NS::Error* error = nullptr; @@ -276,12 +277,13 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( if (error) { LOG_ERROR(Render_Metal, "failed to create library: {}", error->description()->cString(NS::ASCIIStringEncoding)); - // std::cout << error->description()->cString(NS::ASCIIStringEncoding) << std::endl; + // HACK + std::cout << error->description()->cString(NS::ASCIIStringEncoding) << std::endl; // HACK throw; } - functions[index] = + functions[index - 1] = library->newFunction(NS::String::string("main_", NS::ASCIIStringEncoding)); previous_stage = &program; } @@ -326,7 +328,7 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( } functions[0] = library->newFunction(NS::String::string("vertexMain", NS::ASCIIStringEncoding)); - functions[1] = + functions[4] = library->newFunction(NS::String::string("fragmentMain", NS::ASCIIStringEncoding)); return std::make_unique(device, command_recorder, key, buffer_cache,