Skip to content
Permalink
Browse files

Merge pull request #3713 from stenzek/d3d12-more-fixes

D3D12: Bug fixes, implement bbox, realxfb, perfquery
  • Loading branch information...
Parlane committed May 10, 2016
2 parents 7fdf0c7 + ccf9470 commit bb6a04dc8ee7454d3f85b53f009cb9d9afa6ccda
Showing with 1,082 additions and 656 deletions.
  1. +121 −13 Source/Core/VideoBackends/D3D12/BoundingBox.cpp
  2. +2 −1 Source/Core/VideoBackends/D3D12/BoundingBox.h
  3. +0 −2 Source/Core/VideoBackends/D3D12/D3D12.vcxproj
  4. +0 −6 Source/Core/VideoBackends/D3D12/D3D12.vcxproj.filters
  5. +105 −175 Source/Core/VideoBackends/D3D12/D3DBase.cpp
  6. +15 −13 Source/Core/VideoBackends/D3D12/D3DBase.h
  7. +0 −2 Source/Core/VideoBackends/D3D12/D3DCommandListManager.h
  8. +70 −10 Source/Core/VideoBackends/D3D12/D3DQueuedCommandList.cpp
  9. +30 −0 Source/Core/VideoBackends/D3D12/D3DQueuedCommandList.h
  10. +9 −4 Source/Core/VideoBackends/D3D12/D3DShader.cpp
  11. +2 −2 Source/Core/VideoBackends/D3D12/D3DState.cpp
  12. +7 −4 Source/Core/VideoBackends/D3D12/D3DStreamBuffer.cpp
  13. +50 −17 Source/Core/VideoBackends/D3D12/D3DTexture.cpp
  14. +9 −3 Source/Core/VideoBackends/D3D12/D3DTexture.h
  15. +2 −105 Source/Core/VideoBackends/D3D12/D3DUtil.cpp
  16. +6 −4 Source/Core/VideoBackends/D3D12/D3DUtil.h
  17. +40 −38 Source/Core/VideoBackends/D3D12/FramebufferManager.cpp
  18. +2 −0 Source/Core/VideoBackends/D3D12/FramebufferManager.h
  19. +11 −10 Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp
  20. +161 −14 Source/Core/VideoBackends/D3D12/PerfQuery.cpp
  21. +17 −3 Source/Core/VideoBackends/D3D12/PerfQuery.h
  22. +51 −55 Source/Core/VideoBackends/D3D12/Render.cpp
  23. +115 −1 Source/Core/VideoBackends/D3D12/StaticShaderCache.cpp
  24. +2 −0 Source/Core/VideoBackends/D3D12/StaticShaderCache.h
  25. +0 −45 Source/Core/VideoBackends/D3D12/Television.cpp
  26. +0 −37 Source/Core/VideoBackends/D3D12/Television.h
  27. +20 −30 Source/Core/VideoBackends/D3D12/TextureCache.cpp
  28. +8 −16 Source/Core/VideoBackends/D3D12/VertexManager.cpp
  29. +157 −10 Source/Core/VideoBackends/D3D12/XFBEncoder.cpp
  30. +20 −6 Source/Core/VideoBackends/D3D12/XFBEncoder.h
  31. +43 −26 Source/Core/VideoBackends/D3D12/main.cpp
  32. +5 −0 Source/Core/VideoBackends/OGL/Render.cpp
  33. +2 −4 Source/Core/VideoCommon/FramebufferManagerBase.cpp
@@ -2,43 +2,151 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include <memory>

#include "Common/CommonTypes.h"
#include "Common/MsgHandler.h"
#include "VideoBackends/D3D12/BoundingBox.h"
#include "VideoBackends/D3D12/D3DBase.h"
#include "VideoBackends/D3D12/D3DCommandListManager.h"
#include "VideoBackends/D3D12/D3DDescriptorHeapManager.h"
#include "VideoBackends/D3D12/D3DStreamBuffer.h"
#include "VideoBackends/D3D12/D3DUtil.h"
#include "VideoBackends/D3D12/FramebufferManager.h"
#include "VideoBackends/D3D12/Render.h"
#include "VideoCommon/VideoConfig.h"

