如何在 Metal 中为给定的缓冲区索引创建参数缓冲区?

问题描述 投票:0回答:0

我正在使用 Metal-CPP 并尝试使用参数缓冲区使数据可用于以下着色器:

#include <metal_stdlib>

using namespace metal;

struct Vertex
{
    packed_float3 position;
    packed_float3 normal;
    packed_float2 texCoord0;
    packed_float2 texCoord1;
};

struct VertexOutput {
    float4 outPosition [[position]];
    float3 outNormal;
    float4 lightSpacePosition;
};

struct Constants
{
    float4x4 modelViewProjection;
    float4x4 lightSpaceModelViewProjection;
};

struct ArgumentBuffer2
{
    depth2d<float> shadowMap    [[id(0)]];
    sampler depthSampler        [[id(1)]];
};

struct DrawUBO {
    packed_float3 lightPosition;
};

struct ArgumentBuffer
{
    device DrawUBO* drawUBO   [[id(0)]];
};

vertex VertexOutput vertex_main
(
    constant Constants& constants         [[buffer(0)]],
    const device ArgumentBuffer2* globals [[buffer(1)]],
    const device ArgumentBuffer* uniforms [[buffer(2)]],
    constant Vertex* vertices             [[buffer(3)]],
    uint vid                              [[vertex_id]]
)
{
    const float4x4 biasMat = float4x4(
        0.5, 0.0, 0.0, 0.0,
        0.0, 0.5, 0.0, 0.0,
        0.0, 0.0, 1.0, 0.0,
        0.5, 0.5, 0.0, 1.0
    );

    Vertex vertexIn = vertices[vid];

    float4x4 modelViewProjection = constants.modelViewProjection;
    float4x4 lightSpaceModelViewProjection = constants.lightSpaceModelViewProjection;

    VertexOutput vertexOut;
    vertexOut.outPosition = modelViewProjection * float4(vertexIn.position, 1.0);
    vertexOut.outNormal = vertexIn.normal;
    vertexOut.lightSpacePosition = biasMat * lightSpaceModelViewProjection * float4(vertexIn.position, 1.0);
    return vertexOut;
}

fragment float4 fragment_main(
    constant Constants& constants         [[buffer(0)]],
    const device ArgumentBuffer2* globals [[buffer(1)]],
    const device ArgumentBuffer* uniforms [[buffer(2)]],
    VertexOutput vertexIn                 [[stage_in]]
)
{
   // Empty for brevity
}

以下代码行用于使用 newArgumentEncoderWithBufferIndex 创建 MTLArgumentEncoder

MTL::ArgumentEncoder* vertexArgumentEncoder = vertexShader.function->newArgumentEncoder(setIndex);

这适用于

buffer(1)
(其中
setIndex
1
)。然而,当尝试对
buffer(2)
做同样的事情时,我得到以下错误:

newArgumentEncoder:91: failed assertion `Buffer argument vertices (buffer index: 2) of function vertex_main is not an indirect argument buffer. If vertices is expected to be an argument buffer, this could be a shader bug. Argument buffers can be distinguished from regular buffers if they contain buffers, textures, samplers, or any element with the [[id]] attribute'

我已经验证了MTLFunction来自上面显示的着色器。我相信我正确地遵循了argument buffer indexing rules.

macos graphics shader metal metalkit
© www.soinside.com 2019 - 2024. All rights reserved.