Post

Replies

Boosts

Views

Activity

Is supersampling available?
Multisampling is pretty well-covered, including under its own heading in the documentation for MTLRenderPipelineDescriptor - https://developer.apple.com/documentation/metal/mtlrenderpipelinedescriptor and that's all fairly straightforward. But multisampling usually means that only a limit subset of things is sampled multiple times — in a typical implementation, depth, stencil and inclusion tests are run at the higher resolution but the fragment shader is performed only at the target output resolution. So you reduce aliasing around things like edges but polygon fills are not improved. Is that what Metal considers to be multisampling and, if so, is true supersampling available, in which everything including the fragment shader occurs at a higher frequency? If it helps as to motivation, you can imagine my app as presenting a 2d framebuffer that does not necessarily match the output display's resolution or pixel aspect ratio. So I want some filtering on the internal pixels and if a fixed hardware solution is available then that's definitely worth exploring. Mine is an app that does partial updates of its display and it uses an MTKView for output so I already have a texture that keeps the current state of the backing buffer that I simply copy to the front. For the time being I'm doing a poor-man's supersampling by just maintaining that at twice the width and height of the target output and linearly sampling for output. Since it isn't MIP mapped each fragment falls exactly between four pixels and I get a 2x2 box filter from a single sampling. That's not terrible, but on a lot of hardware supersampling is implemented with a more nuanced sampling grid so real hardware supersampling would likely be a good first improvement.
0
0
826
Sep ’20
Running a compute shader over only a subregion of a texture
As per the title, I wish to use a compute shader, but run it only over a rectangular subregion of a texture. The textures are currently marked as MTLResourceStorageModePrivate since that best represents their intended use. Seeming dead ends already explored: setStageInRegion: is barely documented and it's unclear to me what purpose it has, but I assume it relates to per-thread kernel inputs, since that's what you'd mark as [[stage_in]], so that's something else; texture views seem to vary only in pixel format and layout, there's no obvious way to create a texture view that is a subregion of another texture; neither of the dispatch functions on MTLComputeCommandEncoder take a region; there is similarly nothing obvious in MTLComputePipelineState, or indeed in MTLComputePassDescriptor. Is what I want to do supported? It'd be a real hassle to have to cram myself into a 1:1 render pass just to get this functionality. EDIT: I guess I could adjust the number of threadgroups I dispatch to set a size and then provide an offset via a buffer, adding that to whatever comes out of my gid before accessing the source and destination. But is that within the bounds of intended usage of compute shaders?
2
0
1.1k
Sep ’20
MTLVertexDescriptor being ignored
I'm new to Metal; humour me. I have the following in my .metal file: struct InputVertex { float2 position [[attribute(0)]]; float3 colour [[attribute(1)]]; }; In my code I therefore build an MTLVertexDescriptor as follows: MTLVertexDescriptor *vertexDescriptor = [[MTLVertexDescriptor alloc] init]; // Position. vertexDescriptor.attributes[0].bufferIndex = 0; vertexDescriptor.attributes[0].offset = 0; vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // Colour. vertexDescriptor.attributes[1].bufferIndex = 0; vertexDescriptor.attributes[1].offset = sizeof(float)*2; vertexDescriptor.attributes[1].format = MTLVertexFormatFloat3; // Total vertex size. vertexDescriptor.layouts[0].stride = sizeof(float)*5; I then create a pipeline descriptor, set appropriate vertex and fragment functions and set that vertexDescriptor. I'm just playing around with absolute basics right now, so I have a hand-written array of float that starts with: constexpr float vertices[] = { -0.9f, -0.9f, // Position. 1.0f, 0.0f, 0.0f, // Colour. ... and continues with three other vertices, eventually to form a rectangle via MTLPrimitiveTypeTriangleStrip. So I also create a buffer and copy vertices into that. Rendering does not produce what I expect. And when I capture a GPU frame I can see why. Metal is using the above and is then: treating my layout stride as 32 bytes, which is notably different from the 20 that I specified; and assuming that the colour attribute begins 16 bytes into each vertex, not the 8 that I've specified. i.e. it is as if I had used two float4s and declared my descriptor accordingly. My actual values seem to be acceptable per the documentation which requires only 4-byte alignment for each attribute. I actually had originally declared my InputVertex as two float4s but I've cleaned the whole project and rebuilt, even shutting Xcode and restarted the computer so if there's some sort of broken caching here then any advice as to a workaround would be welcome. My paranoia on that has extended to step debugging and confirming the values written to each MTLVertexAttributeDescriptor; they are as above. Can anyone give me any insight as to why my MTLVertexDescriptor is being either ignored or heavily modified? If this is a case where you're supposed to ask for what you want then work with what you get, how am I supposed to find out what I got?
1
0
606
Aug ’20