// D3D12TODO: Support bounding box behavior.
namespace DX12
{

ID3D11UnorderedAccessView* BBox::GetUAV()
constexpr size_t BBOX_BUFFER_SIZE = sizeof(int) * 4;
constexpr size_t BBOX_STREAM_BUFFER_SIZE = BBOX_BUFFER_SIZE * 128;

static ID3D12Resource* s_bbox_buffer;
static ID3D12Resource* s_bbox_staging_buffer;
static void* s_bbox_staging_buffer_map;
static std::unique_ptr<D3DStreamBuffer> s_bbox_stream_buffer;
static D3D12_GPU_DESCRIPTOR_HANDLE s_bbox_descriptor_handle;

void BBox::Init()
{
CD3DX12_RESOURCE_DESC buffer_desc(CD3DX12_RESOURCE_DESC::Buffer(BBOX_BUFFER_SIZE, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, 0));
CD3DX12_RESOURCE_DESC staging_buffer_desc(CD3DX12_RESOURCE_DESC::Buffer(BBOX_BUFFER_SIZE, D3D12_RESOURCE_FLAG_NONE, 0));

CheckHR(D3D::device12->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&buffer_desc,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr,
IID_PPV_ARGS(&s_bbox_buffer)));

CheckHR(D3D::device12->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK),
D3D12_HEAP_FLAG_NONE,
&staging_buffer_desc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&s_bbox_staging_buffer)));

s_bbox_stream_buffer = std::make_unique<D3DStreamBuffer>(BBOX_STREAM_BUFFER_SIZE, BBOX_STREAM_BUFFER_SIZE, nullptr);

// D3D12 root signature UAV must be raw or structured buffers, not typed. Since we used a typed buffer,
// we have to use a descriptor table. Luckily, we only have to allocate this once, and it never changes.
D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle;
if (!D3D::gpu_descriptor_heap_mgr->Allocate(&cpu_descriptor_handle, &s_bbox_descriptor_handle, nullptr, false))
PanicAlert("Failed to create bounding box UAV descriptor");

D3D12_UNORDERED_ACCESS_VIEW_DESC view_desc = { DXGI_FORMAT_R32_SINT, D3D12_UAV_DIMENSION_BUFFER };
view_desc.Buffer.FirstElement = 0;
view_desc.Buffer.NumElements = 4;
view_desc.Buffer.StructureByteStride = 0;
view_desc.Buffer.CounterOffsetInBytes = 0;
view_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
D3D::device12->CreateUnorderedAccessView(s_bbox_buffer, nullptr, &view_desc, cpu_descriptor_handle);

Bind();
}

void BBox::Bind()
{
// D3D12TODO: Implement this;
return nullptr;
D3D::current_command_list->SetGraphicsRootDescriptorTable(DESCRIPTOR_TABLE_PS_UAV, s_bbox_descriptor_handle);
}

void BBox::Init()
void BBox::Invalidate()
{
if (g_ActiveConfig.backend_info.bSupportsBBox)
{
// D3D12TODO: Implement this;
}
if (!s_bbox_staging_buffer_map)
return;

D3D12_RANGE write_range = {};
s_bbox_staging_buffer->Unmap(0, &write_range);
s_bbox_staging_buffer_map = nullptr;
}

void BBox::Shutdown()
{
// D3D12TODO: Implement this;
Invalidate();

if (s_bbox_buffer)
{
D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(s_bbox_buffer);
s_bbox_buffer = nullptr;
}

if (s_bbox_staging_buffer)
{
D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(s_bbox_staging_buffer);
s_bbox_staging_buffer = nullptr;
}

s_bbox_stream_buffer.reset();
}

