From 2a9895b7f0bd8fa60cbb976e1575662edfeea79b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 31 Oct 2015 18:43:53 +0100 Subject: [PATCH] rsx/d3d12: Move fragment constants filling code to ProgramStateCache --- rpcs3/Emu/RSX/Common/ProgramStateCache.h | 30 ++++++++++++++++++++++++ rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 22 ++--------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index 7182796b5c..cfb07ff44d 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -337,6 +337,36 @@ public: return result; } + size_t get_fragment_constants_buffer_size(const RSXFragmentProgram *fragmentShader) const noexcept + { + typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(fragmentShader->addr)); + if (It != m_cacheFS.end()) + return It->second.FragmentConstantOffsetCache.size() * 4 * sizeof(float); + LOG_ERROR(RSX, "Can't retrieve constant offset cache"); + return 0; + } + + void fill_fragment_constans_buffer(void *buffer, const RSXFragmentProgram *fragment_program) const noexcept + { + typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(fragment_program->addr)); + if (It == m_cacheFS.end()) + return; + __m128i mask = _mm_set_epi8(0xE, 0xF, 0xC, 0xD, + 0xA, 0xB, 0x8, 0x9, + 0x6, 0x7, 0x4, 0x5, + 0x2, 0x3, 0x0, 0x1); + + size_t offset = 0; + for (size_t offset_in_fragment_program : It->second.FragmentConstantOffsetCache) + { + void *data = vm::base(fragment_program->addr + (u32)offset_in_fragment_program); + const __m128i &vector = _mm_loadu_si128((__m128i*)data); + const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask); + _mm_stream_si128((__m128i*)((char*)buffer + offset), shuffled_vector); + offset += 4 * sizeof(u32); + } + } + const std::vector &getFragmentConstantOffsetsCache(const RSXFragmentProgram *fragmentShader) const { typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(fragmentShader->addr)); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index e11ebe9f0b..09a0a685d6 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -189,8 +189,7 @@ void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_in void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_index) { // Get constant from fragment program - const std::vector &fragment_constant_offsets = m_cachePSO.getFragmentConstantOffsetsCache(&fragment_program); - size_t buffer_size = fragment_constant_offsets.size() * 4 * sizeof(float) + 1; + size_t buffer_size = m_cachePSO.get_fragment_constants_buffer_size(&fragment_program); // Multiple of 256 never 0 buffer_size = (buffer_size + 255) & ~255; @@ -200,24 +199,7 @@ void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_ size_t offset = 0; void *mapped_buffer; ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer)); - for (size_t offset_in_fragment_program : fragment_constant_offsets) - { - u32 vector[4]; - auto data = vm::ps3::ptr::make(fragment_program.addr + (u32)offset_in_fragment_program); - - u32 c0 = (data[0] >> 16 | data[0] << 16); - u32 c1 = (data[1] >> 16 | data[1] << 16); - u32 c2 = (data[2] >> 16 | data[2] << 16); - u32 c3 = (data[3] >> 16 | data[3] << 16); - - vector[0] = c0; - vector[1] = c1; - vector[2] = c2; - vector[3] = c3; - - streamToBuffer((char*)mapped_buffer + heap_offset + offset, vector, 4 * sizeof(u32)); - offset += 4 * sizeof(u32); - } + m_cachePSO.fill_fragment_constans_buffer((char*)mapped_buffer + heap_offset, &fragment_program); m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {