iOS Metal "The pixel format of the texture is incompatible with the data type" - ios

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)]],
)

Related

how can i get the pixel shader asm code "Ld"?I'm writing HLSL

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(...);

Metal Shader vertex attributes - cannot convert attribute from MTLAttributeFormatUInt to float1

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.

validateFunctionArguments:3379: failed assertion `Fragment Function , The pixel format (MTLPixelFormatRGBA16Unorm) of the texture

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)]]

Metal: unknown type name float4

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.

To use the second variant of FeatureDetector on an image set

I was able to successfully load a number of images into a vector, vector<Mat>. The images once loaded in can be displayed with the imread function.
The problem is that I want to apply SIFT on this set of images using the second variant, as mentioned in the documentation:
void FeatureDetector::detect(const vector<Mat>& images, vector<vector<KeyPoint>>& keypoints, const vector<Mat>& masks=vector<Mat>() ) const
This is producing the following error:
error C2664: 'void cv::FeatureDetector::detect(const cv::Mat &,std::vector<_Ty> &,const cv::Mat &) const' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const cv::Mat &'
The code I am using:
vector<Mat> images;
/* code to add all images to vector not shown as its messy but it was performed with FindFirstFile of windows.h. All images loaded correctly as they can be read by imread*/
initModule_nonfree();
Ptr<FeatureDetector> get_keypoints = FeatureDetector::create("SIFT");
vector<KeyPoint> keypoints;
get_keypoints->detect(images , keypoints);
The error is detected at get_keypoints->detect(images , keypoints);
From the detect signature, keypoints should be vector<vector<KeyPoint>>, yet you declare it as vector<KeyPoint>.

Resources