void BBox::Set(int index, int value)
{
// D3D12TODO: Implement this;
// If the buffer is currently mapped, compare the value, and update the staging buffer.
if (s_bbox_staging_buffer_map)
{
int current_value;
memcpy(&current_value, reinterpret_cast<u8*>(s_bbox_staging_buffer_map) + (index * sizeof(int)), sizeof(int));
if (current_value == value)
{
// Value hasn't changed. So skip updating completely.
return;
}

memcpy(reinterpret_cast<u8*>(s_bbox_staging_buffer_map) + (index * sizeof(int)), &value, sizeof(int));
}

s_bbox_stream_buffer->AllocateSpaceInBuffer(sizeof(int), sizeof(int));

// Allocate temporary bytes in upload buffer, then copy to real buffer.
memcpy(s_bbox_stream_buffer->GetCPUAddressOfCurrentAllocation(), &value, sizeof(int));
D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST, 0);
D3D::current_command_list->CopyBufferRegion(s_bbox_buffer, index * sizeof(int), s_bbox_stream_buffer->GetBuffer(), s_bbox_stream_buffer->GetOffsetOfCurrentAllocation(), sizeof(int));
D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0);
}

int BBox::Get(int index)
{
// D3D12TODO: Implement this;
return 0;
if (!s_bbox_staging_buffer_map)
{
D3D::command_list_mgr->CPUAccessNotify();

// Copy from real buffer to staging buffer, then block until we have the results.
D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE, 0);
D3D::current_command_list->CopyBufferRegion(s_bbox_staging_buffer, 0, s_bbox_buffer, 0, BBOX_BUFFER_SIZE);
D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0);

D3D::command_list_mgr->ExecuteQueuedWork(true);

D3D12_RANGE read_range = { 0, BBOX_BUFFER_SIZE };
CheckHR(s_bbox_staging_buffer->Map(0, &read_range, &s_bbox_staging_buffer_map));
}

int value;
memcpy(&value, &reinterpret_cast<int*>(s_bbox_staging_buffer_map)[index], sizeof(int));
return value;
}

};
@@ -11,8 +11,9 @@ namespace DX12
class BBox
{
public:
static ID3D11UnorderedAccessView* GetUAV();
static void Init();
static void Bind();
static void Invalidate();
static void Shutdown();

static void Set(int index, int value);
@@ -67,7 +67,6 @@
<ClCompile Include="ShaderCache.cpp" />
<ClCompile Include="ShaderConstantsManager.cpp" />
<ClCompile Include="StaticShaderCache.cpp" />
<ClCompile Include="Television.cpp" />
<ClCompile Include="TextureCache.cpp" />
<ClCompile Include="VertexManager.cpp" />
<ClCompile Include="XFBEncoder.cpp" />
@@ -91,7 +90,6 @@
<ClInclude Include="ShaderCache.h" />
<ClInclude Include="ShaderConstantsManager.h" />
<ClInclude Include="StaticShaderCache.h" />
<ClInclude Include="Television.h" />
<ClInclude Include="TextureCache.h" />
<ClInclude Include="TextureEncoder.h" />
<ClInclude Include="VertexManager.h" />
@@ -39,9 +39,6 @@
<ClCompile Include="Render.cpp">
<Filter>Render</Filter>
</ClCompile>
<ClCompile Include="Television.cpp">
<Filter>Render</Filter>
</ClCompile>
<ClCompile Include="TextureCache.cpp">
<Filter>Render</Filter>
</ClCompile>
@@ -105,9 +102,6 @@
<ClInclude Include="Render.h">
<Filter>Render</Filter>
</ClInclude>
<ClInclude Include="Television.h">
<Filter>Render</Filter>
</ClInclude>
<ClInclude Include="TextureCache.h">
<Filter>Render</Filter>
</ClInclude>
Oops, something went wrong.

0 comments on commit bb6a04d

Please sign in to comment.
You can’t perform that action at this time.