|
6 | 6 | #include "Cafe/HW/Latte/Renderer/Metal/CachedFBOMtl.h"
|
7 | 7 | #include "Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h"
|
8 | 8 | #include "Cafe/HW/Latte/Renderer/Metal/MetalDepthStencilCache.h"
|
9 |
| -#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h" |
10 | 9 | #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h"
|
11 | 10 |
|
12 | 11 | #include "Cafe/HW/Latte/Renderer/Metal/ShaderSourcePresent.h"
|
@@ -440,11 +439,22 @@ void MetalRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint
|
440 | 439 |
|
441 | 440 | void MetalRenderer::buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, uint32 size)
|
442 | 441 | {
|
443 |
| - if (m_state.vertexBuffers[bufferIndex].offset == offset) |
| 442 | + cemu_assert_debug(bufferIndex < LATTE_MAX_VERTEX_BUFFERS); |
| 443 | + auto& buffer = m_state.vertexBuffers[bufferIndex]; |
| 444 | + if (buffer.offset == offset && buffer.size == size) |
444 | 445 | return;
|
445 |
| - cemu_assert_debug(bufferIndex < LATTE_MAX_VERTEX_BUFFERS); |
446 |
| - m_state.vertexBuffers[bufferIndex].needsRebind = true; |
447 |
| - m_state.vertexBuffers[bufferIndex].offset = offset; |
| 446 | + |
| 447 | + if (buffer.offset != INVALID_OFFSET) |
| 448 | + { |
| 449 | + m_memoryManager->UntrackVertexBuffer(bufferIndex); |
| 450 | + } |
| 451 | + |
| 452 | + buffer.needsRebind = true; |
| 453 | + buffer.offset = offset; |
| 454 | + buffer.size = size; |
| 455 | + buffer.restrideInfo = {}; |
| 456 | + |
| 457 | + m_memoryManager->TrackVertexBuffer(bufferIndex, offset, size, buffer.restrideInfo); |
448 | 458 | }
|
449 | 459 |
|
450 | 460 | void MetalRenderer::buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size)
|
@@ -598,15 +608,25 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
598 | 608 | LatteBufferCache_Sync(indexMin + baseVertex, indexMax + baseVertex, baseInstance, instanceCount);
|
599 | 609 |
|
600 | 610 | // Vertex buffers
|
601 |
| - for (uint8 i = 0; i < MAX_MTL_BUFFERS; i++) |
602 |
| - { |
603 |
| - auto& vertexBufferRange = m_state.vertexBuffers[i]; |
604 |
| - if (vertexBufferRange.needsRebind) |
| 611 | + for (uint8 i = 0; i < MAX_MTL_BUFFERS; i++) |
| 612 | + { |
| 613 | + auto& vertexBufferRange = m_state.vertexBuffers[i]; |
| 614 | + if (vertexBufferRange.offset != INVALID_OFFSET) |
605 | 615 | {
|
606 |
| - renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), vertexBufferRange.offset, GET_MTL_VERTEX_BUFFER_INDEX(i)); |
607 |
| - vertexBufferRange.needsRebind = false; |
| 616 | + // Restride |
| 617 | + uint32 bufferBaseRegisterIndex = mmSQ_VTX_ATTRIBUTE_BLOCK_START + i * 7; |
| 618 | + uint32 bufferStride = (LatteGPUState.contextNew.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF; |
| 619 | + |
| 620 | + auto restridedBuffer = m_memoryManager->RestrideBufferIfNeeded(i, bufferStride); |
| 621 | + |
| 622 | + // Bind |
| 623 | + if (vertexBufferRange.needsRebind) |
| 624 | + { |
| 625 | + renderCommandEncoder->setVertexBuffer(restridedBuffer.buffer, restridedBuffer.offset, GET_MTL_VERTEX_BUFFER_INDEX(i)); |
| 626 | + vertexBufferRange.needsRebind = false; |
| 627 | + } |
608 | 628 | }
|
609 |
| - } |
| 629 | + } |
610 | 630 |
|
611 | 631 | // Uniform buffers, textures and samplers
|
612 | 632 | BindStageResources(renderCommandEncoder, vertexShader);
|
@@ -1186,10 +1206,7 @@ void MetalRenderer::RebindRenderState(MTL::RenderCommandEncoder* renderCommandEn
|
1186 | 1206 | {
|
1187 | 1207 | auto& vertexBufferRange = m_state.vertexBuffers[i];
|
1188 | 1208 | if (vertexBufferRange.offset != INVALID_OFFSET)
|
1189 |
| - { |
1190 |
| - renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), vertexBufferRange.offset, GET_MTL_VERTEX_BUFFER_INDEX(i)); |
1191 |
| - vertexBufferRange.needsRebind = false; |
1192 |
| - } |
| 1209 | + vertexBufferRange.needsRebind = true; |
1193 | 1210 | }
|
1194 | 1211 | }
|
1195 | 1212 |
|
|
0 commit comments