// Initialize the DirectX resources required to run. void Graphics::Initialize(void) { ASSERT(s_SwapChain1 == nullptr, "Graphics has already been initialized"); Microsoft::WRL::ComPtr<ID3D12Device> pDevice; #if _DEBUG Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface; if (SUCCEEDED(D3D12GetDebugInterface(MY_IID_PPV_ARGS(&debugInterface)))) debugInterface->EnableDebugLayer(); else Utility::Print("WARNING: Unable to enable D3D12 debug validation layer\n"); #endif #ifdef DXIL EnableExperimentalShaderModels(); #endif // Obtain the DXGI factory Microsoft::WRL::ComPtr<IDXGIFactory4> dxgiFactory; ASSERT_SUCCEEDED(CreateDXGIFactory2(0, MY_IID_PPV_ARGS(&dxgiFactory))); // Create the D3D graphics device Microsoft::WRL::ComPtr<IDXGIAdapter1> pAdapter; static const bool bUseWarpDriver = false; if (!bUseWarpDriver) { SIZE_T MaxSize = 0; for (uint32_t Idx = 0; DXGI_ERROR_NOT_FOUND != dxgiFactory->EnumAdapters1(Idx, &pAdapter); ++Idx) { DXGI_ADAPTER_DESC1 desc; pAdapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) continue; if (desc.DedicatedVideoMemory > MaxSize && SUCCEEDED(D3D12CreateDevice(pAdapter.Get(), D3D_FEATURE_LEVEL_11_0, MY_IID_PPV_ARGS(&pDevice)))) { pAdapter->GetDesc1(&desc); Utility::Printf(L"D3D12-capable hardware found: %s (%u MB)\n", desc.Description, desc.DedicatedVideoMemory >> 20); MaxSize = desc.DedicatedVideoMemory; } }
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(); }
D3D12GSRender::D3D12GSRender() : GSRender() , m_d3d12_lib() , m_current_pso({}) { if (g_cfg.video.debug_output) { 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> adapter; const std::wstring adapter_name = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(g_cfg.video.d3d12.adapter); for (UINT id = 0; dxgi_factory->EnumAdapters(id, adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND; id++) { DXGI_ADAPTER_DESC desc; adapter->GetDesc(&desc); // Adapter with specified name if (adapter_name == desc.Description) { break; } // Default adapter if (id == 1 && adapter_name.empty()) { break; } } if (FAILED(wrapD3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)))) { LOG_ERROR(RSX, "Failed to initialize D3D device on adapter '%s', falling back to first available GPU", g_cfg.video.d3d12.adapter.get()); //Try to create a device on the first available device if (FAILED(wrapD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)))) { LOG_FATAL(RSX, "Unable to create D3D12 device. Your GPU(s) may not have D3D12 support."); return; } } g_d3d12_device = m_device.Get(); // 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()); D3D12_DESCRIPTOR_HEAP_DESC current_texture_descriptors_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 16 }; CHECK_HRESULT(m_device->CreateDescriptorHeap(¤t_texture_descriptors_desc, IID_PPV_ARGS(m_current_texture_descriptors.GetAddressOf()))); D3D12_DESCRIPTOR_HEAP_DESC current_sampler_descriptors_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 16 }; CHECK_HRESULT(m_device->CreateDescriptorHeap(¤t_sampler_descriptors_desc, IID_PPV_ARGS(m_current_sampler_descriptors.GetAddressOf()))); ComPtr<ID3DBlob> root_signature_blob = get_shared_root_signature_blob(); m_device->CreateRootSignature(0, root_signature_blob->GetBufferPointer(), root_signature_blob->GetBufferSize(), IID_PPV_ARGS(m_shared_root_signature.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(); 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 (g_cfg.video.overlay) init_d2d_structures(); }
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(); }