Skip to content

Commit ac651eb

Browse files
committed
implement vertex stride workaround
1 parent 82dcbd9 commit ac651eb

File tree

3 files changed

+25
-16
lines changed

3 files changed

+25
-16
lines changed

src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
22
#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
33
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
4+
#include "Metal/MTLResource.hpp"
45

56
const size_t BUFFER_ALLOCATION_SIZE = 8 * 1024 * 1024;
67

@@ -79,29 +80,36 @@ MetalVertexBufferCache::~MetalVertexBufferCache()
7980
}
8081
}
8182

82-
MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(uint32 bufferIndex, size_t stride)
83+
MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Buffer* bufferCache, uint32 bufferIndex, size_t stride)
8384
{
8485
auto vertexBufferRange = m_bufferRanges[bufferIndex];
8586
auto& restrideInfo = vertexBufferRange->restrideInfo;
8687

8788
if (stride % 4 == 0)
8889
{
8990
// No restride needed
90-
return {nullptr, vertexBufferRange->offset};
91+
return {bufferCache, vertexBufferRange->offset};
9192
}
9293

9394
if (restrideInfo.memoryInvalidated || stride != restrideInfo.lastStride)
9495
{
95-
// TODO: restride
96-
throw std::runtime_error("restride needed");
96+
// TODO: use compute/void vertex function instead
97+
size_t newStride = align(stride, 4);
98+
size_t newSize = vertexBufferRange->size / stride * newStride;
99+
restrideInfo.buffer = m_mtlr->GetDevice()->newBuffer(newSize, MTL::StorageModeShared);
100+
101+
uint8* oldPtr = (uint8*)bufferCache->contents() + vertexBufferRange->offset;
102+
uint8* newPtr = (uint8*)restrideInfo.buffer->contents();
103+
104+
for (size_t elem = 0; elem < vertexBufferRange->size / stride; elem++)
105+
{
106+
memcpy(newPtr + elem * newStride, oldPtr + elem * stride, stride);
107+
}
97108

98109
restrideInfo.memoryInvalidated = false;
99-
restrideInfo.lastStride = stride;
110+
restrideInfo.lastStride = newStride;
100111
}
101112

102-
// TODO: remove
103-
throw std::runtime_error("restride unimplemented");
104-
105113
return {restrideInfo.buffer, 0};
106114
}
107115

src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class MetalVertexBufferCache
9797
range = nullptr;
9898
}
9999

100-
MetalRestridedBufferRange RestrideBufferIfNeeded(uint32 bufferIndex, size_t stride);
100+
MetalRestridedBufferRange RestrideBufferIfNeeded(MTL::Buffer* bufferCache, uint32 bufferIndex, size_t stride);
101101

102102
private:
103103
class MetalRenderer* m_mtlr;
@@ -159,13 +159,7 @@ class MetalMemoryManager
159159

160160
MetalRestridedBufferRange RestrideBufferIfNeeded(uint32 bufferIndex, size_t stride)
161161
{
162-
auto range = m_vertexBufferCache.RestrideBufferIfNeeded(bufferIndex, stride);
163-
if (!range.buffer)
164-
{
165-
range.buffer = m_bufferCache;
166-
}
167-
168-
return range;
162+
return m_vertexBufferCache.RestrideBufferIfNeeded(m_bufferCache, bufferIndex, stride);
169163
}
170164

171165
private:

src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS
6363
uint32 bufferStride = (LatteGPUState.contextNew.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF;
6464
bufferStride = align(bufferStride, 4);
6565

66+
// HACK
67+
if (bufferStride == 0)
68+
{
69+
debug_printf("vertex buffer %u has a vertex stride of 0 bytes, using 4 bytes instead\n", bufferIndex);
70+
bufferStride = 4;
71+
}
72+
6673
auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex));
6774
layout->setStride(bufferStride);
6875
if (!fetchType.has_value() || fetchType == LatteConst::VertexFetchType2::VERTEX_DATA)

0 commit comments

Comments
 (0)