|
1 | 1 | #include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
|
2 | 2 | #include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
|
3 | 3 | #include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
| 4 | +#include "Metal/MTLResource.hpp" |
4 | 5 |
|
5 | 6 | const size_t BUFFER_ALLOCATION_SIZE = 8 * 1024 * 1024;
|
6 | 7 |
|
@@ -79,29 +80,36 @@ MetalVertexBufferCache::~MetalVertexBufferCache()
|
79 | 80 | }
|
80 | 81 | }
|
81 | 82 |
|
82 |
| -MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(uint32 bufferIndex, size_t stride) |
| 83 | +MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Buffer* bufferCache, uint32 bufferIndex, size_t stride) |
83 | 84 | {
|
84 | 85 | auto vertexBufferRange = m_bufferRanges[bufferIndex];
|
85 | 86 | auto& restrideInfo = vertexBufferRange->restrideInfo;
|
86 | 87 |
|
87 | 88 | if (stride % 4 == 0)
|
88 | 89 | {
|
89 | 90 | // No restride needed
|
90 |
| - return {nullptr, vertexBufferRange->offset}; |
| 91 | + return {bufferCache, vertexBufferRange->offset}; |
91 | 92 | }
|
92 | 93 |
|
93 | 94 | if (restrideInfo.memoryInvalidated || stride != restrideInfo.lastStride)
|
94 | 95 | {
|
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 | + } |
97 | 108 |
|
98 | 109 | restrideInfo.memoryInvalidated = false;
|
99 |
| - restrideInfo.lastStride = stride; |
| 110 | + restrideInfo.lastStride = newStride; |
100 | 111 | }
|
101 | 112 |
|
102 |
| - // TODO: remove |
103 |
| - throw std::runtime_error("restride unimplemented"); |
104 |
| - |
105 | 113 | return {restrideInfo.buffer, 0};
|
106 | 114 | }
|
107 | 115 |
|
|
0 commit comments