diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 1592521cf2..950daef552 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -792,6 +792,16 @@ bool D3D12GSRender::LoadProgram() assert(0); } + switch (m_surface_color_format) + { + case CELL_GCM_SURFACE_A8R8G8B8: + prop.RenderTargetsFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + prop.RenderTargetsFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + break; + } + switch (m_surface_color_target) { case CELL_GCM_SURFACE_TARGET_0: @@ -1166,8 +1176,19 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra { ID3D12Resource *Result; size_t w = m_surface_clip_w, h = m_surface_clip_h; - size_t rowPitch = w * 4; - rowPitch = (rowPitch + 255) & ~255; + DXGI_FORMAT dxgiFormat; + size_t rowPitch; + switch (m_surface_color_format) + { + case CELL_GCM_SURFACE_A8R8G8B8: + dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + rowPitch = powerOf2Align(w * 4, 256); + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + rowPitch = powerOf2Align(w * 8, 256); + break; + } D3D12_HEAP_PROPERTIES heapProp = {}; heapProp.Type = D3D12_HEAP_TYPE_READBACK; @@ -1201,7 +1222,7 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra dst.pResource = Result; dst.PlacedFootprint.Offset = 0; dst.PlacedFootprint.Footprint.Depth = 1; - dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dst.PlacedFootprint.Footprint.Format = dxgiFormat; dst.PlacedFootprint.Footprint.Height = (UINT)h; dst.PlacedFootprint.Footprint.Width = (UINT)w; dst.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch; @@ -1216,7 +1237,7 @@ void copyToCellRamAndRelease(void *dstAddress, ID3D12Resource *res, size_t rowPi void *srcBuffer; check(res->Map(0, nullptr, &srcBuffer)); for (unsigned row = 0; row < height; row++) - memcpy((char*)dstAddress + row * width * 4, (char*)srcBuffer + row * rowPitch, width * 4); + memcpy((char*)dstAddress + row * rowPitch, (char*)srcBuffer + row * rowPitch, rowPitch); res->Unmap(0, nullptr); res->Release(); } @@ -1452,8 +1473,16 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) convertCommandList->Release(); } - size_t colorRowPitch = m_surface_clip_w * 4; - colorRowPitch = (colorRowPitch + 255) & ~255; + size_t colorRowPitch; + switch (m_surface_color_format) + { + case CELL_GCM_SURFACE_A8R8G8B8: + colorRowPitch = powerOf2Align(m_surface_clip_w * 4, 256); + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + colorRowPitch = powerOf2Align(m_surface_clip_w * 8, 256); + break; + } if (Ini.GSDumpColorBuffers.GetValue()) { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index 0b0326b806..dc49e0c56b 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -14,6 +14,7 @@ struct D3D12PipelineProperties { D3D12_PRIMITIVE_TOPOLOGY_TYPE Topology; DXGI_FORMAT DepthStencilFormat; + DXGI_FORMAT RenderTargetsFormat; std::vector IASet; D3D12_BLEND_DESC Blend; unsigned numMRT : 3; @@ -46,7 +47,7 @@ struct D3D12PipelineProperties return false; if (memcmp(&Rasterization, &in.Rasterization, sizeof(D3D12_RASTERIZER_DESC))) return false; - return Topology == in.Topology && DepthStencilFormat == in.DepthStencilFormat && numMRT == in.numMRT && SampleMask == in.SampleMask; + return Topology == in.Topology && DepthStencilFormat == in.DepthStencilFormat && numMRT == in.numMRT && SampleMask == in.SampleMask && RenderTargetsFormat == in.RenderTargetsFormat; } }; @@ -155,7 +156,7 @@ struct D3D12Traits graphicPipelineStateDesc.NumRenderTargets = pipelineProperties.numMRT; for (unsigned i = 0; i < pipelineProperties.numMRT; i++) - graphicPipelineStateDesc.RTVFormats[i] = DXGI_FORMAT_R8G8B8A8_UNORM; + graphicPipelineStateDesc.RTVFormats[i] = pipelineProperties.RenderTargetsFormat; graphicPipelineStateDesc.DSVFormat = pipelineProperties.DepthStencilFormat; graphicPipelineStateDesc.InputLayout.pInputElementDescs = pipelineProperties.IASet.data(); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index 767fa50b16..6bcdfbc56f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -45,97 +45,78 @@ void D3D12GSRender::InitDrawBuffers() D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + DXGI_FORMAT dxgiFormat; + switch (m_surface_color_format) + { + case CELL_GCM_SURFACE_A8R8G8B8: + dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + break; + } + D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; + rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rttViewDesc.Format = dxgiFormat; + switch (m_surface_color_target) { case CELL_GCM_SURFACE_TARGET_0: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); break; } case CELL_GCM_SURFACE_TARGET_1: { - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_b, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); break; } case CELL_GCM_SURFACE_TARGET_MRT1: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); } break; case CELL_GCM_SURFACE_TARGET_MRT2: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttC, &rttViewDesc, Handle); break; } case CELL_GCM_SURFACE_TARGET_MRT3: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttC, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttD = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 3, address_d, m_surface_clip_w, m_surface_clip_h, + ID3D12Resource *rttD = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 3, address_d, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); - rttViewDesc = {}; - rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateRenderTargetView(rttD, &rttViewDesc, Handle); break; } @@ -166,7 +147,7 @@ void D3D12GSRender::InitDrawBuffers() } ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, size_t slot, u32 address, - size_t width, size_t height, float clearColorR, float clearColorG, float clearColorB, float clearColorA) + size_t width, size_t height, u8 surfaceColorFormat, float clearColorR, float clearColorG, float clearColorB, float clearColorA) { ID3D12Resource* rtt; auto It = m_renderTargets.find(address); @@ -179,8 +160,18 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, else { LOG_WARNING(RSX, "Creating RTT"); + DXGI_FORMAT dxgiFormat; + switch (surfaceColorFormat) + { + case CELL_GCM_SURFACE_A8R8G8B8: + dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + break; + } D3D12_CLEAR_VALUE clearColorValue = {}; - clearColorValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + clearColorValue.Format = dxgiFormat; clearColorValue.Color[0] = clearColorR; clearColorValue.Color[1] = clearColorG; clearColorValue.Color[2] = clearColorB; @@ -189,7 +180,7 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, D3D12_HEAP_PROPERTIES heapProp = {}; heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, DXGI_FORMAT_R8G8B8A8_UNORM); + D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat); resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; device->CreateCommittedResource( diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h index 493a3d8c21..719c189669 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h @@ -20,7 +20,7 @@ struct RenderTargets * returns the corresponding render target resource. */ ID3D12Resource *bindAddressAsRenderTargets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, size_t slot, u32 address, - size_t width, size_t height, float clearColorR, float clearColorG, float clearColorB, float clearColorA); + size_t width, size_t height, u8 surfaceColorFormat, float clearColorR, float clearColorG, float clearColorB, float clearColorA); ID3D12Resource *bindAddressAsDepthStencil(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address, size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear);