d3d12: Read constants directly from fp

This commit is contained in:
vlj 2015-05-16 19:10:38 +02:00 committed by Vincent Lejeune
parent 7b6ad026c6
commit c3e162b442
4 changed files with 49 additions and 32 deletions

View File

@ -431,15 +431,24 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer()
void D3D12GSRender::FillPixelShaderConstantsBuffer() void D3D12GSRender::FillPixelShaderConstantsBuffer()
{ {
// Get constant from fragment program
const std::vector<size_t> &fragmentOffset = m_cachePSO.getFragmentConstantOffsetsCache(m_cur_fragment_prog);
size_t offset = 0; size_t offset = 0;
void *constantsBufferMap; void *constantsBufferMap;
check(m_constantsFragmentBuffer->Map(0, nullptr, &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; auto data = vm::ptr<u32>::make(m_cur_fragment_prog->addr + (u32)offsetInFP);
float vector[] = { c.x, c.y, c.z, c.w };
memcpy((char*)constantsBufferMap + constantsFragmentSize + offset, vector, 4 * sizeof(float)); u32 c0 = (data[0] >> 16 | data[0] << 16);
offset += 4 * sizeof(float); 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); m_constantsFragmentBuffer->Unmap(0, nullptr);
// Multiple of 256 // Multiple of 256
@ -540,24 +549,6 @@ void D3D12GSRender::ExecCMD()
assert((m_draw_array_first + m_draw_array_count) * item_size <= m_vertexBufferSize[i]); assert((m_draw_array_first + m_draw_array_count) * item_size <= m_vertexBufferSize[i]);
} }
commandList->IASetVertexBuffers(0, (UINT)vertexBufferViews.size(), vertexBufferViews.data()); 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()) if (!LoadProgram())
@ -566,6 +557,25 @@ void D3D12GSRender::ExecCMD()
Emu.Pause(); Emu.Pause();
return; 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); commandList->SetPipelineState(m_PSO);
InitDrawBuffers(); InitDrawBuffers();

View File

@ -65,6 +65,15 @@ struct D3D12Traits
const std::string &shader = FS.Decompile(); const std::string &shader = FS.Decompile();
fragmentProgramData.Compile(shader, Shader::SHADER_TYPE::SHADER_TYPE_FRAGMENT); 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 // TODO: This shouldn't use current dir
fs::file("./FragmentProgram.hlsl", o_write | o_create | o_trunc).write(shader.c_str(), shader.size()); fs::file("./FragmentProgram.hlsl", o_write | o_create | o_trunc).write(shader.c_str(), shader.size());
fragmentProgramData.Id = (u32)ID; fragmentProgramData.Id = (u32)ID;

View File

@ -368,16 +368,14 @@ std::string FragmentDecompiler::BuildCode()
std::stringstream OS; std::stringstream OS;
insertHeader(OS); insertHeader(OS);
OS << std::endl; OS << std::endl;
insertConstants(OS);
OS << std::endl; OS << std::endl;
insertIntputs(OS); insertIntputs(OS);
OS << std::endl; OS << std::endl;
insertOutputs(OS); insertOutputs(OS);
OS << std::endl; OS << std::endl;
insertMainStart(OS); insertMainStart(OS);
insertConstants(OS);
OS << main << std::endl; OS << main << std::endl;
insertMainEnd(OS); insertMainEnd(OS);
return OS.str(); return OS.str();
@ -434,20 +432,20 @@ void FragmentDecompiler::insertOutputs(std::stringstream & OS)
void FragmentDecompiler::insertConstants(std::stringstream & OS) void FragmentDecompiler::insertConstants(std::stringstream & OS)
{ {
// TODO : Avoid constant recompilation and properly use constant buffer // 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; 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) for (ParamItem PI : PT.items)
OS << " " << PT.type << " " << PI.name << ";" << std::endl; 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) for (ParamItem PI : PT.items)
OS << PT.type << " " << PI.name << " = " << PI.value << ";" << std::endl; OS << PT.type << " " << PI.name << " = " << PI.value << ";" << std::endl;
} }*/
} }
void FragmentDecompiler::insertMainStart(std::stringstream & OS) void FragmentDecompiler::insertMainStart(std::stringstream & OS)

View File

@ -7,7 +7,6 @@
class FragmentDecompiler class FragmentDecompiler
{ {
std::string main; std::string main;
ParamArray m_parr;
u32 m_addr; u32 m_addr;
u32& m_size; u32& m_size;
u32 m_const_index; u32 m_const_index;
@ -44,6 +43,7 @@ protected:
virtual void insertMainStart(std::stringstream &OS); virtual void insertMainStart(std::stringstream &OS);
virtual void insertMainEnd(std::stringstream &OS); virtual void insertMainEnd(std::stringstream &OS);
public: public:
ParamArray m_parr;
FragmentDecompiler(u32 addr, u32& size, u32 ctrl); FragmentDecompiler(u32 addr, u32& size, u32 ctrl);
std::string Decompile(); std::string Decompile();
}; };