I have a shader that looks like this:
struct VertexIn {
float a_customIdx [[attribute(0)]];
...
};
vertex vec4 vertex_func(VertexIn v_in [[stage_in]], ...) {...}
In my buffer I'm actually passing in a uint32_t for a_customIdx, so in my MTLVertexAttributeDescriptor I specify its type to be MTLAttributeFormatUInt. When I create the RenderPipelineState I get the error:
cannot convert attribute from MTLAttributeFormatUInt to float1
I get the same error if I use MTLAttributeFormatInt, but can successfully convert a MTLAttributeFormatUShort.
Why is this not a valid operation? According to the documentation for format, "Casting any MTLVertexFormat to a float or half is valid".
I know there are multiple ways I can get around this problem, but I'm curious about why this is invalid - perhaps there's something about alignments and byte sizes I'm missing here.
Related
I added another texture to one of my metal Kernel functions, and get the following error. I searched, and see a lot of confusion about this error.
How to solve Metal error "The pixel format of the texture is incompatible with the data type" ?
validateComputeFunctionArguments:841: failed assertion `Compute Function(screenSampleWithScreenshot):
The pixel format (MTLPixelFormatBGRA8Unorm) of the texture (name:CAMetalLayer Display Drawable)
bound at index 4 is incompatible with the data type (MTLDataTypeUInt) of the texture parameter
(myTexture [[texture(0)]]). MTLPixelFormatBGRA8Unorm is compatible with the data type(s) (
float,
half
).'
The solution is simple: metal validation has detected that your function signature is incorrect. It found unsigned int (or other unexpected) data type, while you are passing in a texture with a float color format.
kernel void myComputeFunction(
texture2d<unsigned int, access::read> integerTexture [[texture(0)]],
texture2d<unsigned int, access::read> myTexture [[texture(1)]],
//change unsigned int to float if your texture MTLPixelFormatBGRA8Unorm:
texture2d<unsigned int, access::read> integerTexture [[texture(0)]],
texture2d<float, access::read> myTexture [[texture(1)]],
)
When I'm reading the asm code ,I dont know how to get the instruction "ld" just below.
Which function should I use in HLSL to get it?
Or had it be replaced with the update of versions?
The following is asm code:
ld r0.xyzw r0.xyzw t19.xyzw
I tried to use texture2D in HLSL but when compiled it was "sample " not "ld".
ld is a Shader Model 4.0 or later instruction. Which shader profile & HLSL compiler are you using?
The Load member of a texture object is typically how you do this in modern HLSL.
Texture2D<float4> g_Input : register( t0 );
float4 pixel = g_Input.Load(...);
validateFunctionArguments:3379: failed assertion `Fragment Function(ca_uber_fragment_lp0_cp1_fo0): The pixel format (MTLPixelFormatRGBA16Unorm) of the texture (name:) bound at index 0 is incompatible with the data type (MTLDataTypeHalf) of the texture parameter (img_tex_0A [[texture(0)]]). MTLPixelFormatRGBA16Unorm is compatible with the data type(s) (
float
).'
When I run my project on iPhone 8, I got this crash error, someone adviced me to set "edit scheme - Options - Metal API Validation" disabled, and It really can solve it, But I do not know why ? so I'm looking forward to you give me some suggestions, Thanks.
Try to set colorPixelFormat = .bgra8Unorm for your MTLView and MTLRenderPipelineState
In the metal function, you have one of two options - try changing the texture type from float to half or from half to float.
texture2d<float, access::read> myTexture [[texture(0)]]
texture2d<half, access::read> myTexture [[texture(0)]]
I'm trying to include a header file in a metal shader.
For a prototype like this,
float4 someFunction(float4 v);
I get this error message,
Unknown type name 'float4'; did you mean 'float'?
It seems it doesn't understand it's a header for a shader program... Although other errors suggest it does. For instance, if I don't specify the address space here,
static float someK = 2.0;
I get this error,
Global variables must have a constant address space qualifier
which can be fixed if I add
constant static float someK = 2.0;
If I use references, I also get these type of errors,
Reference type must include device, threadgroup, constant, or thread address space qualifier
So it does look as if the compiler knows it's a shader. Why it doesn't know about float4? :(
Make sure you have the first two lines in your shader like in this example:
#include <metal_stdlib>
using namespace metal;
float4 someFunction(float4 v);
kernel void compute(texture2d<float, access::write> output [[texture(0)]],
uint2 gid [[thread_position_in_grid]])
{
float4 color = float4(0, 0.5, 0.5, 1);
output.write(color, gid);
}
This works fine for me.
Try using
vector_float4
instead.
I have the following fragment shader:
precision highp float;
varying highp vec2 vTexCoord;
uniform sampler2D uColorTexture;
void main () {
highp vec4 tmp;
tmp = ((texture2D (uColorTexture, vTexCoord) + texture2D (uColorTexture, vTexCoord)) / 2.0);
gl_FragColor = tmp;
}
I know this shader does not make much sense but it should still run correct and I try to reproduce a problem with it. When I analyze this shader with the Xcode OpenGL-ES analyzer it shows an error:
Overflow in implicit conversion, minimum range for lowp float is
(-2,2)
and it not only shows this error, also the rendering output is broken do to overflows. So it's not just a false positive from the analyzer it actually overflows.
Can anyone explain to me why dis produces an overflow although I chose highp everywhere?
You didn't really choose highp everywhere; from the GLSL ES spec chapter 8 (Built-in Functions):
Precision qualifiers for parameters and return values are not shown. For the texture functions, the precision of the return type matches the precision of the sampler type.
and from 4.5.3 (Default Precision Qualifiers):
The fragment language has the following predeclared globally scoped default precision statements: ... precision lowp sampler2D; ...
Which means that in your code texture2D (uColorTexture, vTexCoord) will return a lowp, you are adding two of them, potentially resulting in a value of 2.0.
From 4.5.2 (Precision Qualifiers):
The required minimum ranges and precisions for precision qualifiers are: ... lowp (−2,2) ...
The parentheses in (-2,2) indicate an open range, meaning it includes values up to (but not including) 2.
So I think the fact that you're adding two lowp's together means you're overflowing. Try changing that line to:
tmp = texture2D(uColorTexture, vTexCoord)/2.0 + texture2D(uColorTexture, vTexCoord)/2.0;