metal: initial vertex attribute support for pipelines

Also hook up samplers
This commit is contained in:
Alex Szpakowski
2020-05-03 17:14:54 -03:00
parent 9765485222
commit de041ded0e
4 changed files with 108 additions and 15 deletions
+1 -1
View File
@@ -165,7 +165,7 @@ private:
void endPass();
id<MTLDepthStencilState> getCachedDepthStencilState(const DepthState &depth, const StencilState &stencil);
void applyRenderState(id<MTLRenderCommandEncoder> renderEncoder);
void applyRenderState(id<MTLRenderCommandEncoder> renderEncoder, const vertex::Attributes &attributes);
id<MTLCommandQueue> commandQueue;
+73 -14
View File
@@ -423,7 +423,7 @@ id<MTLDepthStencilState> Graphics::getCachedDepthStencilState(const DepthState &
return state;
}
void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder)
void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder, const vertex::Attributes &attributes)
{
const uint32 pipelineStateBits = STATEBIT_SHADER | STATEBIT_BLEND | STATEBIT_COLORMASK;
@@ -492,7 +492,7 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder)
}
// TODO: attributes
if (dirtyState & pipelineStateBits)
if ((dirtyState & pipelineStateBits) != 0 || true)
{
// Shader *shader = (Shader *) state.shader.get();
Shader *shader = (Shader *) Shader::current;
@@ -502,6 +502,7 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder)
{
Shader::RenderPipelineKey key;
key.vertexAttributes = attributes;
key.blend = state.blend;
key.colorChannelMask = state.colorMask;
@@ -533,15 +534,32 @@ void Graphics::draw(const DrawCommand &cmd)
{ @autoreleasepool {
id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
applyRenderState(encoder);
applyRenderState(encoder, *cmd.attributes);
// TODO: vertex attributes
id<MTLTexture> mtltexture = (__bridge id<MTLTexture>)(void *) cmd.texture->getHandle();
id<MTLTexture> texture = (__bridge id<MTLTexture>)(void *) cmd.texture->getHandle();
[encoder setFragmentTexture:texture atIndex:0];
[encoder setFragmentTexture:mtltexture atIndex:0];
[encoder setFragmentSamplerState:((Texture *)cmd.texture)->getMTLSampler() atIndex:0];
[encoder setCullMode:MTLCullModeNone];
uint32 allbits = cmd.buffers->useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
if (cmd.buffers->useBits & bit)
{
auto b = cmd.buffers->info[i];
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)b.buffer->getHandle();
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i];
}
i++;
allbits >>= 1;
}
[encoder drawPrimitives:MTLPrimitiveTypeTriangle
vertexStart:cmd.vertexStart
vertexCount:cmd.vertexCount
@@ -552,13 +570,32 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
{ @autoreleasepool {
id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
applyRenderState(encoder);
applyRenderState(encoder, *cmd.attributes);
id<MTLTexture> texture = (__bridge id<MTLTexture>)(void *) cmd.texture->getHandle();
[encoder setFragmentTexture:texture atIndex:0];
id<MTLTexture> mtltexture = (__bridge id<MTLTexture>)(void *) cmd.texture->getHandle();
[encoder setFragmentTexture:mtltexture atIndex:0];
[encoder setFragmentSamplerState:((Texture *)cmd.texture)->getMTLSampler() atIndex:0];
[encoder setCullMode:MTLCullModeNone];
uint32 allbits = cmd.buffers->useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
if (cmd.buffers->useBits & bit)
{
auto b = cmd.buffers->info[i];
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)b.buffer->getHandle();
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i];
}
i++;
allbits >>= 1;
}
auto indexType = cmd.indexType == INDEX_UINT32 ? MTLIndexTypeUInt32 : MTLIndexTypeUInt16;
[encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
@@ -576,16 +613,34 @@ void Graphics::drawQuads(int start, int count, const vertex::Attributes &attribu
id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
applyRenderState(encoder);
applyRenderState(encoder, attributes);
id<MTLTexture> tex = (__bridge id<MTLTexture>)(void *) texture->getHandle();
[encoder setFragmentTexture:tex atIndex:0];
id<MTLTexture> mtltexture = (__bridge id<MTLTexture>)(void *) texture->getHandle();
[encoder setFragmentTexture:mtltexture atIndex:0];
[encoder setFragmentSamplerState:((Texture *)texture)->getMTLSampler() atIndex:0];
[encoder setCullMode:MTLCullModeNone];
uint32 allbits = buffers.useBits;
uint32 i = 0;
while (allbits)
{
uint32 bit = 1u << i;
if (buffers.useBits & bit)
{
auto b = buffers.info[i];
id<MTLBuffer> buffer = (__bridge id<MTLBuffer>)(void *)b.buffer->getHandle();
[encoder setVertexBuffer:buffer offset:b.offset atIndex:i];
}
i++;
allbits >>= 1;
}
id<MTLBuffer> ib = (__bridge id<MTLBuffer>)(void *) quadIndexBuffer->getHandle();
// TODO: Set vertex buffers/attributes
// TODO: support for iOS devices that don't support base vertex.
int basevertex = start * 4;
@@ -716,6 +771,7 @@ void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth
// TODO: handle clearing mid-pass
if (c.hasValue)
{
gammaCorrectColor(c.value);
auto color = MTLClearColorMake(c.value.r, c.value.g, c.value.b, c.value.a);
for (int i = 0; i < MAX_COLOR_RENDER_TARGETS; i++)
{
@@ -758,7 +814,10 @@ void Graphics::clear(const std::vector<OptionalColorf> &colors, OptionalInt sten
{
if (!colors[i].hasValue)
continue;
const Colorf &c = colors[i].value;
Colorf c = colors[i].value;
gammaCorrectColor(c);
passDesc.colorAttachments[i].clearColor = MTLClearColorMake(c.r, c.g, c.b, c.a);
passDesc.colorAttachments[i].loadAction = MTLLoadActionClear;
}
+31
View File
@@ -40,6 +40,37 @@ static_assert(MAX_COLOR_RENDER_TARGETS <= 8, "Metal pipeline cache key only stor
static MTLVertexFormat getMTLVertexFormat(vertex::DataType type, int components)
{
switch (type)
{
case vertex::DATA_UNORM8:
if (components == 1)
return MTLVertexFormatUCharNormalized;
else if (components == 2)
return MTLVertexFormatUChar2Normalized;
else if (components == 3)
return MTLVertexFormatUChar3Normalized;
else
return MTLVertexFormatUChar4Normalized;
case vertex::DATA_UNORM16:
if (components == 1)
return MTLVertexFormatUShortNormalized;
else if (components == 2)
return MTLVertexFormatUShort2Normalized;
else if (components == 3)
return MTLVertexFormatUShort3Normalized;
else
return MTLVertexFormatUShort4Normalized;
case vertex::DATA_FLOAT:
if (components == 1)
return MTLVertexFormatFloat;
else if (components == 2)
return MTLVertexFormatFloat2;
else if (components == 3)
return MTLVertexFormatFloat3;
else
return MTLVertexFormatFloat4;
}
// TODO
return MTLVertexFormatFloat4;
}
+3
View File
@@ -46,8 +46,11 @@ public:
ptrdiff_t getHandle() const override { return (ptrdiff_t) texture; }
ptrdiff_t getRenderTargetHandle() const override { return msaaTexture != nil ? (ptrdiff_t) msaaTexture : (ptrdiff_t) texture; }
int getMSAA() const override { return 1 /* TODO*/; }
id<MTLSamplerState> getMTLSampler() const { return sampler; }
private:
void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) override;