Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metal argument buffers causes incorrect rendering on old iPads #2395

Open
warmenhoven opened this issue Nov 14, 2024 · 0 comments
Open

Metal argument buffers causes incorrect rendering on old iPads #2395

warmenhoven opened this issue Nov 14, 2024 · 0 comments

Comments

@warmenhoven
Copy link
Contributor

Originally from libretro/RetroArch#17163.

Here's the shader in question:

fxaa.slang:

#version 450

#include "config.inc"

#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;

void main() {
   gl_Position = global.MVP * Position;
   vTexCoord = TexCoord;
}

#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;

layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D upscale_passFeedback;

void main() {
   vec4 pixel_out;
   FragColor = texture(Source, vTexCoord);
}

config.inc:

layout(push_constant) uniform Push {
	float HALO_SHARPNESS ;
} params;

layout(std140, set = 0, binding = 0) uniform UBO {
	mat4 MVP;
} global;

If I load this on my iPhone 15 Pro running iOS 18.1, everything renders fine. However, on an iPad Air 3 (A12 Bionic based) or my old 11" iPad Pro 2nd gen (A12Z based), it causes the screen to be rendered black. If I set MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS to 0, it fixes it. If I remove the line layout(set = 0, binding = 3) uniform sampler2D upscale_passFeedback;, it also fixes it.

Here's a log of the cross-compile:

[mvk-debug] Created VkDescriptorSetLayout 0x30076b780 with 3 bindings:
	0: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER             with 1 elements at binding 0
	1: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER     with 1 elements at binding 2
	2: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER     with 1 elements at binding 3

[mvk-debug] Created VkPipelineLayout 0x11bd16e80 with 1 descriptor set layouts:
	0: 0x30076b780

[mvk-debug] Created VkDescriptorPool 0x11bed8a00 with 3 descriptor sets (reset only), and pooled descriptors:
	VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:           3  (3 remaining)
	VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:   6  (6 remaining)

[mvk-info] Converting SPIR-V:
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 38
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %4 "main" %13 %24 %31 %33
               OpSource GLSL 450
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpName %4 "main"
               OpName %11 "gl_PerVertex"
               OpMemberName %11 0 "gl_Position"
               OpMemberName %11 1 "gl_PointSize"
               OpMemberName %11 2 "gl_ClipDistance"
               OpMemberName %11 3 "gl_CullDistance"
               OpName %13 ""
               OpName %17 "UBO"
               OpMemberName %17 0 "MVP"
               OpName %19 "global"
               OpName %24 "Position"
               OpName %31 "vTexCoord"
               OpName %33 "TexCoord"
               OpName %35 "Push"
               OpMemberName %35 0 "HALO_SHARPNESS"
               OpName %37 "params"
               OpMemberDecorate %11 0 BuiltIn Position
               OpMemberDecorate %11 1 BuiltIn PointSize
               OpMemberDecorate %11 2 BuiltIn ClipDistance
               OpMemberDecorate %11 3 BuiltIn CullDistance
               OpDecorate %11 Block
               OpMemberDecorate %17 0 ColMajor
               OpMemberDecorate %17 0 Offset 0
               OpMemberDecorate %17 0 MatrixStride 16
               OpDecorate %17 Block
               OpDecorate %19 DescriptorSet 0
               OpDecorate %19 Binding 0
               OpDecorate %24 Location 0
               OpDecorate %31 Location 0
               OpDecorate %33 Location 1
               OpMemberDecorate %35 0 Offset 0
               OpDecorate %35 Block
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeFloat 32
          %7 = OpTypeVector %6 4
          %8 = OpTypeInt 32 0
          %9 = OpConstant %8 1
         %10 = OpTypeArray %6 %9
         %11 = OpTypeStruct %7 %6 %10 %10
         %12 = OpTypePointer Output %11
         %13 = OpVariable %12 Output
         %14 = OpTypeInt 32 1
         %15 = OpConstant %14 0
         %16 = OpTypeMatrix %7 4
         %17 = OpTypeStruct %16
         %18 = OpTypePointer Uniform %17
         %19 = OpVariable %18 Uniform
         %20 = OpTypePointer Uniform %16
         %23 = OpTypePointer Input %7
         %24 = OpVariable %23 Input
         %27 = OpTypePointer Output %7
         %29 = OpTypeVector %6 2
         %30 = OpTypePointer Output %29
         %31 = OpVariable %30 Output
         %32 = OpTypePointer Input %29
         %33 = OpVariable %32 Input
         %35 = OpTypeStruct %6
         %36 = OpTypePointer PushConstant %35
         %37 = OpVariable %36 PushConstant
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %21 = OpAccessChain %20 %19 %15
         %22 = OpLoad %16 %21
         %25 = OpLoad %7 %24
         %26 = OpMatrixTimesVector %7 %22 %25
         %28 = OpAccessChain %27 %13 %15
               OpStore %28 %26
         %34 = OpLoad %29 %33
               OpStore %31 %34
               OpReturn
               OpFunctionEnd

End SPIR-V

