diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index a3591f27ad..26993e9e8f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -431,15 +431,24 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer() void D3D12GSRender::FillPixelShaderConstantsBuffer() { + // Get constant from fragment program + const std::vector &fragmentOffset = m_cachePSO.getFragmentConstantOffsetsCache(m_cur_fragment_prog); + size_t offset = 0; void *constantsBufferMap; check(m_constantsFragmentBuffer->Map(0, nullptr, &constantsBufferMap)); - for (const RSXTransformConstant& c : m_fragment_constants) + for (size_t offsetInFP : fragmentOffset) { - u32 id = c.id - m_cur_fragment_prog->offset; - float vector[] = { c.x, c.y, c.z, c.w }; - memcpy((char*)constantsBufferMap + constantsFragmentSize + offset, vector, 4 * sizeof(float)); - offset += 4 * sizeof(float); + auto data = vm::ptr::make(m_cur_fragment_prog->addr + (u32)offsetInFP); + + 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); + + u32 vector[] = { c0, c1, c2, c3 }; + memcpy((char*)constantsBufferMap + constantsFragmentSize + offset, vector, 4 * sizeof(u32)); + offset += 4 * sizeof(u32); } m_constantsFragmentBuffer->Unmap(0, nullptr); // Multiple of 256 @@ -540,24 +549,6 @@ void D3D12GSRender::ExecCMD() assert((m_draw_array_first + m_draw_array_count) * item_size <= m_vertexBufferSize[i]); } commandList->IASetVertexBuffers(0, (UINT)vertexBufferViews.size(), vertexBufferViews.data()); - - setScaleOffset(); - commandList->SetDescriptorHeaps(1, &m_scaleOffsetDescriptorHeap); - D3D12_GPU_DESCRIPTOR_HANDLE Handle = m_scaleOffsetDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); - Handle.ptr += m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - commandList->SetGraphicsRootDescriptorTable(0, Handle); - m_currentScaleOffsetBufferIndex++; - - size_t currentBufferIndex = m_constantsBufferIndex; - FillVertexShaderConstantsBuffer(); - m_constantsBufferIndex++; - FillPixelShaderConstantsBuffer(); - m_constantsBufferIndex++; - - commandList->SetDescriptorHeaps(1, &m_constantsBufferDescriptorsHeap); - Handle = m_constantsBufferDescriptorsHeap->GetGPUDescriptorHandleForHeapStart(); - Handle.ptr += currentBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - commandList->SetGraphicsRootDescriptorTable(1, Handle); } if (!LoadProgram()) @@ -566,6 +557,25 @@ void D3D12GSRender::ExecCMD() Emu.Pause(); return; } + + // Constants + setScaleOffset(); + commandList->SetDescriptorHeaps(1, &m_scaleOffsetDescriptorHeap); + D3D12_GPU_DESCRIPTOR_HANDLE Handle = m_scaleOffsetDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); + Handle.ptr += m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + commandList->SetGraphicsRootDescriptorTable(0, Handle); + m_currentScaleOffsetBufferIndex++; + + size_t currentBufferIndex = m_constantsBufferIndex; + FillVertexShaderConstantsBuffer(); + m_constantsBufferIndex++; + FillPixelShaderConstantsBuffer(); + m_constantsBufferIndex++; + + commandList->SetDescriptorHeaps(1, &m_constantsBufferDescriptorsHeap); + Handle = m_constantsBufferDescriptorsHeap->GetGPUDescriptorHandleForHeapStart(); + Handle.ptr += currentBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + commandList->SetGraphicsRootDescriptorTable(1, Handle); commandList->SetPipelineState(m_PSO); InitDrawBuffers(); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index 3f454dc271..ec97c8006a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -65,6 +65,15 @@ struct D3D12Traits const std::string &shader = FS.Decompile(); fragmentProgramData.Compile(shader, Shader::SHADER_TYPE::SHADER_TYPE_FRAGMENT); + for (const ParamType& PT : FS.m_parr.params[PF_PARAM_UNIFORM]) + { + for (const ParamItem PI : PT.items) + { + size_t offset = atoi(PI.name.c_str() + 2); + fragmentProgramData.FragmentConstantOffsetCache.push_back(offset); + } + } + // TODO: This shouldn't use current dir fs::file("./FragmentProgram.hlsl", o_write | o_create | o_trunc).write(shader.c_str(), shader.size()); fragmentProgramData.Id = (u32)ID; diff --git a/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.cpp index 8a88a246e4..9d22dbb786 100644 --- a/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.cpp @@ -368,16 +368,14 @@ std::string FragmentDecompiler::BuildCode() std::stringstream OS; insertHeader(OS); OS << std::endl; - + insertConstants(OS); OS << std::endl; insertIntputs(OS); OS << std::endl; insertOutputs(OS); OS << std::endl; insertMainStart(OS); - insertConstants(OS); OS << main << std::endl; - insertMainEnd(OS); return OS.str(); @@ -434,20 +432,20 @@ void FragmentDecompiler::insertOutputs(std::stringstream & OS) void FragmentDecompiler::insertConstants(std::stringstream & OS) { // TODO : Avoid constant recompilation and properly use constant buffer -/* OS << "cbuffer CONSTANT : register(b2)" << std::endl; + OS << "cbuffer CONSTANT : register(b2)" << std::endl; OS << "{" << std::endl; - for (ParamType PT : m_parr.params[PARAM_UNIFORM]) + for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM]) { for (ParamItem PI : PT.items) OS << " " << PT.type << " " << PI.name << ";" << std::endl; } - OS << "};" << std::endl;*/ + OS << "};" << std::endl; - for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM]) +/* for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM]) { for (ParamItem PI : PT.items) OS << PT.type << " " << PI.name << " = " << PI.value << ";" << std::endl; - } + }*/ } void FragmentDecompiler::insertMainStart(std::stringstream & OS) diff --git a/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.h index 48f0791dc9..c0642a2051 100644 --- a/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/D3D12/FragmentProgramDecompiler.h @@ -7,7 +7,6 @@ class FragmentDecompiler { std::string main; - ParamArray m_parr; u32 m_addr; u32& m_size; u32 m_const_index; @@ -44,6 +43,7 @@ protected: virtual void insertMainStart(std::stringstream &OS); virtual void insertMainEnd(std::stringstream &OS); public: + ParamArray m_parr; FragmentDecompiler(u32 addr, u32& size, u32 ctrl); std::string Decompile(); };