From 60bccf0f109bf21a42dfe8d91f7f1b5773d853a6 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 Oct 2015 01:07:47 +0200 Subject: [PATCH] Remove RSXVertexArray --- rpcs3/Emu/RSX/Common/BufferUtils.cpp | 29 +-- rpcs3/Emu/RSX/Common/BufferUtils.h | 4 +- rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 22 +- rpcs3/Emu/RSX/D3D12/D3D12Buffer.h | 2 +- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 16 +- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 16 +- rpcs3/Emu/RSX/RSXThread.cpp | 284 ++++++++++++-------------- rpcs3/Emu/RSX/RSXThread.h | 43 ++-- 8 files changed, 206 insertions(+), 210 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index 18d5c9e176..bfc85cf41a 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -12,20 +12,22 @@ bool overlaps(const std::pair &range1, const std::pair FormatVertexData(const RSXVertexData *m_vertex_data, size_t *vertex_data_size, size_t base_offset) +std::vector FormatVertexData(const rsx::data_array_format_info *vertex_array_desc, const std::vector *vertex_data, size_t *vertex_data_size, size_t base_offset) { std::vector Result; for (size_t i = 0; i < rsx::limits::vertex_count; ++i) { - const RSXVertexData &vertexData = m_vertex_data[i]; - if (!vertexData.IsEnabled()) continue; + const rsx::data_array_format_info &vertexData = vertex_array_desc[i]; + if (!vertexData.size) continue; - size_t elementCount = ((vertexData.addr) ? vertex_data_size[i] : m_vertex_data[i].data.size()) / (vertexData.size * rsx::get_vertex_type_size(vertexData.type)); + u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 * i]; + u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31); + size_t elementCount = ((vertexData.array) ? vertex_data_size[i] : vertex_data[i].size()) / (vertexData.size * rsx::get_vertex_type_size(vertexData.type)); // If there is a single element, stride is 0, use the size of element instead size_t stride = vertexData.stride; size_t elementSize = rsx::get_vertex_type_size(vertexData.type); - size_t start = vertexData.addr + base_offset; + size_t start = addr + base_offset; size_t end = start + elementSize * vertexData.size + (elementCount - 1) * stride - 1; std::pair range = std::make_pair(start, end); assert(start < end); @@ -53,21 +55,24 @@ std::vector FormatVertexData(const RSXVertexData *m_vertex_d return Result; } -void uploadVertexData(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, void* bufferMap) +void uploadVertexData(const VertexBufferFormat &vbf, const rsx::data_array_format_info *vertex_array_desc, const std::vector *vertex_data, size_t baseOffset, void* bufferMap) { for (int vertex = 0; vertex < vbf.elementCount; vertex++) { for (size_t attributeId : vbf.attributeId) { - if (!vertexData[attributeId].addr) + u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 * attributeId]; + u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31); + + if (!vertex_array_desc[attributeId].array) { - memcpy(bufferMap, vertexData[attributeId].data.data(), vertexData[attributeId].data.size()); + memcpy(bufferMap, vertex_data[attributeId].data(), vertex_data[attributeId].size()); continue; } - size_t offset = (size_t)vertexData[attributeId].addr + baseOffset - vbf.range.first; - size_t tsize = rsx::get_vertex_type_size(vertexData[attributeId].type); - size_t size = vertexData[attributeId].size; - auto src = vm::get_ptr(vertexData[attributeId].addr + (u32)baseOffset + (u32)vbf.stride * vertex); + size_t offset = (size_t)addr + baseOffset - vbf.range.first; + size_t tsize = rsx::get_vertex_type_size(vertex_array_desc[attributeId].type); + size_t size = vertex_array_desc[attributeId].size; + auto src = vm::get_ptr(addr + (u32)baseOffset + (u32)vbf.stride * vertex); char* dst = (char*)bufferMap + offset + vbf.stride * vertex; switch (tsize) diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.h b/rpcs3/Emu/RSX/Common/BufferUtils.h index bdb46b22c4..874d673241 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.h +++ b/rpcs3/Emu/RSX/Common/BufferUtils.h @@ -17,12 +17,12 @@ struct VertexBufferFormat * Detect buffer containing interleaved vertex attribute. * This minimizes memory upload size. */ -std::vector FormatVertexData(const RSXVertexData *m_vertex_data, size_t *vertex_data_size, size_t base_offset); +std::vector FormatVertexData(const rsx::data_array_format_info *vertex_array_desc, const std::vector *vertex_data, size_t *vertex_data_size, size_t base_offset); /* * Write vertex attributes to bufferMap, swapping data as required. */ -void uploadVertexData(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, void* bufferMap); +void uploadVertexData(const VertexBufferFormat &vbf, const rsx::data_array_format_info *vertex_array_desc, const std::vector *vertex_data, size_t baseOffset, void* bufferMap); /* * If primitive mode is not supported and need to be emulated (using an index buffer) returns false. diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index e60826b666..bf1c47a5ce 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -92,7 +92,7 @@ DXGI_FORMAT getFormat(u8 type, u8 size) } static -std::vector getIALayout(ID3D12Device *device, const std::vector &vertexBufferFormat, const RSXVertexData *m_vertex_data, size_t baseOffset) +std::vector getIALayout(ID3D12Device *device, const std::vector &vertexBufferFormat, const rsx::data_array_format_info *m_vertex_data, size_t baseOffset) { std::vector result; @@ -100,15 +100,17 @@ std::vector getIALayout(ID3D12Device *device, const st { for (size_t attributeId : vertexBufferFormat[inputSlot].attributeId) { - const RSXVertexData &vertexData = m_vertex_data[attributeId]; + u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 * attributeId]; + u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31); + const rsx::data_array_format_info &vertexData = m_vertex_data[attributeId]; D3D12_INPUT_ELEMENT_DESC IAElement = {}; IAElement.SemanticName = "TEXCOORD"; IAElement.SemanticIndex = (UINT)attributeId; IAElement.InputSlot = (UINT)inputSlot; IAElement.Format = getFormat(vertexData.type - 1, vertexData.size); - IAElement.AlignedByteOffset = (UINT)(vertexData.addr + baseOffset - vertexBufferFormat[inputSlot].range.first); - IAElement.InputSlotClass = (vertexData.addr > 0) ? D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; - IAElement.InstanceDataStepRate = (vertexData.addr > 0) ? 0 : 0; + IAElement.AlignedByteOffset = (UINT)(addr + baseOffset - vertexBufferFormat[inputSlot].range.first); + IAElement.InputSlotClass = (addr > 0) ? D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; + IAElement.InstanceDataStepRate = (addr > 0) ? 0 : 1; result.push_back(IAElement); } } @@ -122,7 +124,7 @@ std::vector getIALayout(ID3D12Device *device, const st * Suballocate a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap. */ static -D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, size_t baseOffset, ID3D12Device *device, DataHeap &vertexIndexHeap) +D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, const rsx::data_array_format_info *vertex_array_desc, const std::vector *vertex_data, size_t baseOffset, ID3D12Device *device, DataHeap &vertexIndexHeap) { size_t subBufferSize = vbf.range.second - vbf.range.first + 1; // Make multiple of stride @@ -134,7 +136,7 @@ D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, cons void *buffer; ThrowIfFailed(vertexIndexHeap.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); void *bufferMap = (char*)buffer + heapOffset; - uploadVertexData(vbf, vertexData, baseOffset, bufferMap); + uploadVertexData(vbf, vertex_array_desc, vertex_data, baseOffset, bufferMap); vertexIndexHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); return vertexIndexHeap.m_heap->GetGPUVirtualAddress() + heapOffset; } @@ -142,8 +144,8 @@ D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, cons std::vector D3D12GSRender::UploadVertexBuffers(bool indexed_draw) { std::vector result; - const std::vector &vertexBufferFormat = FormatVertexData(m_vertex_data, m_vertexBufferSize, m_vertex_data_base_offset); - m_IASet = getIALayout(m_device.Get(), vertexBufferFormat, m_vertex_data, m_vertex_data_base_offset); + const std::vector &vertexBufferFormat = FormatVertexData(vertex_arrays_info, vertex_arrays, m_vertexBufferSize, m_vertex_data_base_offset); + m_IASet = getIALayout(m_device.Get(), vertexBufferFormat, vertex_arrays_info, m_vertex_data_base_offset); const u32 data_offset = indexed_draw ? 0 : draw_array_first; @@ -155,7 +157,7 @@ std::vector D3D12GSRender::UploadVertexBuffers(bool in if (vbf.stride) subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride; - D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(vbf, m_vertex_data, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData); + D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(vbf, vertex_arrays_info, vertex_arrays, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData); m_timers.m_bufferUploadSize += subBufferSize; D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.h b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.h index cb363e0f6d..b884b072a9 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.h @@ -4,6 +4,6 @@ #include "Emu/Memory/vm.h" #include "Emu/RSX/RSXThread.h" -std::vector getIALayout(ID3D12Device *device, bool indexedDraw, const RSXVertexData *vertexData); +std::vector getIALayout(ID3D12Device *device, bool indexedDraw, const rsx::data_array_format_info *vertexData); #endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 8aaa8b78bd..f5f2d28224 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -404,22 +404,22 @@ void D3D12GSRender::end() { for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - if (!m_vertex_data[i].IsEnabled()) continue; - if (!m_vertex_data[i].addr) continue; + if (!vertex_arrays_info[i].size) continue; + if (!vertex_arrays_info[i].array) continue; - const u32 tsize = rsx::get_vertex_type_size(m_vertex_data[i].type); - m_vertexBufferSize[i] = (m_indexed_array.index_min + m_indexed_array.index_max - m_indexed_array.index_min + 1) * tsize * m_vertex_data[i].size; + const u32 tsize = rsx::get_vertex_type_size(vertex_arrays_info[i].type); + m_vertexBufferSize[i] = (m_indexed_array.index_min + m_indexed_array.index_max - m_indexed_array.index_min + 1) * tsize * vertex_arrays_info[i].size; } } else { for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - if (!m_vertex_data[i].IsEnabled()) continue; - if (!m_vertex_data[i].addr) continue; + if (!vertex_arrays_info[i].size) continue; + if (!vertex_arrays_info[i].array) continue; - const u32 tsize = rsx::get_vertex_type_size(m_vertex_data[i].type); - m_vertexBufferSize[i] = (draw_array_first + draw_array_count) * tsize * m_vertex_data[i].size; + const u32 tsize = rsx::get_vertex_type_size(vertex_arrays_info[i].type); + m_vertexBufferSize[i] = (draw_array_first + draw_array_count) * tsize * vertex_arrays_info[i].size; } } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 249ddc282a..a3381f1853 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -840,14 +840,14 @@ void GLGSRender::EnableVertexData(bool indexed_draw) offset_list[i] = cur_offset; - if (!m_vertex_data[i].IsEnabled()) continue; +/* if (!m_vertex_data[i].IsEnabled()) continue; const size_t item_size = rsx::get_vertex_type_size(m_vertex_data[i].type) * m_vertex_data[i].size; const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size; const u32 pos = m_vdata.size(); cur_offset += data_size; m_vdata.resize(m_vdata.size() + data_size); - memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size); + memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size);*/ } m_vao.Create(); @@ -872,7 +872,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw) for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - if (!m_vertex_data[i].IsEnabled()) continue; +// if (!m_vertex_data[i].IsEnabled()) continue; #if DUMP_VERTEX_DATA dump.Write(wxString::Format("VertexData[%d]:\n", i)); @@ -958,7 +958,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw) GL_FALSE, }; - if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7) +/* if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7) { LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type); } @@ -1005,7 +1005,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw) checkForGlError("glEnableVertexAttribArray"); glVertexAttribPointer(i, m_vertex_data[i].size, gltype, normalized, 0, reinterpret_cast(offset_list[i])); checkForGlError("glVertexAttribPointer"); - } + }*/ } } @@ -1014,7 +1014,7 @@ void GLGSRender::DisableVertexData() m_vdata.clear(); for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - if (!m_vertex_data[i].IsEnabled()) continue; +// if (!m_vertex_data[i].IsEnabled()) continue; glDisableVertexAttribArray(i); checkForGlError("glDisableVertexAttribArray"); } @@ -1647,7 +1647,7 @@ void GLGSRender::end() if (!m_indexed_array.m_count && !draw_array_count) { u32 min_vertex_size = ~0; - for (auto &i : m_vertex_data) +/* for (auto &i : m_vertex_data) { if (!i.size) continue; @@ -1656,7 +1656,7 @@ void GLGSRender::end() if (min_vertex_size > vertex_size) min_vertex_size = vertex_size; - } + }*/ draw_array_count = min_vertex_size; draw_array_first = 0; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 957d03ca4a..b34a0374c9 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -28,6 +28,91 @@ namespace rsx { u32 method_registers[0x10000 >> 2]; + template struct vertex_data_type_from_element_type; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_F }; }; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_SF }; }; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_UB }; }; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_S1 }; }; + + namespace nv4097 + { + //fire only when all data passed to rsx cmd buffer + template + force_inline void set_vertex_data_impl(RSXThread* rsx, u32 arg) + { + static const size_t element_size = (count * sizeof(type)); + static const size_t element_size_in_words = element_size / sizeof(u32); + + auto& info = rsx->vertex_arrays_info[index]; + + info.type = vertex_data_type_from_element_type::type; + info.size = count; + info.frequency = 0; + info.stride = 0; + info.array = false; + + auto& entry = rsx->vertex_arrays[index]; + + //find begin of data + size_t begin = id + index * element_size_in_words; + + size_t position = entry.size(); + entry.resize(position + element_size); + + memcpy(entry.data() + position, method_registers + begin, element_size); + } + + template + force_inline void set_vertex_data4ub_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data1f_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data2f_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data3f_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data4f_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data2s_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data4s_m(RSXThread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + force_inline void set_vertex_data_array_format(RSXThread* rsx, u32 arg) + { + auto& info = rsx->vertex_arrays_info[index]; + info.unpack(arg); + info.array = info.size > 0; + } + } + u32 linear_to_swizzle(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) { u32 offset = 0; @@ -120,66 +205,6 @@ namespace rsx } } -RSXVertexData::RSXVertexData() - : frequency(0) - , stride(0) - , size(0) - , type(0) - , addr(0) - , data() -{ -} - -void RSXVertexData::Reset() -{ - frequency = 0; - stride = 0; - size = 0; - type = 0; - addr = 0; - data.clear(); -} - -void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex = 0) -{ - if (!addr) return; - - const u32 tsize = rsx::get_vertex_type_size(type); - - data.resize((start + count) * tsize * size); - - for (u32 i = start; i < start + count; ++i) - { - auto src = vm::get_ptr(addr + baseOffset + stride * (i + baseIndex)); - u8* dst = &data[i * tsize * size]; - - switch (tsize) - { - case 1: - { - memcpy(dst, src, size); - break; - } - - case 2: - { - auto c_src = (const be_t*)src; - auto c_dst = (u16*)dst; - for (u32 j = 0; j < size; ++j) *c_dst++ = *c_src++; - break; - } - - case 4: - { - auto c_src = (const be_t*)src; - auto c_dst = (u32*)dst; - for (u32 j = 0; j < size; ++j) *c_dst++ = *c_src++; - break; - } - } - } -} - u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr) { auto args = vm::ps3::ptr::make(args_addr); @@ -440,99 +465,61 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const break; } +#define bind_2(index, offset, step, func) \ + case offset : \ + func(this, ARGS(0)); \ + break; \ + case offset + step: \ + func(this, ARGS(0)); \ + break; + +#define bind_4(index, offset, step, func) \ + bind_2(index, offset, step, func); \ + bind_2(index + 2, offset + 2*step, step, func) + +#define bind_8(index, offset, step, func) \ + bind_4(index, offset, step, func); \ + bind_4(index + 4, offset + 4*step, step, func) + +#define bind_16(index, offset, step, func) \ + bind_8(index, offset, step, func); \ + bind_8(index + 8, offset + 8*step, step, func) + +#define bind_32(index, offset, step, func) \ + bind_16(index, offset, step, func); \ + bind_16(index + 16, offset + 16*step, step, func) + +#define bind_64(index, offset, step, func) \ + bind_32(index, offset, step, func); \ + bind_32(index + 32, offset + 32*step, step, func) + +#define bind_128(index, offset, step, func) \ + bind_64(index, offset, step, func); \ + bind_64(index + 64, offset + 64*step, step, func) + +#define bind_256(index, offset, step, func) \ + bind_128(index, offset, step, func); \ + bind_128(index + 128, offset + 128*step, step, func) + +#define bind_512(index, offset, step, func) \ + bind_256(index, offset, step, func); \ + bind_256(index + 256, offset + 256*step, step, func) + // Vertex data - case_range(16, NV4097_SET_VERTEX_DATA4UB_M, 4); - { - const u32 a0 = ARGS(0); - u8 v0 = a0; - u8 v1 = a0 >> 8; - u8 v2 = a0 >> 16; - u8 v3 = a0 >> 24; - - m_vertex_data[index].Reset(); - m_vertex_data[index].size = 4; - m_vertex_data[index].type = CELL_GCM_VERTEX_UB; - m_vertex_data[index].data.push_back(v0); - m_vertex_data[index].data.push_back(v1); - m_vertex_data[index].data.push_back(v2); - m_vertex_data[index].data.push_back(v3); - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA4UB_M: index = %d, v0 = 0x%x, v1 = 0x%x, v2 = 0x%x, v3 = 0x%x", index, v0, v1, v2, v3); - break; - } - - case_range(16, NV4097_SET_VERTEX_DATA2F_M, 8); - { - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - - float v0 = (float&)a0; - float v1 = (float&)a1; - - m_vertex_data[index].Reset(); - m_vertex_data[index].type = CELL_GCM_VERTEX_F; - m_vertex_data[index].size = 2; - u32 pos = m_vertex_data[index].data.size(); - m_vertex_data[index].data.resize(pos + sizeof(float) * 2); - (float&)m_vertex_data[index].data[pos + sizeof(float) * 0] = v0; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 1] = v1; - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA2F_M: index = %d, v0 = %f, v1 = %f", index, v0, v1); - break; - } - - case_range(16, NV4097_SET_VERTEX_DATA4F_M, 16); - { - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - const u32 a2 = ARGS(2); - const u32 a3 = ARGS(3); - - float v0 = (float&)a0; - float v1 = (float&)a1; - float v2 = (float&)a2; - float v3 = (float&)a3; - - m_vertex_data[index].Reset(); - m_vertex_data[index].type = CELL_GCM_VERTEX_F; - m_vertex_data[index].size = 4; - u32 pos = m_vertex_data[index].data.size(); - m_vertex_data[index].data.resize(pos + sizeof(float) * 4); - (float&)m_vertex_data[index].data[pos + sizeof(float) * 0] = v0; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 1] = v1; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 2] = v2; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 3] = v3; - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA4F_M: index = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f", index, v0, v1, v2, v3); - break; - } + bind_16(0, NV4097_SET_VERTEX_DATA4UB_M, 4, rsx::nv4097::set_vertex_data4ub_m); + bind_16(0, NV4097_SET_VERTEX_DATA2F_M, 8, rsx::nv4097::set_vertex_data2f_m); + bind_16(0, NV4097_SET_VERTEX_DATA4F_M, 16, rsx::nv4097::set_vertex_data4f_m); case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4); - { - const u32 addr = rsx::get_address(ARGS(0) & 0x7fffffff, ARGS(0) >> 31); - - m_vertex_data[index].addr = addr; - m_vertex_data[index].data.clear(); - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET: num=%d, addr=0x%x", index, addr); break; - } case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4); { const u32 a0 = ARGS(0); - u16 frequency = a0 >> 16; - u8 stride = (a0 >> 8) & 0xff; - u8 size = (a0 >> 4) & 0xf; - u8 type = a0 & 0xf; - RSXVertexData& cv = m_vertex_data[index]; - cv.frequency = frequency; - cv.stride = stride; - cv.size = size; - cv.type = type; - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT: index=%d, frequency=%d, stride=%d, size=%d, type=%d", index, frequency, stride, size, type); + rsx::data_array_format_info &cv = vertex_arrays_info[index]; + cv.unpack(a0); + cv.array = cv.size > 0; break; } @@ -948,12 +935,13 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if (!m_indexed_array.m_count && !draw_array_count) { u32 min_vertex_size = ~0; - for (auto &i : m_vertex_data) + for (unsigned id = 0; id < rsx::limits::vertex_count; id++) { + auto &i = vertex_arrays_info[id]; if (!i.size) continue; - u32 vertex_size = i.data.size() / (i.size * rsx::get_vertex_type_size(i.type)); + u32 vertex_size = vertex_arrays[id].size() / (i.size * rsx::get_vertex_type_size(i.type)); if (min_vertex_size > vertex_size) min_vertex_size = vertex_size; @@ -2183,9 +2171,9 @@ void RSXThread::End() { end(); - for (auto &vdata : m_vertex_data) + for (auto &vdata : vertex_arrays) { - vdata.data.clear(); + vdata.clear(); } m_indexed_array.Reset(); diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index f59b907a1c..bfe962c2a0 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -59,6 +59,23 @@ namespace rsx height = 1 << (u32(log2width) + 1); } }; + + struct data_array_format_info + { + u16 frequency = 0; + u8 stride = 0; + u8 size = 0; + u8 type = CELL_GCM_VERTEX_F; + bool array = false; + + void unpack(u32 data_array_format) + { + frequency = data_array_format >> 16; + stride = (data_array_format >> 8) & 0xff; + size = (data_array_format >> 4) & 0xf; + type = data_array_format & 0xf; + } + }; } enum Method @@ -69,24 +86,6 @@ enum Method CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, }; -struct RSXVertexData -{ - u32 frequency; - u32 stride; - u32 size; - u32 type; - u32 addr; - u32 constant_count; - - std::vector data; - - RSXVertexData(); - - void Reset(); - bool IsEnabled() const { return size > 0; } - void Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex); -}; - struct RSXIndexArrayData { std::vector m_data; @@ -149,7 +148,9 @@ public: GcmZcullInfo zculls[rsx::limits::zculls_count]; rsx::texture textures[rsx::limits::textures_count]; rsx::vertex_texture m_vertex_textures[rsx::limits::vertex_textures_count]; - RSXVertexData m_vertex_data[rsx::limits::vertex_count]; + + rsx::data_array_format_info vertex_arrays_info[rsx::limits::vertex_count]; + std::vector vertex_arrays[rsx::limits::vertex_count]; RSXIndexArrayData m_indexed_array; std::vector m_fragment_constants; std::vector m_transform_constants; @@ -603,9 +604,9 @@ protected: { for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - if (!m_vertex_data[i].IsEnabled()) continue; +// if (!m_vertex_data[i].IsEnabled()) continue; - m_vertex_data[i].Load(first, count, m_vertex_data_base_offset, m_vertex_data_base_index); +// m_vertex_data[i].Load(first, count, m_vertex_data_base_offset, m_vertex_data_base_index); } }