diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index 9d75ad4ce1..53f68dfa72 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -109,34 +109,88 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_ } } -template -void expandIndexedTriangleFan(DstType *dst, const SrcType *src, size_t indexCount) +template +void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) { - IndexType *typedDst = reinterpret_cast(dst); - const IndexType *typedSrc = reinterpret_cast(src); - for (unsigned i = 0; i < indexCount - 2; i++) + for (u32 i = 0; i < indexCount; ++i) { - typedDst[3 * i] = typedSrc[0]; - typedDst[3 * i + 1] = typedSrc[i + 2 - 1]; - typedDst[3 * i + 2] = typedSrc[i + 2]; + IndexType index = vm::ps3::_ref(address + i * sizeof(IndexType)); + (IndexType&)dst[i * sizeof(IndexType)] = index; + if (is_primitive_restart_enabled && index == (IndexType)-1) // Cut + continue; + max_index = MAX2(max_index, index); + min_index = MIN2(min_index, index); } } -template -void expandIndexedQuads(DstType *dst, const SrcType *src, size_t indexCount) +template +void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) +{ + for (unsigned i = 0; i < indexCount - 2; i++) + { + IndexType index0 = vm::ps3::_ref(address); + (IndexType&)dst[(3 * i) * sizeof(IndexType)] = index0; + IndexType index1 = vm::ps3::_ref(address + (i + 2 - 1) * sizeof(IndexType)); + (IndexType&)dst[(3 * i + 1) * sizeof(IndexType)] = index1; + IndexType index2 = vm::ps3::_ref(address + (i + 2) * sizeof(IndexType)); + (IndexType&)dst[(3 * i + 2) * sizeof(IndexType)] = index2; + + if (!is_primitive_restart_enabled || index0 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index0); + max_index = MAX2(max_index, index0); + } + if (!is_primitive_restart_enabled || index1 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index1); + max_index = MAX2(max_index, index1); + } + if (!is_primitive_restart_enabled || index2 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index2); + max_index = MAX2(max_index, index2); + } + } +} + +template +void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) { - IndexType *typedDst = reinterpret_cast(dst); - const IndexType *typedSrc = reinterpret_cast(src); for (unsigned i = 0; i < indexCount / 4; i++) { // First triangle - typedDst[6 * i] = typedSrc[4 * i]; - typedDst[6 * i + 1] = typedSrc[4 * i + 1]; - typedDst[6 * i + 2] = typedSrc[4 * i + 2]; + IndexType index0 = vm::ps3::_ref(address + 4 * i * sizeof(IndexType)); + (IndexType&)dst[(6 * i) * sizeof(IndexType)] = index0; + IndexType index1 = vm::ps3::_ref(address + (4 * i + 1) * sizeof(IndexType)); + (IndexType&)dst[(6 * i + 1) * sizeof(IndexType)] = index1; + IndexType index2 = vm::ps3::_ref(address + (4 * i + 2) * sizeof(IndexType)); + (IndexType&)dst[(6 * i + 2) * sizeof(IndexType)] = index2; // Second triangle - typedDst[6 * i + 3] = typedSrc[4 * i + 2]; - typedDst[6 * i + 4] = typedSrc[4 * i + 3]; - typedDst[6 * i + 5] = typedSrc[4 * i]; + (IndexType&)dst[(6 * i + 3) * sizeof(IndexType)] = index2; + IndexType index3 = vm::ps3::_ref(address + (4 * i + 3) * sizeof(IndexType)); + (IndexType&)dst[(6 * i + 4) * sizeof(IndexType)] = index3; + (IndexType&)dst[(6 * i + 5) * sizeof(IndexType)] = index0; + + if (!is_primitive_restart_enabled || index0 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index0); + max_index = MAX2(max_index, index0); + } + if (!is_primitive_restart_enabled || index1 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index1); + max_index = MAX2(max_index, index1); + } + if (!is_primitive_restart_enabled || index2 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index2); + max_index = MAX2(max_index, index2); + } + if (!is_primitive_restart_enabled || index3 != (IndexType)-1) // Cut + { + min_index = MIN2(min_index, index3); + max_index = MAX2(max_index, index3); + } } } @@ -178,79 +232,84 @@ size_t getIndexCount(unsigned m_draw_mode, unsigned initial_index_count) } } - -void uploadIndexData(unsigned m_draw_mode, unsigned index_type, void* indexBuffer, void* bufferMap, unsigned element_count) +void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned draw_mode, unsigned first, unsigned count) { - if (indexBuffer != nullptr) + unsigned short *typedDst = (unsigned short *)(dst); + switch (draw_mode) { - switch (m_draw_mode) + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: + for (unsigned i = 0; i < (count - 2); i++) { - case CELL_GCM_PRIMITIVE_POINTS: - case CELL_GCM_PRIMITIVE_LINES: - case CELL_GCM_PRIMITIVE_LINE_LOOP: - case CELL_GCM_PRIMITIVE_LINE_STRIP: - case CELL_GCM_PRIMITIVE_TRIANGLES: - case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: - case CELL_GCM_PRIMITIVE_QUAD_STRIP: - case CELL_GCM_PRIMITIVE_POLYGON: + typedDst[3 * i] = first; + typedDst[3 * i + 1] = i + 2 - 1; + typedDst[3 * i + 2] = i + 2; + } + return; + case CELL_GCM_PRIMITIVE_QUADS: + for (unsigned i = 0; i < count / 4; i++) { - size_t indexSize = (index_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32) ? 4 : 2; - memcpy(bufferMap, indexBuffer, indexSize * element_count); - return; - } - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - switch (index_type) - { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - expandIndexedTriangleFan(bufferMap, indexBuffer, element_count); - return; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - expandIndexedTriangleFan(bufferMap, indexBuffer, element_count); - return; - default: - abort(); - return; - } - case CELL_GCM_PRIMITIVE_QUADS: - switch (index_type) - { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - expandIndexedQuads(bufferMap, indexBuffer, element_count); - return; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - expandIndexedQuads(bufferMap, indexBuffer, element_count); - return; - default: - abort(); - return; - } + // First triangle + typedDst[6 * i] = 4 * i + first; + typedDst[6 * i + 1] = 4 * i + 1 + first; + typedDst[6 * i + 2] = 4 * i + 2 + first; + // Second triangle + typedDst[6 * i + 3] = 4 * i + 2 + first; + typedDst[6 * i + 4] = 4 * i + 3 + first; + typedDst[6 * i + 5] = 4 * i + first; } + return; } - else +} + +void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index) +{ + u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); + u32 type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; + + u32 type_size = type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 ? sizeof(u32) : sizeof(u16); + + u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; + u32 base_index = 0;//rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; + bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]; + + switch (m_draw_mode) { - unsigned short *typedDst = static_cast(bufferMap); - switch (m_draw_mode) + case CELL_GCM_PRIMITIVE_POINTS: + case CELL_GCM_PRIMITIVE_LINES: + case CELL_GCM_PRIMITIVE_LINE_LOOP: + case CELL_GCM_PRIMITIVE_LINE_STRIP: + case CELL_GCM_PRIMITIVE_TRIANGLES: + case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: + case CELL_GCM_PRIMITIVE_QUAD_STRIP: + case CELL_GCM_PRIMITIVE_POLYGON: + switch (type) { - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - for (unsigned i = 0; i < (element_count - 2); i++) - { - typedDst[3 * i] = 0; - typedDst[3 * i + 1] = i + 2 - 1; - typedDst[3 * i + 2] = i + 2; - } + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: + uploadAsIt(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, min_index, max_index); return; - case CELL_GCM_PRIMITIVE_QUADS: - for (unsigned i = 0; i < element_count / 4; i++) - { - // First triangle - typedDst[6 * i] = 4 * i; - typedDst[6 * i + 1] = 4 * i + 1; - typedDst[6 * i + 2] = 4 * i + 2; - // Second triangle - typedDst[6 * i + 3] = 4 * i + 2; - typedDst[6 * i + 4] = 4 * i + 3; - typedDst[6 * i + 5] = 4 * i; - } + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: + uploadAsIt(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, min_index, max_index); + return; + } + return; + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: + switch (type) + { + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: + expandIndexedTriangleFan(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, min_index, max_index); + return; + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: + expandIndexedTriangleFan(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, min_index, max_index); + return; + } + case CELL_GCM_PRIMITIVE_QUADS: + switch (type) + { + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: + expandIndexedQuads(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, min_index, max_index); + return; + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: + expandIndexedQuads(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, min_index, max_index); return; } } diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.h b/rpcs3/Emu/RSX/Common/BufferUtils.h index e04bbc33f1..0294256b57 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.h +++ b/rpcs3/Emu/RSX/Common/BufferUtils.h @@ -35,6 +35,13 @@ bool isNativePrimitiveMode(unsigned m_draw_mode); size_t getIndexCount(unsigned m_draw_mode, unsigned initial_index_count); /* - * Write index information to bufferMap + * Write count indexes starting at first to dst buffer. + * Returns min/max index found during the process. + * The function expands index buffer for non native primitive type. */ -void uploadIndexData(unsigned m_draw_mode, unsigned index_type, void* indexBuffer, void* bufferMap, unsigned element_count); \ No newline at end of file +void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index); + +/* +* Write index data needed to emulate non indexed non native primitive mode. +*/ +void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count); \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 2005391f3b..78c66bc379 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -118,13 +118,17 @@ void D3D12GSRender::load_vertex_data(u32 first, u32 count) vertex_draw_count += count; } - -void D3D12GSRender::upload_vertex_attributes() +void D3D12GSRender::upload_vertex_attributes(const std::vector > &vertex_ranges) { m_vertex_buffer_views.clear(); m_IASet.clear(); size_t inputSlot = 0; + size_t vertex_count = 0; + + for (const auto &pair : vertex_ranges) + vertex_count += pair.second; + // First array attribute for (int index = 0; index < rsx::limits::vertex_count; ++index) { @@ -136,14 +140,14 @@ void D3D12GSRender::upload_vertex_attributes() u32 type_size = rsx::get_vertex_type_size(info.type); u32 element_size = type_size * info.size; - size_t subBufferSize = element_size * vertex_draw_count; + size_t subBufferSize = element_size * vertex_count; assert(m_vertexIndexData.canAlloc(subBufferSize)); size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); void *buffer; ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); void *bufferMap = (char*)buffer + heapOffset; - for (const auto &range : m_first_count_pairs) + for (const auto &range : vertex_ranges) { write_vertex_array_data_to_buffer(bufferMap, range.first, range.second, index, info); bufferMap = (char*)bufferMap + range.second * element_size; @@ -210,73 +214,11 @@ void D3D12GSRender::upload_vertex_attributes() IAElement.InstanceDataStepRate = 1; m_IASet.push_back(IAElement); } - m_first_count_pairs.clear(); } -D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) +void D3D12GSRender::load_vertex_index_data(u32 first, u32 count) { - D3D12_INDEX_BUFFER_VIEW indexBufferView = {}; - - // No need for index buffer - if (!indexed_draw && isNativePrimitiveMode(draw_mode)) - { - m_renderingInfo.m_indexed = false; - m_renderingInfo.m_count = vertex_draw_count; - m_renderingInfo.m_baseVertex = 0; - return indexBufferView; - } - m_renderingInfo.m_indexed = true; - - u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; - - // Index type - size_t indexSize; - if (!indexed_draw) - { - indexBufferView.Format = DXGI_FORMAT_R16_UINT; - indexSize = 2; - } - else - { - switch (indexed_type) - { - default: abort(); - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - indexBufferView.Format = DXGI_FORMAT_R16_UINT; - indexSize = 2; - break; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - indexBufferView.Format = DXGI_FORMAT_R32_UINT; - indexSize = 4; - break; - } - } - - // Index count - m_renderingInfo.m_count = getIndexCount(draw_mode, indexed_draw ? (u32)(vertex_index_array.size() / indexSize) : vertex_draw_count); - - // Base vertex - if (!indexed_draw && isNativePrimitiveMode(draw_mode)) - m_renderingInfo.m_baseVertex = 0; - else - m_renderingInfo.m_baseVertex = 0; - - // Alloc - size_t subBufferSize = align(m_renderingInfo.m_count * indexSize, 64); - - assert(m_vertexIndexData.canAlloc(subBufferSize)); - size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); - - void *buffer; - ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); - void *bufferMap = (char*)buffer + heapOffset; - uploadIndexData(draw_mode, indexed_type, indexed_draw ? vertex_index_array.data() : nullptr, bufferMap, indexed_draw ? (u32)(vertex_index_array.size() / indexSize) : vertex_draw_count); - m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); - m_timers.m_bufferUploadSize += subBufferSize; - indexBufferView.SizeInBytes = (UINT)subBufferSize; - indexBufferView.BufferLocation = m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset; - return indexBufferView; } void D3D12GSRender::setScaleOffset(size_t descriptorIndex) @@ -419,4 +361,83 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer(size_t descriptorIndex) CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart()) .Offset((INT)descriptorIndex, g_descriptorStrideSRVCBVUAV)); } + +void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *cmdlist) +{ + // Index count + m_renderingInfo.m_count = 0; + for (const auto &pair : m_first_count_pairs) + m_renderingInfo.m_count += getIndexCount(draw_mode, pair.second); + + if (!m_renderingInfo.m_indexed) + { + // Non indexed + upload_vertex_attributes(m_first_count_pairs); + cmdlist->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data()); + if (isNativePrimitiveMode(draw_mode)) + return; + // Handle non native primitive + + // Alloc + size_t subBufferSize = align(m_renderingInfo.m_count * sizeof(u16), 64); + assert(m_vertexIndexData.canAlloc(subBufferSize)); + size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); + + void *buffer; + ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); + void *bufferMap = (char*)buffer + heapOffset; + size_t first = 0; + for (const auto &pair : m_first_count_pairs) + { + size_t element_count = getIndexCount(draw_mode, pair.second); + write_index_array_for_non_indexed_non_native_primitive_to_buffer((char*)bufferMap, draw_mode, first, pair.second); + bufferMap = (char*)bufferMap + element_count * sizeof(u16); + first += pair.second; + } + m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); + D3D12_INDEX_BUFFER_VIEW indexBufferView = { + m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset, + (UINT)subBufferSize, + DXGI_FORMAT_R16_UINT + }; + cmdlist->IASetIndexBuffer(&indexBufferView); + m_renderingInfo.m_indexed = true; + } + else + { + u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; + + // Index type + size_t indexSize = (indexed_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16) ? 2 : 4; + + // Alloc + size_t subBufferSize = align(m_renderingInfo.m_count * indexSize, 64); + assert(m_vertexIndexData.canAlloc(subBufferSize)); + size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); + + void *buffer; + ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); + void *bufferMap = (char*)buffer + heapOffset; + u32 min_index = (u32)-1, max_index = 0; + for (const auto &pair : m_first_count_pairs) + { + size_t element_count = getIndexCount(draw_mode, pair.second); + write_index_array_data_to_buffer((char*)bufferMap, draw_mode, pair.first, pair.second, min_index, max_index); + bufferMap = (char*)bufferMap + element_count * indexSize; + } + m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); + D3D12_INDEX_BUFFER_VIEW indexBufferView = { + m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset, + (UINT)subBufferSize, + (indexed_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT + }; + m_timers.m_bufferUploadSize += subBufferSize; + cmdlist->IASetIndexBuffer(&indexBufferView); + m_renderingInfo.m_indexed = true; + + upload_vertex_attributes({ std::make_pair(0, max_index + 1) }); + cmdlist->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data()); + } +} + #endif diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 50edd4756d..f9c7cabd9a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -413,13 +413,7 @@ void D3D12GSRender::end() std::chrono::time_point vertexIndexDurationStart = std::chrono::system_clock::now(); if (!vertex_index_array.empty() || vertex_draw_count) - { - upload_vertex_attributes(); - const D3D12_INDEX_BUFFER_VIEW &indexBufferView = uploadIndexBuffers(!vertex_index_array.empty()); - getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data()); - if (m_renderingInfo.m_indexed) - getCurrentResourceStorage().m_commandList->IASetIndexBuffer(&indexBufferView); - } + upload_vertex_index_data(getCurrentResourceStorage().m_commandList.Get()); std::chrono::time_point vertexIndexDurationEnd = std::chrono::system_clock::now(); m_timers.m_vertexIndexDuration += std::chrono::duration_cast(vertexIndexDurationEnd - vertexIndexDurationStart).count(); @@ -595,9 +589,9 @@ void D3D12GSRender::end() } if (m_renderingInfo.m_indexed) - getCurrentResourceStorage().m_commandList->DrawIndexedInstanced((UINT)m_renderingInfo.m_count, 1, 0, (UINT)m_renderingInfo.m_baseVertex, 0); + getCurrentResourceStorage().m_commandList->DrawIndexedInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0, 0); else - getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, (UINT)m_renderingInfo.m_baseVertex, 0); + getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0); vertex_index_array.clear(); std::chrono::time_point endDuration = std::chrono::system_clock::now(); @@ -610,7 +604,8 @@ void D3D12GSRender::end() m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf()); getCurrentResourceStorage().setNewCommandList(); } - + m_first_count_pairs.clear(); + m_renderingInfo.m_indexed = false; thread::end(); } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index b2e216798f..e8dd4f6d14 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -417,7 +417,6 @@ private: { bool m_indexed; /* > m_first_count_pairs; /** - * Upload all vertex attribute whose (first, count) info were previously accumulated. + * Upload all enabled vertex attributes for vertex in ranges described by vertex_ranges. + * A range in vertex_range is a pair whose first element is the index of the beginning of the + * range, and whose second element is the number of vertex in this range. */ - void upload_vertex_attributes(); - - /** - * Create index buffer for indexed rendering and non native primitive format if nedded, and - * update m_renderingInfo member accordingly. If m_renderingInfo::m_indexed is true, - * returns an index buffer view that can be passed to a command list. - */ - D3D12_INDEX_BUFFER_VIEW uploadIndexBuffers(bool indexed_draw = false); - + void upload_vertex_attributes(const std::vector > &vertex_ranges); void setScaleOffset(size_t descriptorIndex); void FillVertexShaderConstantsBuffer(size_t descriptorIndex); @@ -504,4 +503,5 @@ protected: virtual void flip(int buffer) override; virtual void load_vertex_data(u32 first, u32 count) override; + virtual void load_vertex_index_data(u32 first, u32 count) override; }; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index c84c1714a3..2131b26d82 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -164,7 +164,7 @@ namespace rsx u32 transform_program[512 * 4] = {}; virtual void load_vertex_data(u32 first, u32 count); - void load_vertex_index_data(u32 first, u32 count); + virtual void load_vertex_index_data(u32 first, u32 count); public: u32 ioAddress, ioSize;