diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 753c28d3d9..1d5714ea25 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -75,11 +75,12 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device) check(device->CreateHeap(&heapDescription, IID_PPV_ARGS(&m_textureStorage))); D3D12_DESCRIPTOR_HEAP_DESC textureDescriptorDesc = {}; - textureDescriptorDesc.NumDescriptors = 2048; // For safety + textureDescriptorDesc.NumDescriptors = 10000; // For safety textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; textureDescriptorDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_textureDescriptorsHeap))); + textureDescriptorDesc.NumDescriptors = 2048; // For safety textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap))); } @@ -230,55 +231,58 @@ D3D12GSRender::D3D12GSRender() m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_backbufferAsRendertarget[1])); m_device->CreateRenderTargetView(m_backBuffer[1], &rttDesc, m_backbufferAsRendertarget[1]->GetCPUDescriptorHandleForHeapStart()); - // Common root signature - D3D12_DESCRIPTOR_RANGE descriptorRange[4] = {}; - // Scale Offset data - descriptorRange[0].BaseShaderRegister = 0; - descriptorRange[0].NumDescriptors = 1; - descriptorRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; - // Constants - descriptorRange[1].BaseShaderRegister = 1; - descriptorRange[1].NumDescriptors = 2; - descriptorRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; - // Textures - descriptorRange[2].BaseShaderRegister = 0; - descriptorRange[2].NumDescriptors = 16; - descriptorRange[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - // Samplers - descriptorRange[3].BaseShaderRegister = 0; - descriptorRange[3].NumDescriptors = 16; - descriptorRange[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; - D3D12_ROOT_PARAMETER RP[4] = {}; - RP[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - RP[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - RP[0].DescriptorTable.pDescriptorRanges = &descriptorRange[0]; - RP[0].DescriptorTable.NumDescriptorRanges = 1; - RP[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - RP[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - RP[1].DescriptorTable.pDescriptorRanges = &descriptorRange[1]; - RP[1].DescriptorTable.NumDescriptorRanges = 1; - RP[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - RP[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - RP[2].DescriptorTable.pDescriptorRanges = &descriptorRange[2]; - RP[2].DescriptorTable.NumDescriptorRanges = 1; - RP[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - RP[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - RP[3].DescriptorTable.pDescriptorRanges = &descriptorRange[3]; - RP[3].DescriptorTable.NumDescriptorRanges = 1; + // Common root signatures + for (unsigned textureCount = 0; textureCount < 17; textureCount++) + { + D3D12_DESCRIPTOR_RANGE descriptorRange[4] = {}; + // Scale Offset data + descriptorRange[0].BaseShaderRegister = 0; + descriptorRange[0].NumDescriptors = 1; + descriptorRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + // Constants + descriptorRange[1].BaseShaderRegister = 1; + descriptorRange[1].NumDescriptors = 2; + descriptorRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + // Textures + descriptorRange[2].BaseShaderRegister = 0; + descriptorRange[2].NumDescriptors = textureCount; + descriptorRange[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + // Samplers + descriptorRange[3].BaseShaderRegister = 0; + descriptorRange[3].NumDescriptors = textureCount; + descriptorRange[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + D3D12_ROOT_PARAMETER RP[4] = {}; + RP[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + RP[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + RP[0].DescriptorTable.pDescriptorRanges = &descriptorRange[0]; + RP[0].DescriptorTable.NumDescriptorRanges = 1; + RP[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + RP[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + RP[1].DescriptorTable.pDescriptorRanges = &descriptorRange[1]; + RP[1].DescriptorTable.NumDescriptorRanges = 1; + RP[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + RP[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + RP[2].DescriptorTable.pDescriptorRanges = &descriptorRange[2]; + RP[2].DescriptorTable.NumDescriptorRanges = 1; + RP[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + RP[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + RP[3].DescriptorTable.pDescriptorRanges = &descriptorRange[3]; + RP[3].DescriptorTable.NumDescriptorRanges = 1; - D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = {}; - rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - rootSignatureDesc.NumParameters = 4; - rootSignatureDesc.pParameters = RP; + D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = {}; + rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + rootSignatureDesc.NumParameters = (textureCount > 0) ? 4 : 2; + rootSignatureDesc.pParameters = RP; - Microsoft::WRL::ComPtr rootSignatureBlob; - Microsoft::WRL::ComPtr errorBlob; - check(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); + Microsoft::WRL::ComPtr rootSignatureBlob; + Microsoft::WRL::ComPtr errorBlob; + check(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); - m_device->CreateRootSignature(0, - rootSignatureBlob->GetBufferPointer(), - rootSignatureBlob->GetBufferSize(), - IID_PPV_ARGS(&m_rootSignature)); + m_device->CreateRootSignature(0, + rootSignatureBlob->GetBufferPointer(), + rootSignatureBlob->GetBufferSize(), + IID_PPV_ARGS(&m_rootSignatures[textureCount])); + } m_perFrameStorage.Init(m_device); m_perFrameStorage.Reset(); @@ -348,7 +352,8 @@ D3D12GSRender::~D3D12GSRender() m_backbufferAsRendertarget[1]->Release(); m_backBuffer[1]->Release(); m_rtts.Release(); - m_rootSignature->Release(); + for (unsigned i = 0; i < 17; i++) + m_rootSignatures[i]->Release(); m_swapChain->Release(); m_device->Release(); delete[] vertexConstantShadowCopy; @@ -625,7 +630,7 @@ bool D3D12GSRender::LoadProgram() prop.IASet = m_IASet; - m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device, m_rootSignature)); + m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device, m_rootSignatures)); return m_PSO != nullptr; } @@ -637,8 +642,6 @@ void D3D12GSRender::ExecCMD() m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_perFrameStorage.m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList)); m_perFrameStorage.m_inflightCommandList.push_back(commandList); - commandList->SetGraphicsRootSignature(m_rootSignature); - if (m_indexed_array.m_count) LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); @@ -657,6 +660,8 @@ void D3D12GSRender::ExecCMD() return; } + commandList->SetGraphicsRootSignature(m_rootSignatures[m_PSO->second]); + // Constants setScaleOffset(); commandList->SetDescriptorHeaps(1, &m_perFrameStorage.m_scaleOffsetDescriptorHeap); @@ -675,43 +680,46 @@ void D3D12GSRender::ExecCMD() Handle = m_perFrameStorage.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->first); - size_t usedTexture = UploadTextures(); - // Drivers don't like undefined texture descriptors - for (; usedTexture < 16; usedTexture++) + if (m_PSO->second > 0) { - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srvDesc.Texture2D.MipLevels = 1; - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_perFrameStorage.m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += (m_perFrameStorage.m_currentTextureIndex + usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - m_device->CreateShaderResourceView(m_dummyTexture, &srvDesc, Handle); + size_t usedTexture = UploadTextures(); + // Drivers don't like undefined texture descriptors + /* for (; usedTexture < 16; usedTexture++) + { + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.Texture2D.MipLevels = 1; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_perFrameStorage.m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); + Handle.ptr += (m_perFrameStorage.m_currentTextureIndex + usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + m_device->CreateShaderResourceView(m_dummyTexture, &srvDesc, Handle); - D3D12_SAMPLER_DESC samplerDesc = {}; - samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; - samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - Handle = m_perFrameStorage.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += (m_perFrameStorage.m_currentTextureIndex + usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - m_device->CreateSampler(&samplerDesc, Handle); + D3D12_SAMPLER_DESC samplerDesc = {}; + samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + Handle = m_perFrameStorage.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + Handle.ptr += (usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + m_device->CreateSampler(&samplerDesc, Handle); + }*/ + + Handle = m_perFrameStorage.m_textureDescriptorsHeap->GetGPUDescriptorHandleForHeapStart(); + Handle.ptr += m_perFrameStorage.m_currentTextureIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + commandList->SetDescriptorHeaps(1, &m_perFrameStorage.m_textureDescriptorsHeap); + commandList->SetGraphicsRootDescriptorTable(2, Handle); + + Handle = m_perFrameStorage.m_samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); + Handle.ptr += m_perFrameStorage.m_currentTextureIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + commandList->SetDescriptorHeaps(1, &m_perFrameStorage.m_samplerDescriptorHeap); + commandList->SetGraphicsRootDescriptorTable(3, Handle); + + m_perFrameStorage.m_currentTextureIndex += usedTexture; } - Handle = m_perFrameStorage.m_textureDescriptorsHeap->GetGPUDescriptorHandleForHeapStart(); - Handle.ptr += m_perFrameStorage.m_currentTextureIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - commandList->SetDescriptorHeaps(1, &m_perFrameStorage.m_textureDescriptorsHeap); - commandList->SetGraphicsRootDescriptorTable(2, Handle); - - Handle = m_perFrameStorage.m_samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); - Handle.ptr += m_perFrameStorage.m_currentTextureIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - commandList->SetDescriptorHeaps(1, &m_perFrameStorage.m_samplerDescriptorHeap); - commandList->SetGraphicsRootDescriptorTable(3, Handle); - - m_perFrameStorage.m_currentTextureIndex += usedTexture; - size_t numRTT; switch (m_surface_color_target) { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 051e97fe58..80e3658444 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -54,8 +54,9 @@ private: // std::vector m_post_draw_objs; PipelineStateObjectCache m_cachePSO; - ID3D12PipelineState *m_PSO; - ID3D12RootSignature *m_rootSignature; + std::pair *m_PSO; + // m_rootSignatures[N] is RS with N texture/sample + ID3D12RootSignature *m_rootSignatures[17]; ID3D12PipelineState *m_convertPSO; ID3D12RootSignature *m_convertRootSignature; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index 87756bc625..c264220385 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -44,6 +44,7 @@ public: u32 Id; Microsoft::WRL::ComPtr bytecode; std::vector FragmentConstantOffsetCache; + size_t m_textureCount; /** * Decompile a fragment shader located in the PS3's Memory. This function operates synchronously. @@ -59,9 +60,9 @@ struct D3D12Traits { typedef Shader VertexProgramData; typedef Shader FragmentProgramData; - typedef ID3D12PipelineState PipelineData; + typedef std::pair PipelineData; typedef D3D12PipelineProperties PipelineProperties; - typedef std::pair ExtraData; + typedef std::pair ExtraData; static void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID) @@ -69,12 +70,16 @@ struct D3D12Traits D3D12FragmentDecompiler FS(RSXFP->addr, RSXFP->size, RSXFP->offset); const std::string &shader = FS.Decompile(); fragmentProgramData.Compile(shader, Shader::SHADER_TYPE::SHADER_TYPE_FRAGMENT); - + fragmentProgramData.m_textureCount = 0; for (const ParamType& PT : FS.m_parr.params[PF_PARAM_UNIFORM]) { - if (PT.type == "sampler2D") continue; for (const ParamItem PI : PT.items) { + if (PT.type == "sampler2D") + { + fragmentProgramData.m_textureCount++; + continue; + } size_t offset = atoi(PI.name.c_str() + 2); fragmentProgramData.FragmentConstantOffsetCache.push_back(offset); } @@ -102,7 +107,8 @@ struct D3D12Traits static PipelineData *BuildProgram(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData) { - ID3D12PipelineState *result; + + std::pair *result = new std::pair(); D3D12_GRAPHICS_PIPELINE_STATE_DESC graphicPipelineStateDesc = {}; if (vertexProgramData.bytecode == nullptr) @@ -115,7 +121,8 @@ struct D3D12Traits graphicPipelineStateDesc.PS.BytecodeLength = fragmentProgramData.bytecode->GetBufferSize(); graphicPipelineStateDesc.PS.pShaderBytecode = fragmentProgramData.bytecode->GetBufferPointer(); - graphicPipelineStateDesc.pRootSignature = extraData.second; + graphicPipelineStateDesc.pRootSignature = extraData.second[fragmentProgramData.m_textureCount]; + result->second = fragmentProgramData.m_textureCount; // Sensible default value static D3D12_RASTERIZER_DESC CD3D12_RASTERIZER_DESC = @@ -161,14 +168,15 @@ struct D3D12Traits graphicPipelineStateDesc.SampleMask = UINT_MAX; graphicPipelineStateDesc.NodeMask = 1; - extraData.first->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&result)); + extraData.first->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&result->first)); return result; } static void DeleteProgram(PipelineData *ptr) { - ptr->Release(); + ptr->first->Release(); + delete ptr; } };