Converted MSL:
#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct UBO
{
    float4x4 MVP;
};

struct Push
{
    float HALO_SHARPNESS;
};

struct spvDescriptorSetBuffer0
{
    constant void* _m0_pad [[id(0)]];
    constant UBO* global [[id(1)]];
};

struct main0_out
{
    float2 vTexCoord [[user(locn0)]];
    float4 gl_Position [[position]];
};

struct main0_in
{
    float4 Position [[attribute(0)]];
    float2 TexCoord [[attribute(1)]];
};

vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
    main0_out out = {};
    out.gl_Position = (*spvDescriptorSet0.global).MVP * in.Position;
    out.vTexCoord = in.TexCoord;
    out.gl_Position.y = -(out.gl_Position.y);    // Invert Y-axis for Metal
    return out;
}


End MSL

Estimated original GLSL:
#version 450

out gl_PerVertex
{
    vec4 gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[1];
    float gl_CullDistance[1];
};

layout(set = 0, binding = 0, std140) uniform UBO
{
    mat4 MVP;
} global;

layout(push_constant, std430) uniform Push
{
    float HALO_SHARPNESS;
} params;

layout(location = 0) in vec4 Position;
layout(location = 0) out vec2 vTexCoord;
layout(location = 1) in vec2 TexCoord;

void main()
{
    gl_Position = global.MVP * Position;
    vTexCoord = TexCoord;
}


End GLSL


[mvk-info] Compiling Metal shader with FastMath enabled.
[mvk-info] Converting SPIR-V:
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 28
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main" %9 %17
               OpExecutionMode %4 OriginUpperLeft
               OpSource GLSL 450
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpName %4 "main"
               OpName %9 "FragColor"
               OpName %13 "Source"
               OpName %17 "vTexCoord"
               OpName %20 "Push"
               OpMemberName %20 0 "HALO_SHARPNESS"
               OpName %22 "params"
               OpName %24 "UBO"
               OpMemberName %24 0 "MVP"
               OpName %26 "global"
               OpName %27 "upscale_passFeedback"
               OpDecorate %9 Location 0
               OpDecorate %13 DescriptorSet 0
               OpDecorate %13 Binding 2
               OpDecorate %17 Location 0
               OpMemberDecorate %20 0 Offset 0
               OpDecorate %20 Block
               OpMemberDecorate %24 0 ColMajor
               OpMemberDecorate %24 0 Offset 0
               OpMemberDecorate %24 0 MatrixStride 16
               OpDecorate %24 Block
               OpDecorate %26 DescriptorSet 0
               OpDecorate %26 Binding 0
               OpDecorate %27 DescriptorSet 0
               OpDecorate %27 Binding 3
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeFloat 32
          %7 = OpTypeVector %6 4
          %8 = OpTypePointer Output %7
          %9 = OpVariable %8 Output
         %10 = OpTypeImage %6 2D 0 0 0 1 Unknown
         %11 = OpTypeSampledImage %10
         %12 = OpTypePointer UniformConstant %11
         %13 = OpVariable %12 UniformConstant
         %15 = OpTypeVector %6 2
         %16 = OpTypePointer Input %15
         %17 = OpVariable %16 Input
         %20 = OpTypeStruct %6
         %21 = OpTypePointer PushConstant %20
         %22 = OpVariable %21 PushConstant
         %23 = OpTypeMatrix %7 4
         %24 = OpTypeStruct %23
         %25 = OpTypePointer Uniform %24
         %26 = OpVariable %25 Uniform
         %27 = OpVariable %12 UniformConstant
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %14 = OpLoad %11 %13
         %18 = OpLoad %15 %17
         %19 = OpImageSampleImplicitLod %7 %14 %18
               OpStore %9 %19
               OpReturn
               OpFunctionEnd

End SPIR-V

Converted MSL:
#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Push
{
    float HALO_SHARPNESS;
};

struct UBO
{
    float4x4 MVP;
};

struct spvDescriptorSetBuffer0
{
    constant void* _m0_pad [[id(0)]];
    constant void* _m1_pad [[id(1)]];
    texture2d<float> Source [[id(2)]];
    sampler SourceSmplr [[id(3)]];
};

struct main0_out
{
    float4 FragColor [[color(0)]];
};

struct main0_in
{
    float2 vTexCoord [[user(locn0)]];
};

fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
    main0_out out = {};
    out.FragColor = spvDescriptorSet0.Source.sample(spvDescriptorSet0.SourceSmplr, in.vTexCoord);
    return out;
}


End MSL

Estimated original GLSL:
#version 450

layout(set = 0, binding = 0, std140) uniform UBO
{
    mat4 MVP;
} global;

layout(push_constant, std430) uniform Push
{
    float HALO_SHARPNESS;
} params;

layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D upscale_passFeedback;

layout(location = 0) out vec4 FragColor;
layout(location = 0) in vec2 vTexCoord;

void main()
{
    FragColor = texture(Source, vTexCoord);
}


End GLSL


[mvk-info] Compiling Metal shader with FastMath enabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant