D3D12GSRender::D3D12GSRender() : GSRender(frame_type::DX12), m_d3d12_lib(), m_current_pso({}) { if (rpcs3::config.rsx.d3d12.debug_output.value()) { Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface; wrapD3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)); debugInterface->EnableDebugLayer(); } Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory; CHECK_HRESULT(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory))); // Create adapter ComPtr<IDXGIAdapter> adaptater = nullptr; CHECK_HRESULT(dxgi_factory->EnumAdapters(rpcs3::state.config.rsx.d3d12.adaptater.value(), adaptater.GetAddressOf())); CHECK_HRESULT(wrapD3D12CreateDevice(adaptater.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))); // Queues D3D12_COMMAND_QUEUE_DESC graphic_queue_desc = { D3D12_COMMAND_LIST_TYPE_DIRECT }; CHECK_HRESULT(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_command_queue.GetAddressOf()))); m_descriptor_stride_srv_cbv_uav = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); m_descriptor_stride_dsv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); m_descriptor_stride_rtv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); m_descriptor_stride_samplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); // Create swap chain and put them in a descriptor heap as rendertarget DXGI_SWAP_CHAIN_DESC swap_chain = {}; swap_chain.BufferCount = 2; swap_chain.Windowed = true; swap_chain.OutputWindow = (HWND)m_frame->handle(); swap_chain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swap_chain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain.SampleDesc.Count = 1; swap_chain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; swap_chain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; CHECK_HRESULT(dxgi_factory->CreateSwapChain(m_command_queue.Get(), &swap_chain, (IDXGISwapChain**)m_swap_chain.GetAddressOf())); m_swap_chain->GetBuffer(0, IID_PPV_ARGS(&m_backbuffer[0])); m_swap_chain->GetBuffer(1, IID_PPV_ARGS(&m_backbuffer[1])); D3D12_DESCRIPTOR_HEAP_DESC render_target_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; D3D12_RENDER_TARGET_VIEW_DESC renter_target_view_desc = {}; renter_target_view_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; renter_target_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbuffer_descriptor_heap[0])); m_device->CreateRenderTargetView(m_backbuffer[0].Get(), &renter_target_view_desc, m_backbuffer_descriptor_heap[0]->GetCPUDescriptorHandleForHeapStart()); m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbuffer_descriptor_heap[1])); m_device->CreateRenderTargetView(m_backbuffer[1].Get(), &renter_target_view_desc, m_backbuffer_descriptor_heap[1]->GetCPUDescriptorHandleForHeapStart()); // Common root signatures for (int vertex_buffer_count = 0; vertex_buffer_count < 17; vertex_buffer_count++) // Some app (naruto ultimate ninja storm 2) uses a shader without inputs... { for (unsigned texture_count = 0; texture_count < 17; texture_count++) { CD3DX12_DESCRIPTOR_RANGE descriptorRange[] = { // Vertex buffer CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, vertex_buffer_count, 0), // Scale Offset data CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0), // Constants CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 1), // Textures CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, texture_count, 16), // Samplers CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, texture_count, 0), }; CD3DX12_ROOT_PARAMETER RP[2]; UINT cbv_srv_uav_descriptor_size = 4; if (texture_count == 0) cbv_srv_uav_descriptor_size -= 1; if (vertex_buffer_count == 0) cbv_srv_uav_descriptor_size -= 1; RP[0].InitAsDescriptorTable(cbv_srv_uav_descriptor_size, (vertex_buffer_count > 0) ? &descriptorRange[0] : &descriptorRange[1]); RP[1].InitAsDescriptorTable(1, &descriptorRange[4]); Microsoft::WRL::ComPtr<ID3DBlob> rootSignatureBlob; Microsoft::WRL::ComPtr<ID3DBlob> errorBlob; CHECK_HRESULT(wrapD3D12SerializeRootSignature( &CD3DX12_ROOT_SIGNATURE_DESC((texture_count > 0) ? 2 : 1, RP, 0, 0), D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); m_device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(m_root_signatures[texture_count][vertex_buffer_count].GetAddressOf())); } } m_per_frame_storage[0].init(m_device.Get()); m_per_frame_storage[0].reset(); m_per_frame_storage[1].init(m_device.Get()); m_per_frame_storage[1].reset(); init_convert_shader(); m_output_scaling_pass.init(m_device.Get(), m_command_queue.Get()); CHECK_HRESULT( m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, 2, 2, 1, 1), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_dummy_texture)) ); m_rtts.init(m_device.Get()); m_readback_resources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST); m_buffer_data.init(m_device.Get(), 1024 * 1024 * 896, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); CHECK_HRESULT( m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(1024 * 1024 * 16), D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, nullptr, IID_PPV_ARGS(m_vertex_buffer_data.GetAddressOf()) ) ); if (rpcs3::config.rsx.d3d12.overlay.value()) init_d2d_structures(); }
void GltfPbr::CreatePipeline(ID3D12Device* pDevice, UINT node, std::vector<std::string> semanticNames, std::vector<D3D12_INPUT_ELEMENT_DESC> layout, PBRPrimitives *pPrimitive) { //================================================================================================= // let vertex shader know what buffers are present // The Shader Code glTF20_EX.hlsl has if defs that are enable using these attributes when compiled // and ref by the D3D12_GRAPHICS_PIPELINE_STATE_DESC //================================================================================================= bool Has_Normals = false; std::map<std::string, std::string> attributeDefines; for (unsigned int i = 0; i < layout.size(); i++) { layout[i].SemanticName = semanticNames[i].c_str(); attributeDefines[std::string("HAS_") + layout[i].SemanticName] = "1"; if (semanticNames[i].compare("NORMAL") == 0) Has_Normals = true; } // Compile shaders // ID3DBlob *pBlobShaderVert, *pBlobShaderPixel; { // build macro structure // std::vector<D3D_SHADER_MACRO> macros; CompileMacros(&attributeDefines, ¯os); CompileMacros(&pPrimitive->m_pMaterial->m_defines, ¯os); macros.push_back(D3D_SHADER_MACRO{ NULL, NULL }); ID3DBlob *pError; D3DCompileFromFile(L"./plugins/shaders/glTF20_EX.hlsl", macros.data(), nullptr, "mainVS", "vs_5_0", 0, 0, &pBlobShaderVert, &pError); D3DCompileFromFile(L"./plugins/shaders/glTF20_EX.hlsl", macros.data(), nullptr, "mainPS", "ps_5_0", 0, 0, &pBlobShaderPixel, &pError); if (pError != NULL) { char *msg = (char *)pError->GetBufferPointer(); MessageBoxA(0, msg, "", 0); } } // Create root signature // { CD3DX12_DESCRIPTOR_RANGE DescRange[4]; DescRange[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // b0 <- per frame DescRange[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, pPrimitive->m_pMaterial->m_textureCount, 0); // t0 <- per material DescRange[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1); // b1 <- per material parameters DescRange[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 5, 0); // s0 <- samplers CD3DX12_ROOT_PARAMETER RTSlot[4]; RTSlot[0].InitAsDescriptorTable(1, &DescRange[0], D3D12_SHADER_VISIBILITY_ALL); RTSlot[1].InitAsDescriptorTable(1, &DescRange[1], D3D12_SHADER_VISIBILITY_PIXEL); RTSlot[2].InitAsDescriptorTable(1, &DescRange[2], D3D12_SHADER_VISIBILITY_ALL); RTSlot[3].InitAsDescriptorTable(1, &DescRange[3], D3D12_SHADER_VISIBILITY_PIXEL); // the root signature contains 3 slots to be used CD3DX12_ROOT_SIGNATURE_DESC descRootSignature = CD3DX12_ROOT_SIGNATURE_DESC(); descRootSignature.NumParameters = 4; descRootSignature.pParameters = RTSlot; descRootSignature.NumStaticSamplers = 0; descRootSignature.pStaticSamplers = NULL; // deny uneccessary access to certain pipeline stages descRootSignature.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT //| D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; //| D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; ID3DBlob *pOutBlob, *pErrorBlob = NULL; ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, &pOutBlob, &pErrorBlob)); ThrowIfFailed( pDevice->CreateRootSignature( node, pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), IID_PPV_ARGS(&pPrimitive->m_RootSignature)) ); pPrimitive->m_RootSignature->SetName(L"OnCreatePrimitiveColorPass"); pOutBlob->Release(); if (pErrorBlob) pErrorBlob->Release(); } D3D12_RENDER_TARGET_BLEND_DESC blendingOpaque = D3D12_RENDER_TARGET_BLEND_DESC { FALSE,FALSE, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_LOGIC_OP_NOOP, D3D12_COLOR_WRITE_ENABLE_ALL, }; D3D12_RENDER_TARGET_BLEND_DESC blendingBlend = D3D12_RENDER_TARGET_BLEND_DESC { TRUE,FALSE, D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_LOGIC_OP_NOOP, D3D12_COLOR_WRITE_ENABLE_ALL, }; // Create a PSO description // if (!pBlobShaderVert || !pBlobShaderPixel) { throw 1; } D3D12_GRAPHICS_PIPELINE_STATE_DESC descPso = {}; descPso.InputLayout = { layout.data(), (UINT)layout.size() }; descPso.pRootSignature = pPrimitive->m_RootSignature.Get(); descPso.VS = { reinterpret_cast<BYTE*>(pBlobShaderVert->GetBufferPointer()), pBlobShaderVert->GetBufferSize() }; descPso.PS = { reinterpret_cast<BYTE*>(pBlobShaderPixel->GetBufferPointer()), pBlobShaderPixel->GetBufferSize() }; descPso.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); descPso.RasterizerState.CullMode = D3D12_CULL_MODE_FRONT; // Decide on default view based on attributes available if (m_pGLTFData) { if(m_pGLTFData->isBinFile) descPso.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME; else { if (Has_Normals) { descPso.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; } else descPso.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME; } } else { if (Has_Normals) { descPso.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; } else descPso.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME; } descPso.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); descPso.BlendState.IndependentBlendEnable = TRUE; descPso.BlendState.RenderTarget[0] = blendingBlend; descPso.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); descPso.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; descPso.SampleMask = UINT_MAX; descPso.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; descPso.NumRenderTargets = 1; descPso.RTVFormats[0] = DXGI_FORMAT_R16G16B16A16_UNORM; descPso.DSVFormat = DXGI_FORMAT_D32_FLOAT; descPso.SampleDesc.Count = 4; descPso.NodeMask = node; descPso.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; ThrowIfFailed( pDevice->CreateGraphicsPipelineState(&descPso, IID_PPV_ARGS(&pPrimitive->m_PipelineRender)) ); // create samplers if not initialized (this should happen once) if (m_sampler.GetSize()==0) { m_pResourceViewHeaps->AllocSamplerDescriptor(5, &m_sampler); //for pbr materials D3D12_SAMPLER_DESC SamplerDesc; ZeroMemory(&SamplerDesc, sizeof(SamplerDesc)); SamplerDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; SamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; SamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; SamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; SamplerDesc.BorderColor[0] = 0.0f; SamplerDesc.BorderColor[1] = 0.0f; SamplerDesc.BorderColor[2] = 0.0f; SamplerDesc.BorderColor[3] = 0.0f; SamplerDesc.MinLOD = 0.0f; SamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; SamplerDesc.MipLODBias = 0; SamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; SamplerDesc.MaxAnisotropy = 1; pDevice->CreateSampler(&SamplerDesc, m_sampler.GetCPU(0)); // diffuse env map sampler ZeroMemory(&SamplerDesc, sizeof(SamplerDesc)); SamplerDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; SamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; SamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; SamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; SamplerDesc.BorderColor[0] = 0.0f; SamplerDesc.BorderColor[1] = 0.0f; SamplerDesc.BorderColor[2] = 0.0f; SamplerDesc.BorderColor[3] = 0.0f; SamplerDesc.MinLOD = 0.0f; SamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; SamplerDesc.MipLODBias = 0; SamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; SamplerDesc.MaxAnisotropy = 1; pDevice->CreateSampler(&SamplerDesc, m_sampler.GetCPU(1)); // specular env map sampler ZeroMemory(&SamplerDesc, sizeof(SamplerDesc)); SamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; SamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; SamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; SamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; SamplerDesc.BorderColor[0] = 0.0f; SamplerDesc.BorderColor[1] = 0.0f; SamplerDesc.BorderColor[2] = 0.0f; SamplerDesc.BorderColor[3] = 0.0f; SamplerDesc.MinLOD = 0.0f; SamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; SamplerDesc.MipLODBias = 0; SamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; SamplerDesc.MaxAnisotropy = 1; pDevice->CreateSampler(&SamplerDesc, m_sampler.GetCPU(2)); // specular BRDF lut sampler ZeroMemory(&SamplerDesc, sizeof(SamplerDesc)); SamplerDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; SamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; SamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; SamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; SamplerDesc.BorderColor[0] = 0.0f; SamplerDesc.BorderColor[1] = 0.0f; SamplerDesc.BorderColor[2] = 0.0f; SamplerDesc.BorderColor[3] = 0.0f; SamplerDesc.MinLOD = 0.0f; SamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; SamplerDesc.MipLODBias = 0; SamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; SamplerDesc.MaxAnisotropy = 1; pDevice->CreateSampler(&SamplerDesc, m_sampler.GetCPU(3)); // specular BRDF lut sampler D3D12_SAMPLER_DESC samplerShadow = { D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, 0.0f, 1u, D3D12_COMPARISON_FUNC_LESS_EQUAL, { 0.0f, 0.0f, 0.0f, 0.0f }, 0.0f, D3D12_FLOAT32_MAX }; pDevice->CreateSampler(&samplerShadow, m_sampler.GetCPU(4)); } pPrimitive->m_sampler = &m_sampler; }
D3D12GSRender::D3D12GSRender() : GSRender(frame_type::DX12), m_D3D12Lib(), m_PSO(nullptr) { m_previous_address_a = 0; m_previous_address_b = 0; m_previous_address_c = 0; m_previous_address_d = 0; m_previous_address_z = 0; gfxHandler = [this](u32 addr) { bool result = invalidateAddress(addr); if (result) LOG_WARNING(RSX, "Reporting Cell writing to %x", addr); return result; }; if (rpcs3::config.rsx.d3d12.debug_output.value()) { Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface; wrapD3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)); debugInterface->EnableDebugLayer(); } Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory; ThrowIfFailed(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory))); // Create adapter ComPtr<IDXGIAdapter> adaptater = nullptr; ThrowIfFailed(dxgi_factory->EnumAdapters(rpcs3::state.config.rsx.d3d12.adaptater.value(), adaptater.GetAddressOf())); ThrowIfFailed(wrapD3D12CreateDevice(adaptater.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))); // Queues D3D12_COMMAND_QUEUE_DESC graphic_queue_desc = { D3D12_COMMAND_LIST_TYPE_DIRECT }; ThrowIfFailed(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_commandQueueGraphic.GetAddressOf()))); g_descriptorStrideSRVCBVUAV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); g_descriptorStrideDSV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); g_descriptorStrideRTV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); g_descriptorStrideSamplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); // Create swap chain and put them in a descriptor heap as rendertarget DXGI_SWAP_CHAIN_DESC swap_chain = {}; swap_chain.BufferCount = 2; swap_chain.Windowed = true; swap_chain.OutputWindow = (HWND)m_frame->handle(); swap_chain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swap_chain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain.SampleDesc.Count = 1; swap_chain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; swap_chain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; ThrowIfFailed(dxgi_factory->CreateSwapChain(m_commandQueueGraphic.Get(), &swap_chain, (IDXGISwapChain**)m_swapChain.GetAddressOf())); m_swapChain->GetBuffer(0, IID_PPV_ARGS(&m_backBuffer[0])); m_swapChain->GetBuffer(1, IID_PPV_ARGS(&m_backBuffer[1])); D3D12_DESCRIPTOR_HEAP_DESC render_target_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; D3D12_RENDER_TARGET_VIEW_DESC renter_target_view_desc = {}; renter_target_view_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; renter_target_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbufferAsRendertarget[0])); m_device->CreateRenderTargetView(m_backBuffer[0].Get(), &renter_target_view_desc, m_backbufferAsRendertarget[0]->GetCPUDescriptorHandleForHeapStart()); m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbufferAsRendertarget[1])); m_device->CreateRenderTargetView(m_backBuffer[1].Get(), &renter_target_view_desc, m_backbufferAsRendertarget[1]->GetCPUDescriptorHandleForHeapStart()); // Common root signatures for (unsigned texture_count = 0; texture_count < 17; texture_count++) { CD3DX12_DESCRIPTOR_RANGE descriptorRange[] = { // Scale Offset data CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0), // Constants CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 1), // Textures CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, texture_count, 0), // Samplers CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, texture_count, 0), }; CD3DX12_ROOT_PARAMETER RP[2]; RP[0].InitAsDescriptorTable((texture_count > 0) ? 3 : 2, &descriptorRange[0]); RP[1].InitAsDescriptorTable(1, &descriptorRange[3]); Microsoft::WRL::ComPtr<ID3DBlob> rootSignatureBlob; Microsoft::WRL::ComPtr<ID3DBlob> errorBlob; ThrowIfFailed(wrapD3D12SerializeRootSignature( &CD3DX12_ROOT_SIGNATURE_DESC((texture_count > 0) ? 2 : 1, RP, 0, 0, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); m_device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(m_rootSignatures[texture_count].GetAddressOf())); } m_perFrameStorage[0].init(m_device.Get()); m_perFrameStorage[0].reset(); m_perFrameStorage[1].init(m_device.Get()); m_perFrameStorage[1].reset(); initConvertShader(); m_outputScalingPass.Init(m_device.Get(), m_commandQueueGraphic.Get()); ThrowIfFailed( m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, 2, 2, 1, 1), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_dummyTexture)) ); m_readbackResources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); m_UAVHeap.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES); m_rtts.init(m_device.Get()); m_constantsData.init(m_device.Get(), 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); m_vertexIndexData.init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); m_textureUploadData.init(m_device.Get(), 1024 * 1024 * 512, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); if (rpcs3::config.rsx.d3d12.overlay.value()) init_d2d_structures(); }