mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 21:44:17 +01:00
support instancing for mesh shaders
This commit is contained in:
parent
395cd1cd11
commit
950f04d444
@ -64,6 +64,7 @@ struct LatteDecompilerShaderResourceMapping
|
|||||||
// attributes (vertex shader only)
|
// attributes (vertex shader only)
|
||||||
sint8 attributeMapping[LATTE_NUM_MAX_ATTRIBUTE_LOCATIONS];
|
sint8 attributeMapping[LATTE_NUM_MAX_ATTRIBUTE_LOCATIONS];
|
||||||
// Metal exclusive
|
// Metal exclusive
|
||||||
|
sint8 verticesPerInstanceBinding{-1};
|
||||||
sint8 indexBufferBinding{-1};
|
sint8 indexBufferBinding{-1};
|
||||||
sint8 indexTypeBinding{-1};
|
sint8 indexTypeBinding{-1};
|
||||||
|
|
||||||
|
@ -1019,6 +1019,7 @@ void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteD
|
|||||||
LatteDecompiler::_initTextureBindingPointsMTL(shaderContext);
|
LatteDecompiler::_initTextureBindingPointsMTL(shaderContext);
|
||||||
LatteDecompiler::_initUniformBindingPoints(shaderContext);
|
LatteDecompiler::_initUniformBindingPoints(shaderContext);
|
||||||
LatteDecompiler::_initAttributeBindingPoints(shaderContext);
|
LatteDecompiler::_initAttributeBindingPoints(shaderContext);
|
||||||
|
shaderContext->output->resourceMappingMTL.verticesPerInstanceBinding = shaderContext->currentBufferBindingPointMTL++;
|
||||||
shaderContext->output->resourceMappingMTL.indexBufferBinding = shaderContext->currentBufferBindingPointMTL++;
|
shaderContext->output->resourceMappingMTL.indexBufferBinding = shaderContext->currentBufferBindingPointMTL++;
|
||||||
shaderContext->output->resourceMappingMTL.indexTypeBinding = shaderContext->currentBufferBindingPointMTL++;
|
shaderContext->output->resourceMappingMTL.indexTypeBinding = shaderContext->currentBufferBindingPointMTL++;
|
||||||
}
|
}
|
||||||
|
@ -3920,8 +3920,8 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
// Index buffer
|
// Index buffer
|
||||||
inputFetchDefinition += "if (indexType == 1) // UShort\n";
|
inputFetchDefinition += "if (indexType == 1) // UShort\n";
|
||||||
inputFetchDefinition += "vid = ((device ushort*)indexBuffer)[vid];\n";
|
inputFetchDefinition += "vid = ((device ushort*)indexBuffer)[vid];\n";
|
||||||
inputFetchDefinition += "else if (indexType == 2)\n";
|
inputFetchDefinition += "else if (indexType == 2) // UInt\n";
|
||||||
inputFetchDefinition += "vid = ((device uint*)indexBuffer)[vid]; // UInt\n";
|
inputFetchDefinition += "vid = ((device uint*)indexBuffer)[vid];\n";
|
||||||
|
|
||||||
inputFetchDefinition += "VertexIn in;\n";
|
inputFetchDefinition += "VertexIn in;\n";
|
||||||
for (auto& bufferGroup : shaderContext->fetchShader->bufferGroups)
|
for (auto& bufferGroup : shaderContext->fetchShader->bufferGroups)
|
||||||
@ -4060,8 +4060,8 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
{
|
{
|
||||||
// Calculate the imaginary vertex id
|
// Calculate the imaginary vertex id
|
||||||
src->add("uint vid = tig * VERTICES_PER_VERTEX_PRIMITIVE + tid;" _CRLF);
|
src->add("uint vid = tig * VERTICES_PER_VERTEX_PRIMITIVE + tid;" _CRLF);
|
||||||
// TODO: don't hardcode the instance index
|
src->add("uint iid = vid / verticesPerInstance;" _CRLF);
|
||||||
src->add("uint iid = 0;" _CRLF);
|
src->add("vid %= verticesPerInstance;" _CRLF);
|
||||||
// Fetch the input
|
// Fetch the input
|
||||||
src->add("VertexIn in = fetchVertex(vid, indexBuffer, indexType VERTEX_BUFFERS);" _CRLF);
|
src->add("VertexIn in = fetchVertex(vid, indexBuffer, indexType VERTEX_BUFFERS);" _CRLF);
|
||||||
// Output is defined as object payload
|
// Output is defined as object payload
|
||||||
|
@ -497,8 +497,11 @@ namespace LatteDecompiler
|
|||||||
src->add(", mesh_grid_properties meshGridProperties");
|
src->add(", mesh_grid_properties meshGridProperties");
|
||||||
src->add(", uint tig [[threadgroup_position_in_grid]]");
|
src->add(", uint tig [[threadgroup_position_in_grid]]");
|
||||||
src->add(", uint tid [[thread_index_in_threadgroup]]");
|
src->add(", uint tid [[thread_index_in_threadgroup]]");
|
||||||
|
// TODO: put into the support buffer?
|
||||||
|
src->addFmt(", constant uint& verticesPerInstance [[buffer({})]]", decompilerContext->output->resourceMappingMTL.verticesPerInstanceBinding);
|
||||||
// TODO: inly include index buffer if needed
|
// TODO: inly include index buffer if needed
|
||||||
src->addFmt(", device uint* indexBuffer [[buffer({})]]", decompilerContext->output->resourceMappingMTL.indexBufferBinding);
|
src->addFmt(", device uint* indexBuffer [[buffer({})]]", decompilerContext->output->resourceMappingMTL.indexBufferBinding);
|
||||||
|
// TODO: put into the support buffer?
|
||||||
// TODO: use uchar?
|
// TODO: use uchar?
|
||||||
src->addFmt(", constant uint& indexType [[buffer({})]]", decompilerContext->output->resourceMappingMTL.indexTypeBinding);
|
src->addFmt(", constant uint& indexType [[buffer({})]]", decompilerContext->output->resourceMappingMTL.indexTypeBinding);
|
||||||
src->add(" VERTEX_BUFFER_DEFINITIONS");
|
src->add(" VERTEX_BUFFER_DEFINITIONS");
|
||||||
|
@ -1183,6 +1183,10 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
}
|
}
|
||||||
if (usesGeometryShader)
|
if (usesGeometryShader)
|
||||||
{
|
{
|
||||||
|
uint32 verticesPerInstance = count / instanceCount;
|
||||||
|
// TODO: make a helper function for this
|
||||||
|
renderCommandEncoder->setObjectBytes(&verticesPerInstance, sizeof(verticesPerInstance), vertexShader->resourceMapping.verticesPerInstanceBinding);
|
||||||
|
encoderState.m_buffers[METAL_SHADER_TYPE_OBJECT][vertexShader->resourceMapping.verticesPerInstanceBinding] = {nullptr};
|
||||||
if (indexBuffer)
|
if (indexBuffer)
|
||||||
SetBuffer(renderCommandEncoder, METAL_SHADER_TYPE_OBJECT, indexBuffer, indexBufferOffset, vertexShader->resourceMapping.indexBufferBinding);
|
SetBuffer(renderCommandEncoder, METAL_SHADER_TYPE_OBJECT, indexBuffer, indexBufferOffset, vertexShader->resourceMapping.indexBufferBinding);
|
||||||
renderCommandEncoder->setObjectBytes(&hostIndexType, sizeof(hostIndexType), vertexShader->resourceMapping.indexTypeBinding);
|
renderCommandEncoder->setObjectBytes(&hostIndexType, sizeof(hostIndexType), vertexShader->resourceMapping.indexTypeBinding);
|
||||||
@ -1206,7 +1210,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder->drawMeshThreadgroups(MTL::Size(count / verticesPerPrimitive, 1, 1), MTL::Size(verticesPerPrimitive, 1, 1), MTL::Size(1, 1, 1));
|
renderCommandEncoder->drawMeshThreadgroups(MTL::Size(count * instanceCount / verticesPerPrimitive, 1, 1), MTL::Size(verticesPerPrimitive, 1, 1), MTL::Size(1, 1, 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user