mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 21:44:17 +01:00
properly implement 0 stride vertex buffers
This commit is contained in:
parent
b011d756ee
commit
7a28985454
@ -368,6 +368,57 @@ MTL::VertexFormat GetMtlVertexFormat(uint8 format)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 GetMtlVertexFormatSize(uint8 format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case FMT_32_32_32_32_FLOAT:
|
||||||
|
return 16;
|
||||||
|
case FMT_32_32_32_FLOAT:
|
||||||
|
return 12;
|
||||||
|
case FMT_32_32_FLOAT:
|
||||||
|
return 8;
|
||||||
|
case FMT_32_FLOAT:
|
||||||
|
return 4;
|
||||||
|
case FMT_8_8_8_8:
|
||||||
|
return 4;
|
||||||
|
case FMT_8_8_8:
|
||||||
|
return 3;
|
||||||
|
case FMT_8_8:
|
||||||
|
return 2;
|
||||||
|
case FMT_8:
|
||||||
|
return 1;
|
||||||
|
case FMT_32_32_32_32:
|
||||||
|
return 16;
|
||||||
|
case FMT_32_32_32:
|
||||||
|
return 12;
|
||||||
|
case FMT_32_32:
|
||||||
|
return 8;
|
||||||
|
case FMT_32:
|
||||||
|
return 4;
|
||||||
|
case FMT_16_16_16_16:
|
||||||
|
return 8;
|
||||||
|
case FMT_16_16_16:
|
||||||
|
return 6;
|
||||||
|
case FMT_16_16:
|
||||||
|
return 4;
|
||||||
|
case FMT_16:
|
||||||
|
return 2;
|
||||||
|
case FMT_16_16_16_16_FLOAT:
|
||||||
|
return 8;
|
||||||
|
case FMT_16_16_16_FLOAT:
|
||||||
|
return 6;
|
||||||
|
case FMT_16_16_FLOAT:
|
||||||
|
return 4;
|
||||||
|
case FMT_16_FLOAT:
|
||||||
|
return 2;
|
||||||
|
case FMT_2_10_10_10:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType)
|
MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType)
|
||||||
{
|
{
|
||||||
switch (indexType)
|
switch (indexType)
|
||||||
|
@ -42,6 +42,8 @@ MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode primitiveMode);
|
|||||||
|
|
||||||
MTL::VertexFormat GetMtlVertexFormat(uint8 format);
|
MTL::VertexFormat GetMtlVertexFormat(uint8 format);
|
||||||
|
|
||||||
|
uint32 GetMtlVertexFormatSize(uint8 format);
|
||||||
|
|
||||||
MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType);
|
MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType);
|
||||||
|
|
||||||
MTL::BlendOperation GetMtlBlendOp(Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC combineFunc);
|
MTL::BlendOperation GetMtlBlendOp(Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC combineFunc);
|
||||||
|
@ -298,6 +298,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
{
|
{
|
||||||
std::optional<LatteConst::VertexFetchType2> fetchType;
|
std::optional<LatteConst::VertexFetchType2> fetchType;
|
||||||
|
|
||||||
|
uint32 minBufferStride = 0;
|
||||||
for (sint32 j = 0; j < bufferGroup.attribCount; ++j)
|
for (sint32 j = 0; j < bufferGroup.attribCount; ++j)
|
||||||
{
|
{
|
||||||
auto& attr = bufferGroup.attrib[j];
|
auto& attr = bufferGroup.attrib[j];
|
||||||
@ -311,6 +312,8 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
attribute->setBufferIndex(GET_MTL_VERTEX_BUFFER_INDEX(attr.attributeBufferIndex));
|
attribute->setBufferIndex(GET_MTL_VERTEX_BUFFER_INDEX(attr.attributeBufferIndex));
|
||||||
attribute->setFormat(GetMtlVertexFormat(attr.format));
|
attribute->setFormat(GetMtlVertexFormat(attr.format));
|
||||||
|
|
||||||
|
minBufferStride = std::max(minBufferStride, attr.offset + GetMtlVertexFormatSize(attr.format));
|
||||||
|
|
||||||
if (fetchType.has_value())
|
if (fetchType.has_value())
|
||||||
cemu_assert_debug(fetchType == attr.fetchType);
|
cemu_assert_debug(fetchType == attr.fetchType);
|
||||||
else
|
else
|
||||||
@ -327,24 +330,30 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
uint32 bufferStride = (lcr.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF;
|
uint32 bufferStride = (lcr.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF;
|
||||||
bufferStride = Align(bufferStride, 4);
|
bufferStride = Align(bufferStride, 4);
|
||||||
|
|
||||||
// HACK
|
auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex));
|
||||||
if (bufferStride == 0)
|
if (bufferStride == 0)
|
||||||
{
|
{
|
||||||
debug_printf("vertex buffer %u has a vertex stride of 0 bytes, using 4 bytes instead\n", bufferIndex);
|
// Buffer stride cannot be zero, let's use the minimum stride
|
||||||
bufferStride = 4;
|
bufferStride = minBufferStride;
|
||||||
}
|
debug_printf("vertex buffer %u has a vertex stride of 0 bytes, using %u bytes instead\n", bufferIndex, bufferStride);
|
||||||
|
|
||||||
auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex));
|
// Additionally, constant vertex function must be used
|
||||||
layout->setStride(bufferStride);
|
layout->setStepFunction(MTL::VertexStepFunctionConstant);
|
||||||
if (!fetchType.has_value() || fetchType == LatteConst::VertexFetchType2::VERTEX_DATA)
|
layout->setStepRate(0);
|
||||||
layout->setStepFunction(MTL::VertexStepFunctionPerVertex);
|
}
|
||||||
else if (fetchType == LatteConst::VertexFetchType2::INSTANCE_DATA)
|
|
||||||
layout->setStepFunction(MTL::VertexStepFunctionPerInstance);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug_printf("unimplemented vertex fetch type %u\n", (uint32)fetchType.value());
|
if (!fetchType.has_value() || fetchType == LatteConst::VertexFetchType2::VERTEX_DATA)
|
||||||
cemu_assert(false);
|
layout->setStepFunction(MTL::VertexStepFunctionPerVertex);
|
||||||
|
else if (fetchType == LatteConst::VertexFetchType2::INSTANCE_DATA)
|
||||||
|
layout->setStepFunction(MTL::VertexStepFunctionPerInstance);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf("unimplemented vertex fetch type %u\n", (uint32)fetchType.value());
|
||||||
|
cemu_assert(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
layout->setStride(bufferStride);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mtlVertexShader = static_cast<RendererShaderMtl*>(vertexShader->shader);
|
auto mtlVertexShader = static_cast<RendererShaderMtl*>(vertexShader->shader);
|
||||||
|
Loading…
Reference in New Issue
Block a user