d3d12: Move storage helpers to their dedicated files.

This commit is contained in:
Vincent Lejeune 2015-10-28 17:42:43 +01:00
parent fdae12c52e
commit 124d0de325
8 changed files with 533 additions and 506 deletions

View File

@ -83,6 +83,7 @@
<ClInclude Include="Emu\RSX\D3D12\D3D12Formats.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12FragmentProgramDecompiler.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12GSRender.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12MemoryHelpers.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12PipelineState.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12RenderTargetSets.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12VertexProgramDecompiler.h" />
@ -95,6 +96,7 @@
<ClCompile Include="Emu\RSX\D3D12\D3D12Formats.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12FragmentProgramDecompiler.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12GSRender.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12MemoryHelpers.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12Overlay.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12PipelineState.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12RenderTargetSets.cpp" />

View File

@ -38,6 +38,9 @@
<ClInclude Include="Emu\RSX\D3D12\D3D12Formats.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\D3D12\D3D12MemoryHelpers.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Emu\RSX\D3D12\D3D12Buffer.cpp">
@ -76,5 +79,8 @@
<ClCompile Include="Emu\RSX\D3D12\D3D12Formats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\D3D12\D3D12MemoryHelpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -12,10 +12,10 @@ namespace
/**
*
*/
D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector<u8> &vertex_data, ID3D12Device *device, DataHeap<ID3D12Resource, 65536> &vertex_index_heap)
D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector<u8> &vertex_data, ID3D12Device *device, data_heap<ID3D12Resource, 65536> &vertex_index_heap)
{
size_t buffer_size = vertex_data.size();
assert(vertex_index_heap.canAlloc(buffer_size));
assert(vertex_index_heap.can_alloc(buffer_size));
size_t heap_offset = vertex_index_heap.alloc(buffer_size);
void *buffer;
@ -57,7 +57,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
u32 element_size = type_size * info.size;
size_t buffer_size = element_size * vertex_count;
assert(m_vertexIndexData.canAlloc(buffer_size));
assert(m_vertexIndexData.can_alloc(buffer_size));
size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer;
@ -107,7 +107,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
u32 element_size = type_size * info.size;
size_t buffer_size = data.size();
assert(m_vertexIndexData.canAlloc(buffer_size));
assert(m_vertexIndexData.can_alloc(buffer_size));
size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer;
@ -166,7 +166,7 @@ void D3D12GSRender::setScaleOffset(size_t descriptorIndex)
scale_offset_matrix[3] /= clip_w / 2.f;
scale_offset_matrix[7] /= clip_h / 2.f;
assert(m_constantsData.canAlloc(256));
assert(m_constantsData.can_alloc(256));
size_t heap_offset = m_constantsData.alloc(256);
// Scale offset buffer
@ -185,7 +185,7 @@ void D3D12GSRender::setScaleOffset(size_t descriptorIndex)
256
};
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptorIndex, g_descriptorStrideSRVCBVUAV));
}
@ -196,7 +196,7 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer(size_t descriptor_index)
size_t buffer_size = 512 * 4 * sizeof(float);
assert(m_constantsData.canAlloc(buffer_size));
assert(m_constantsData.can_alloc(buffer_size));
size_t heap_offset = m_constantsData.alloc(buffer_size);
void *mapped_buffer;
@ -218,7 +218,7 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer(size_t descriptor_index)
(UINT)buffer_size
};
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptor_index, g_descriptorStrideSRVCBVUAV));
}
@ -230,7 +230,7 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer(size_t descriptor_index)
// Multiple of 256 never 0
buffer_size = (buffer_size + 255) & ~255;
assert(m_constantsData.canAlloc(buffer_size));
assert(m_constantsData.can_alloc(buffer_size));
size_t heap_offset = m_constantsData.alloc(buffer_size);
size_t offset = 0;
@ -261,7 +261,7 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer(size_t descriptor_index)
(UINT)buffer_size
};
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptor_index, g_descriptorStrideSRVCBVUAV));
}
@ -283,7 +283,7 @@ void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *command_
// Alloc
size_t buffer_size = align(m_renderingInfo.m_count * sizeof(u16), 64);
assert(m_vertexIndexData.canAlloc(buffer_size));
assert(m_vertexIndexData.can_alloc(buffer_size));
size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer;
@ -315,7 +315,7 @@ void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *command_
// Alloc
size_t buffer_size = align(m_renderingInfo.m_count * index_size, 64);
assert(m_vertexIndexData.canAlloc(buffer_size));
assert(m_vertexIndexData.can_alloc(buffer_size));
size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer;

View File

@ -59,68 +59,6 @@ void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_qu
}
}
void D3D12GSRender::ResourceStorage::Reset()
{
m_descriptorsHeapIndex = 0;
m_currentSamplerIndex = 0;
m_samplerDescriptorHeapIndex = 0;
ThrowIfFailed(m_commandAllocator->Reset());
setNewCommandList();
m_singleFrameLifetimeResources.clear();
}
void D3D12GSRender::ResourceStorage::setNewCommandList()
{
ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), nullptr));
}
void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
{
m_inUse = false;
m_device = device;
m_RAMFramebuffer = nullptr;
// Create a global command allocator
ThrowIfFailed(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(m_commandAllocator.GetAddressOf())));
ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(m_commandList.GetAddressOf())));
ThrowIfFailed(m_commandList->Close());
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(&m_descriptorsHeap)));
D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2048, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&m_samplerDescriptorHeap[0])));
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&m_samplerDescriptorHeap[1])));
m_frameFinishedHandle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
m_fenceValue = 0;
ThrowIfFailed(device->CreateFence(m_fenceValue++, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_frameFinishedFence.GetAddressOf())));
}
void D3D12GSRender::ResourceStorage::WaitAndClean()
{
if (m_inUse)
WaitForSingleObjectEx(m_frameFinishedHandle, INFINITE, FALSE);
else
ThrowIfFailed(m_commandList->Close());
Reset();
m_dirtyTextures.clear();
m_RAMFramebuffer = nullptr;
}
void D3D12GSRender::ResourceStorage::Release()
{
m_dirtyTextures.clear();
// NOTE: Should be released only after gfx pipeline last command has been finished.
CloseHandle(m_frameFinishedHandle);
}
void D3D12GSRender::Shader::Release()
{
m_PSO->Release();
@ -135,7 +73,7 @@ extern std::function<bool(u32 addr)> gfxHandler;
bool D3D12GSRender::invalidateAddress(u32 addr)
{
bool result = false;
result |= m_textureCache.invalidateAddress(addr);
result |= m_textureCache.invalidate_address(addr);
return result;
}
@ -240,10 +178,10 @@ D3D12GSRender::D3D12GSRender()
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();
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());
@ -258,14 +196,14 @@ D3D12GSRender::D3D12GSRender()
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_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);
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())
InitD2DStructures();
@ -275,22 +213,20 @@ D3D12GSRender::~D3D12GSRender()
{
wait_for_command_queue(m_device.Get(), m_commandQueueGraphic.Get());
{
m_textureCache.unprotedAll();
}
m_textureCache.unprotect_all();
gfxHandler = [this](u32) { return false; };
m_constantsData.Release();
m_vertexIndexData.Release();
m_textureUploadData.Release();
m_constantsData.release();
m_vertexIndexData.release();
m_textureUploadData.release();
m_UAVHeap.m_heap->Release();
m_readbackResources.m_heap->Release();
m_texturesRTTs.clear();
m_dummyTexture->Release();
m_convertPSO->Release();
m_convertRootSignature->Release();
m_perFrameStorage[0].Release();
m_perFrameStorage[1].Release();
m_perFrameStorage[0].release();
m_perFrameStorage[1].release();
m_rtts.Release();
m_outputScalingPass.Release();
@ -376,7 +312,7 @@ void D3D12GSRender::clear_surface(u32 arg)
std::chrono::time_point<std::chrono::system_clock> start_duration = std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> rtt_duration_start = std::chrono::system_clock::now();
PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get());
PrepareRenderTargets(getCurrentResourceStorage().command_list.Get());
std::chrono::time_point<std::chrono::system_clock> rtt_duration_end = std::chrono::system_clock::now();
m_timers.m_rttDuration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
@ -398,17 +334,17 @@ void D3D12GSRender::clear_surface(u32 arg)
{
u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8;
u32 max_depth_value = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff;
getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, 0, nullptr);
getCurrentResourceStorage().command_list->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, 0, nullptr);
}
if (arg & 0x2)
getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f,
getCurrentResourceStorage().command_list->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f,
get_clear_stencil(rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE]), 0, nullptr);
if (arg & 0xF0)
{
for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(i, g_descriptorStrideRTV),
getCurrentResourceStorage().command_list->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(i, g_descriptorStrideRTV),
get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(), 0, nullptr);
}
@ -418,9 +354,9 @@ void D3D12GSRender::clear_surface(u32 arg)
if (rpcs3::config.rsx.d3d12.debug_output.value())
{
ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
getCurrentResourceStorage().setNewCommandList();
ThrowIfFailed(getCurrentResourceStorage().command_list->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().command_list.GetAddressOf());
getCurrentResourceStorage().set_new_command_list();
}
}
@ -429,7 +365,7 @@ void D3D12GSRender::end()
std::chrono::time_point<std::chrono::system_clock> start_duration = std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> rtt_duration_start = std::chrono::system_clock::now();
PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get());
PrepareRenderTargets(getCurrentResourceStorage().command_list.Get());
std::chrono::time_point<std::chrono::system_clock> rtt_duration_end = std::chrono::system_clock::now();
m_timers.m_rttDuration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
@ -437,7 +373,7 @@ void D3D12GSRender::end()
std::chrono::time_point<std::chrono::system_clock> vertex_index_duration_start = std::chrono::system_clock::now();
if (!vertex_index_array.empty() || vertex_draw_count)
upload_vertex_index_data(getCurrentResourceStorage().m_commandList.Get());
upload_vertex_index_data(getCurrentResourceStorage().command_list.Get());
std::chrono::time_point<std::chrono::system_clock> vertex_index_duration_end = std::chrono::system_clock::now();
m_timers.m_vertexIndexDuration += std::chrono::duration_cast<std::chrono::microseconds>(vertex_index_duration_end - vertex_index_duration_start).count();
@ -452,12 +388,12 @@ void D3D12GSRender::end()
std::chrono::time_point<std::chrono::system_clock> program_load_end = std::chrono::system_clock::now();
m_timers.m_programLoadDuration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count();
getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_rootSignatures[std::get<2>(*m_PSO)].Get());
getCurrentResourceStorage().m_commandList->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]);
getCurrentResourceStorage().command_list->SetGraphicsRootSignature(m_rootSignatures[std::get<2>(*m_PSO)].Get());
getCurrentResourceStorage().command_list->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]);
std::chrono::time_point<std::chrono::system_clock> constants_duration_start = std::chrono::system_clock::now();
size_t currentDescriptorIndex = getCurrentResourceStorage().m_descriptorsHeapIndex;
size_t currentDescriptorIndex = getCurrentResourceStorage().descriptors_heap_index;
// Constants
setScaleOffset(currentDescriptorIndex);
FillVertexShaderConstantsBuffer(currentDescriptorIndex + 1);
@ -466,47 +402,47 @@ void D3D12GSRender::end()
std::chrono::time_point<std::chrono::system_clock> constants_duration_end = std::chrono::system_clock::now();
m_timers.m_constantsDuration += std::chrono::duration_cast<std::chrono::microseconds>(constants_duration_end - constants_duration_start).count();
getCurrentResourceStorage().m_commandList->SetPipelineState(std::get<0>(*m_PSO));
getCurrentResourceStorage().command_list->SetPipelineState(std::get<0>(*m_PSO));
std::chrono::time_point<std::chrono::system_clock> texture_duration_start = std::chrono::system_clock::now();
if (std::get<2>(*m_PSO) > 0)
{
upload_and_bind_textures(getCurrentResourceStorage().m_commandList.Get(), currentDescriptorIndex + 3, std::get<2>(*m_PSO) > 0);
upload_and_bind_textures(getCurrentResourceStorage().command_list.Get(), currentDescriptorIndex + 3, std::get<2>(*m_PSO) > 0);
ID3D12DescriptorHeap *descriptors[] =
{
getCurrentResourceStorage().m_descriptorsHeap.Get(),
getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex].Get(),
getCurrentResourceStorage().descriptors_heap.Get(),
getCurrentResourceStorage().sampler_descriptor_heap[getCurrentResourceStorage().sampler_descriptors_heap_index].Get(),
};
getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(2, descriptors);
getCurrentResourceStorage().command_list->SetDescriptorHeaps(2, descriptors);
getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetGPUDescriptorHandleForHeapStart())
getCurrentResourceStorage().command_list->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetGPUDescriptorHandleForHeapStart())
.Offset((INT)currentDescriptorIndex, g_descriptorStrideSRVCBVUAV)
);
getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(1,
CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetGPUDescriptorHandleForHeapStart())
.Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex, g_descriptorStrideSamplers)
getCurrentResourceStorage().command_list->SetGraphicsRootDescriptorTable(1,
CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().sampler_descriptor_heap[getCurrentResourceStorage().sampler_descriptors_heap_index]->GetGPUDescriptorHandleForHeapStart())
.Offset((INT)getCurrentResourceStorage().current_sampler_index, g_descriptorStrideSamplers)
);
getCurrentResourceStorage().m_currentSamplerIndex += std::get<2>(*m_PSO);
getCurrentResourceStorage().m_descriptorsHeapIndex += std::get<2>(*m_PSO) + 3;
getCurrentResourceStorage().current_sampler_index += std::get<2>(*m_PSO);
getCurrentResourceStorage().descriptors_heap_index += std::get<2>(*m_PSO) + 3;
}
else
{
getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, getCurrentResourceStorage().m_descriptorsHeap.GetAddressOf());
getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetGPUDescriptorHandleForHeapStart())
getCurrentResourceStorage().command_list->SetDescriptorHeaps(1, getCurrentResourceStorage().descriptors_heap.GetAddressOf());
getCurrentResourceStorage().command_list->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetGPUDescriptorHandleForHeapStart())
.Offset((INT)currentDescriptorIndex, g_descriptorStrideSRVCBVUAV)
);
getCurrentResourceStorage().m_descriptorsHeapIndex += 3;
getCurrentResourceStorage().descriptors_heap_index += 3;
}
std::chrono::time_point<std::chrono::system_clock> texture_duration_end = std::chrono::system_clock::now();
m_timers.m_textureDuration += std::chrono::duration_cast<std::chrono::microseconds>(texture_duration_end - texture_duration_start).count();
size_t num_rtt = get_num_rtt(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]);
getCurrentResourceStorage().m_commandList->OMSetRenderTargets((UINT)num_rtt, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true,
getCurrentResourceStorage().command_list->OMSetRenderTargets((UINT)num_rtt, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true,
&CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart()));
int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
@ -521,7 +457,7 @@ void D3D12GSRender::end()
-1.f,
1.f
};
getCurrentResourceStorage().m_commandList->RSSetViewports(1, &viewport);
getCurrentResourceStorage().command_list->RSSetViewports(1, &viewport);
D3D12_RECT box =
{
@ -530,14 +466,14 @@ void D3D12GSRender::end()
(LONG)clip_w,
(LONG)clip_h,
};
getCurrentResourceStorage().m_commandList->RSSetScissorRects(1, &box);
getCurrentResourceStorage().command_list->RSSetScissorRects(1, &box);
getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(get_primitive_topology(draw_mode));
getCurrentResourceStorage().command_list->IASetPrimitiveTopology(get_primitive_topology(draw_mode));
if (m_renderingInfo.m_indexed)
getCurrentResourceStorage().m_commandList->DrawIndexedInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0, 0);
getCurrentResourceStorage().command_list->DrawIndexedInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0, 0);
else
getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0);
getCurrentResourceStorage().command_list->DrawInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0);
vertex_index_array.clear();
std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now();
@ -546,9 +482,9 @@ void D3D12GSRender::end()
if (rpcs3::config.rsx.d3d12.debug_output.value())
{
ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
getCurrentResourceStorage().setNewCommandList();
ThrowIfFailed(getCurrentResourceStorage().command_list->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().command_list.GetAddressOf());
getCurrentResourceStorage().set_new_command_list();
}
m_first_count_pairs.clear();
m_renderingInfo.m_indexed = false;
@ -581,8 +517,8 @@ void D3D12GSRender::flip(int buffer)
if (!is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
{
ResourceStorage &storage = getCurrentResourceStorage();
assert(storage.m_RAMFramebuffer == nullptr);
resource_storage &storage = getCurrentResourceStorage();
assert(storage.ram_framebuffer == nullptr);
size_t w = 0, h = 0, row_pitch = 0;
@ -597,7 +533,7 @@ void D3D12GSRender::flip(int buffer)
row_pitch = align(w * 4, 256);
size_t texture_size = row_pitch * h; // * 4 for mipmap levels
assert(m_textureUploadData.canAlloc(texture_size));
assert(m_textureUploadData.can_alloc(texture_size));
size_t heap_offset = m_textureUploadData.alloc(texture_size);
void *buffer;
@ -616,24 +552,24 @@ void D3D12GSRender::flip(int buffer)
&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, 1),
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(storage.m_RAMFramebuffer.GetAddressOf())
IID_PPV_ARGS(storage.ram_framebuffer.GetAddressOf())
)
);
getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.m_RAMFramebuffer.Get(), 0), 0, 0, 0,
getCurrentResourceStorage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.ram_framebuffer.Get(), 0), 0, 0, 0,
&CD3DX12_TEXTURE_COPY_LOCATION(m_textureUploadData.m_heap, { offset, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)row_pitch } }), nullptr);
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(storage.m_RAMFramebuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ));
resource_to_flip = storage.m_RAMFramebuffer.Get();
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(storage.ram_framebuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ));
resource_to_flip = storage.ram_framebuffer.Get();
viewport_w = (float)w, viewport_h = (float)h;
}
else
{
if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr)
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ));
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ));
resource_to_flip = m_rtts.m_currentlyBoundRenderTargets[0];
}
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
D3D12_VIEWPORT viewport =
{
@ -644,7 +580,7 @@ void D3D12GSRender::flip(int buffer)
0.f,
1.f
};
getCurrentResourceStorage().m_commandList->RSSetViewports(1, &viewport);
getCurrentResourceStorage().command_list->RSSetViewports(1, &viewport);
D3D12_RECT box =
{
@ -653,9 +589,9 @@ void D3D12GSRender::flip(int buffer)
(LONG)m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()]->GetDesc().Width,
(LONG)m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()]->GetDesc().Height,
};
getCurrentResourceStorage().m_commandList->RSSetScissorRects(1, &box);
getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_outputScalingPass.m_rootSignature);
getCurrentResourceStorage().m_commandList->SetPipelineState(m_outputScalingPass.m_PSO);
getCurrentResourceStorage().command_list->RSSetScissorRects(1, &box);
getCurrentResourceStorage().command_list->SetGraphicsRootSignature(m_outputScalingPass.m_rootSignature);
getCurrentResourceStorage().command_list->SetPipelineState(m_outputScalingPass.m_PSO);
D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {};
// FIXME: Not always true
@ -682,31 +618,31 @@ void D3D12GSRender::flip(int buffer)
m_device->CreateSampler(&sampler_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSamplers));
getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, &m_outputScalingPass.m_textureDescriptorHeap);
getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(0,
getCurrentResourceStorage().command_list->SetDescriptorHeaps(1, &m_outputScalingPass.m_textureDescriptorHeap);
getCurrentResourceStorage().command_list->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_textureDescriptorHeap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSRVCBVUAV));
getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, &m_outputScalingPass.m_samplerDescriptorHeap);
getCurrentResourceStorage().m_commandList->SetGraphicsRootDescriptorTable(1,
getCurrentResourceStorage().command_list->SetDescriptorHeaps(1, &m_outputScalingPass.m_samplerDescriptorHeap);
getCurrentResourceStorage().command_list->SetGraphicsRootDescriptorTable(1,
CD3DX12_GPU_DESCRIPTOR_HANDLE(m_outputScalingPass.m_samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swapChain->GetCurrentBackBufferIndex(), g_descriptorStrideSamplers));
getCurrentResourceStorage().m_commandList->OMSetRenderTargets(1,
getCurrentResourceStorage().command_list->OMSetRenderTargets(1,
&CD3DX12_CPU_DESCRIPTOR_HANDLE(m_backbufferAsRendertarget[m_swapChain->GetCurrentBackBufferIndex()]->GetCPUDescriptorHandleForHeapStart()),
true, nullptr);
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = {};
vertex_buffer_view.BufferLocation = m_outputScalingPass.m_vertexBuffer->GetGPUVirtualAddress();
vertex_buffer_view.StrideInBytes = 4 * sizeof(float);
vertex_buffer_view.SizeInBytes = 16 * sizeof(float);
getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, 1, &vertex_buffer_view);
getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
getCurrentResourceStorage().command_list->IASetVertexBuffers(0, 1, &vertex_buffer_view);
getCurrentResourceStorage().command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr)
getCurrentResourceStorage().m_commandList->DrawInstanced(4, 1, 0, 0);
getCurrentResourceStorage().command_list->DrawInstanced(4, 1, 0, 0);
if (!rpcs3::config.rsx.d3d12.overlay.value())
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
if (is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr)
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
ThrowIfFailed(getCurrentResourceStorage().command_list->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().command_list.GetAddressOf());
if(rpcs3::config.rsx.d3d12.overlay.value())
renderOverlay();
@ -718,38 +654,38 @@ void D3D12GSRender::flip(int buffer)
ThrowIfFailed(m_swapChain->Present(rpcs3::state.config.rsx.vsync.value() ? 1 : 0, 0));
// Add an event signaling queue completion
ResourceStorage &storage = getNonCurrentResourceStorage();
resource_storage &storage = getNonCurrentResourceStorage();
m_commandQueueGraphic->Signal(storage.m_frameFinishedFence.Get(), storage.m_fenceValue);
storage.m_frameFinishedFence->SetEventOnCompletion(storage.m_fenceValue, storage.m_frameFinishedHandle);
storage.m_fenceValue++;
m_commandQueueGraphic->Signal(storage.frame_finished_fence.Get(), storage.fence_value);
storage.frame_finished_fence->SetEventOnCompletion(storage.fence_value, storage.frame_finished_handle);
storage.fence_value++;
storage.m_inUse = true;
storage.in_use = true;
// Get the put pos - 1. This way after cleaning we can set the get ptr to
// this value, allowing heap to proceed even if we cleant before allocating
// a new value (that's the reason of the -1)
storage.m_getPosConstantsHeap = m_constantsData.getCurrentPutPosMinusOne();
storage.m_getPosVertexIndexHeap = m_vertexIndexData.getCurrentPutPosMinusOne();
storage.m_getPosTextureUploadHeap = m_textureUploadData.getCurrentPutPosMinusOne();
storage.m_getPosReadbackHeap = m_readbackResources.getCurrentPutPosMinusOne();
storage.m_getPosUAVHeap = m_UAVHeap.getCurrentPutPosMinusOne();
storage.constants_heap_get_pos = m_constantsData.get_current_put_pos_minus_one();
storage.vertex_index_heap_get_pos = m_vertexIndexData.get_current_put_pos_minus_one();
storage.texture_upload_heap_get_pos = m_textureUploadData.get_current_put_pos_minus_one();
storage.readback_heap_get_pos = m_readbackResources.get_current_put_pos_minus_one();
storage.uav_heap_get_pos = m_UAVHeap.get_current_put_pos_minus_one();
// Flush
local_transform_constants.clear();
m_texturesRTTs.clear();
// Now get ready for next frame
ResourceStorage &new_storage = getCurrentResourceStorage();
resource_storage &new_storage = getCurrentResourceStorage();
new_storage.WaitAndClean();
if (new_storage.m_inUse)
new_storage.wait_and_clean();
if (new_storage.in_use)
{
m_constantsData.m_getPos = new_storage.m_getPosConstantsHeap;
m_vertexIndexData.m_getPos = new_storage.m_getPosVertexIndexHeap;
m_textureUploadData.m_getPos = new_storage.m_getPosTextureUploadHeap;
m_readbackResources.m_getPos = new_storage.m_getPosReadbackHeap;
m_UAVHeap.m_getPos = new_storage.m_getPosUAVHeap;
m_constantsData.m_get_pos = new_storage.constants_heap_get_pos;
m_vertexIndexData.m_get_pos = new_storage.vertex_index_heap_get_pos;
m_textureUploadData.m_get_pos = new_storage.texture_upload_heap_get_pos;
m_readbackResources.m_get_pos = new_storage.readback_heap_get_pos;
m_UAVHeap.m_get_pos = new_storage.uav_heap_get_pos;
}
m_frame->flip(nullptr);
@ -772,12 +708,12 @@ void D3D12GSRender::ResetTimer()
m_timers.m_flipDuration = 0;
}
D3D12GSRender::ResourceStorage& D3D12GSRender::getCurrentResourceStorage()
resource_storage& D3D12GSRender::getCurrentResourceStorage()
{
return m_perFrameStorage[m_swapChain->GetCurrentBackBufferIndex()];
}
D3D12GSRender::ResourceStorage& D3D12GSRender::getNonCurrentResourceStorage()
resource_storage& D3D12GSRender::getNonCurrentResourceStorage()
{
return m_perFrameStorage[1 - m_swapChain->GetCurrentBackBufferIndex()];
}
@ -791,7 +727,7 @@ namespace
ComPtr<ID3D12Resource> create_readback_buffer_and_download(
ID3D12Device *device,
ID3D12GraphicsCommandList * command_list,
DataHeap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> &readback_heap,
data_heap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> &readback_heap,
ID3D12Resource * color_surface,
int color_surface_format
)
@ -812,7 +748,7 @@ namespace
}
size_t buffer_size = row_pitch * clip_h;
assert(readback_heap.canAlloc(buffer_size));
assert(readback_heap.can_alloc(buffer_size));
size_t heapOffset = readback_heap.alloc(buffer_size);
ComPtr<ID3D12Resource> Result;
ThrowIfFailed(
@ -880,7 +816,7 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release()
if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer)
{
size_t uav_size = clip_w * clip_h * 2;
assert(m_UAVHeap.canAlloc(uav_size));
assert(m_UAVHeap.can_alloc(uav_size));
size_t heap_offset = m_UAVHeap.alloc(uav_size);
ThrowIfFailed(
@ -895,7 +831,7 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release()
);
size_t buffer_size = depth_row_pitch * clip_h;
assert(m_readbackResources.canAlloc(buffer_size));
assert(m_readbackResources.can_alloc(buffer_size));
heap_offset = m_readbackResources.alloc(buffer_size);
ThrowIfFailed(
@ -927,22 +863,22 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release()
CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptor_heap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideSRVCBVUAV));
// Convert
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
getCurrentResourceStorage().m_commandList->SetPipelineState(m_convertPSO);
getCurrentResourceStorage().m_commandList->SetComputeRootSignature(m_convertRootSignature);
getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, descriptor_heap.GetAddressOf());
getCurrentResourceStorage().m_commandList->SetComputeRootDescriptorTable(0, descriptor_heap->GetGPUDescriptorHandleForHeapStart());
getCurrentResourceStorage().m_commandList->Dispatch(clip_w / 8, clip_h / 8, 1);
getCurrentResourceStorage().command_list->SetPipelineState(m_convertPSO);
getCurrentResourceStorage().command_list->SetComputeRootSignature(m_convertRootSignature);
getCurrentResourceStorage().command_list->SetDescriptorHeaps(1, descriptor_heap.GetAddressOf());
getCurrentResourceStorage().command_list->SetComputeRootDescriptorTable(0, descriptor_heap->GetGPUDescriptorHandleForHeapStart());
getCurrentResourceStorage().command_list->Dispatch(clip_w / 8, clip_h / 8, 1);
D3D12_RESOURCE_BARRIER barriers[] =
{
CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE),
CD3DX12_RESOURCE_BARRIER::UAV(depth_format_conversion_buffer.Get()),
};
getCurrentResourceStorage().m_commandList->ResourceBarrier(2, barriers);
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depth_format_conversion_buffer.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(depth_buffer_write_dest.Get(), { 0, { DXGI_FORMAT_R8_UNORM, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0,
getCurrentResourceStorage().command_list->ResourceBarrier(2, barriers);
getCurrentResourceStorage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depth_format_conversion_buffer.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
getCurrentResourceStorage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(depth_buffer_write_dest.Get(), { 0, { DXGI_FORMAT_R8_UNORM, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0,
&CD3DX12_TEXTURE_COPY_LOCATION(depth_buffer_write_dest.Get(), 0), nullptr);
invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], m_context_dma_z - 0xfeed0000));
@ -957,16 +893,16 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release()
{
if (!context_dma_color[i])
continue;
readback_buffers[i] = create_readback_buffer_and_download(m_device.Get(), getCurrentResourceStorage().m_commandList.Get(), m_readbackResources, m_rtts.m_currentlyBoundRenderTargets[0], m_surface.color_format);
readback_buffers[i] = create_readback_buffer_and_download(m_device.Get(), getCurrentResourceStorage().command_list.Get(), m_readbackResources, m_rtts.m_currentlyBoundRenderTargets[0], m_surface.color_format);
invalidateAddress(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[i] - 0xfeed0000));
need_transfer = true;
}
}
if (need_transfer)
{
ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
getCurrentResourceStorage().setNewCommandList();
ThrowIfFailed(getCurrentResourceStorage().command_list->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().command_list.GetAddressOf());
getCurrentResourceStorage().set_new_command_list();
}
//Wait for result

View File

@ -11,6 +11,7 @@
#include "D3D12RenderTargetSets.h"
#include "D3D12PipelineState.h"
#include "d3dx12.h"
#include "D3D12MemoryHelpers.h"
/**
@ -35,244 +36,6 @@
* are not currently correctly signaled which leads to deadlock.
*/
template<typename T>
struct InitHeap
{
static T* Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags);
};
template<>
struct InitHeap<ID3D12Heap>
{
static ID3D12Heap* Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{
ID3D12Heap *result;
D3D12_HEAP_DESC heapDesc = {};
heapDesc.SizeInBytes = heapSize;
heapDesc.Properties.Type = type;
heapDesc.Flags = flags;
ThrowIfFailed(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&result)));
return result;
}
};
template<>
struct InitHeap<ID3D12Resource>
{
static ID3D12Resource* Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{
ID3D12Resource *result;
D3D12_HEAP_PROPERTIES heapProperties = {};
heapProperties.Type = type;
ThrowIfFailed(device->CreateCommittedResource(&heapProperties,
flags,
&CD3DX12_RESOURCE_DESC::Buffer(heapSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&result))
);
return result;
}
};
/**
* Wrapper around a ID3D12Resource or a ID3D12Heap.
* Acts as a ring buffer : hold a get and put pointers,
* put pointer is used as storage space offset
* and get is used as beginning of in use data space.
* This wrapper checks that put pointer doesn't cross get one.
*/
template<typename T, size_t Alignment>
struct DataHeap
{
T *m_heap;
size_t m_size;
size_t m_putPos; // Start of free space
size_t m_getPos; // End of free space
void Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{
m_size = heapSize;
m_heap = InitHeap<T>::Init(device, heapSize, type, flags);
m_putPos = 0;
m_getPos = heapSize - 1;
}
/**
* Does alloc cross get position ?
*/
bool canAlloc(size_t size) const
{
size_t allocSize = align(size, Alignment);
size_t currentGetPos = m_getPos;
if (m_putPos + allocSize < m_size)
{
// range before get
if (m_putPos + allocSize < m_getPos)
return true;
// range after get
if (m_putPos > m_getPos)
return true;
return false;
}
else
{
// ..]....[..get..
if (m_putPos < m_getPos)
return false;
// ..get..]...[...
// Actually all resources extending beyond heap space starts at 0
if (allocSize > m_getPos)
return false;
return true;
}
}
size_t alloc(size_t size)
{
assert(canAlloc(size));
size_t allocSize = align(size, Alignment);
if (m_putPos + allocSize < m_size)
{
size_t oldPutPos = m_putPos;
m_putPos += allocSize;
return oldPutPos;
}
else
{
m_putPos = allocSize;
return 0;
}
}
void Release()
{
m_heap->Release();
}
/**
* return current putpos - 1
*/
size_t getCurrentPutPosMinusOne() const
{
return (m_putPos - 1 > 0) ? m_putPos - 1 : m_size - 1;
}
};
struct TextureEntry
{
int m_format;
size_t m_width;
size_t m_height;
size_t m_mipmap;
bool m_isDirty;
TextureEntry() : m_format(0), m_width(0), m_height(0), m_isDirty(true)
{}
TextureEntry(int f, size_t w, size_t h, size_t m) : m_format(f), m_width(w), m_height(h), m_isDirty(false)
{}
bool operator==(const TextureEntry &other)
{
return (m_format == other.m_format && m_width == other.m_width && m_height == other.m_height);
}
};
/**
* Manages cache of data (texture/vertex/index)
*/
struct DataCache
{
private:
/**
* Mutex protecting m_dataCache access
* Memory protection fault catch can be generated by any thread and
* modifies it.
*/
std::mutex mut;
std::unordered_map<u64, std::pair<TextureEntry, ComPtr<ID3D12Resource>> > m_dataCache; // Storage
std::list <std::tuple<u64, u32, u32> > m_protectedRange; // address, start of protected range, size of protected range
public:
void storeAndProtectData(u64 key, u32 start, size_t size, int format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data)
{
std::lock_guard<std::mutex> lock(mut);
m_dataCache[key] = std::make_pair(TextureEntry(format, w, h, m), data);
protectData(key, start, size);
}
/**
* Make memory from start to start + size write protected.
* Associate key to this range so that when a write is detected, data at key is marked dirty.
*/
void protectData(u64 key, u32 start, size_t size)
{
/// align start to 4096 byte
u32 protected_range_start = align(start, 4096);
u32 protected_range_size = (u32)align(size, 4096);
m_protectedRange.push_back(std::make_tuple(key, protected_range_start, protected_range_size));
vm::page_protect(protected_range_start, protected_range_size, 0, 0, vm::page_writable);
}
/// remove all data containing addr from cache, unprotect them. Returns false if no data is modified.
bool invalidateAddress(u32 addr)
{
bool handled = false;
auto It = m_protectedRange.begin(), E = m_protectedRange.end();
for (; It != E;)
{
auto currentIt = It;
++It;
auto protectedTexture = *currentIt;
u32 protectedRangeStart = std::get<1>(protectedTexture), protectedRangeSize = std::get<2>(protectedTexture);
if (addr >= protectedRangeStart && addr <= protectedRangeSize + protectedRangeStart)
{
std::lock_guard<std::mutex> lock(mut);
u64 texadrr = std::get<0>(protectedTexture);
m_dataCache[texadrr].first.m_isDirty = true;
vm::page_protect(protectedRangeStart, protectedRangeSize, 0, vm::page_writable, 0);
m_protectedRange.erase(currentIt);
handled = true;
}
}
return handled;
}
std::pair<TextureEntry, ComPtr<ID3D12Resource> > *findDataIfAvailable(u64 key)
{
std::lock_guard<std::mutex> lock(mut);
auto It = m_dataCache.find(key);
if (It == m_dataCache.end())
return nullptr;
return &It->second;
}
void unprotedAll()
{
std::lock_guard<std::mutex> lock(mut);
for (auto &protectedTexture : m_protectedRange)
{
u32 protectedRangeStart = std::get<1>(protectedTexture), protectedRangeSize = std::get<2>(protectedTexture);
vm::page_protect(protectedRangeStart, protectedRangeSize, 0, vm::page_writable, 0);
}
}
/**
* Remove data stored at key, and returns a ComPtr owning it.
* The caller is responsible for releasing the ComPtr.
*/
ComPtr<ID3D12Resource> removeFromCache(u64 key)
{
auto result = m_dataCache[key].second;
m_dataCache.erase(key);
return result;
}
};
/**
* Structure used to load/unload D3D12 lib.
*/
@ -298,7 +61,7 @@ private:
ComPtr<ID3D12RootSignature> m_rootSignatures[17];
// TODO: Use a tree structure to parse more efficiently
DataCache m_textureCache;
data_cache m_textureCache;
bool invalidateAddress(u32 addr);
// Copy of RTT to be used as texture
@ -350,67 +113,18 @@ private:
ID3D12RootSignature *m_convertRootSignature;
void initConvertShader();
/**
* Stores data that are "ping ponged" between frame.
* For instance command allocator : maintains 2 command allocators and
* swap between them when frame is flipped.
*/
struct ResourceStorage
{
bool m_inUse; // False until command list has been populated at least once
ComPtr<ID3D12Fence> m_frameFinishedFence;
UINT64 m_fenceValue;
HANDLE m_frameFinishedHandle;
// Pointer to device, not owned by ResourceStorage
ID3D12Device *m_device;
ComPtr<ID3D12CommandAllocator> m_commandAllocator;
ComPtr<ID3D12GraphicsCommandList> m_commandList;
// Descriptor heap
ComPtr<ID3D12DescriptorHeap> m_descriptorsHeap;
size_t m_descriptorsHeapIndex;
// Sampler heap
ComPtr<ID3D12DescriptorHeap> m_samplerDescriptorHeap[2];
size_t m_samplerDescriptorHeapIndex;
size_t m_currentSamplerIndex;
ComPtr<ID3D12Resource> m_RAMFramebuffer;
// List of resources that can be freed after frame is flipped
std::vector<ComPtr<ID3D12Resource> > m_singleFrameLifetimeResources;
/// Texture that were invalidated
std::list<ComPtr<ID3D12Resource> > m_dirtyTextures;
size_t m_getPosConstantsHeap;
size_t m_getPosVertexIndexHeap;
size_t m_getPosTextureUploadHeap;
size_t m_getPosReadbackHeap;
size_t m_getPosUAVHeap;
void Reset();
void Init(ID3D12Device *device);
void setNewCommandList();
void WaitAndClean();
void Release();
};
ResourceStorage m_perFrameStorage[2];
ResourceStorage &getCurrentResourceStorage();
ResourceStorage &getNonCurrentResourceStorage();
resource_storage m_perFrameStorage[2];
resource_storage &getCurrentResourceStorage();
resource_storage &getNonCurrentResourceStorage();
// Constants storage
DataHeap<ID3D12Resource, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT> m_constantsData;
data_heap<ID3D12Resource, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT> m_constantsData;
// Vertex storage
DataHeap<ID3D12Resource, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT> m_vertexIndexData;
data_heap<ID3D12Resource, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT> m_vertexIndexData;
// Texture storage
DataHeap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> m_textureUploadData;
DataHeap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> m_UAVHeap;
DataHeap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> m_readbackResources;
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> m_textureUploadData;
data_heap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> m_UAVHeap;
data_heap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> m_readbackResources;
struct
{

View File

@ -0,0 +1,131 @@
#include "stdafx_d3d12.h"
#ifdef _WIN32
#include "D3D12MemoryHelpers.h"
void data_cache::store_and_protect_data(u64 key, u32 start, size_t size, int format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data) noexcept
{
std::lock_guard<std::mutex> lock(m_mut);
m_address_to_data[key] = std::make_pair(texture_entry(format, w, h, m), data);
protect_data(key, start, size);
}
void data_cache::protect_data(u64 key, u32 start, size_t size) noexcept
{
/// align start to 4096 byte
u32 protected_range_start = align(start, 4096);
u32 protected_range_size = (u32)align(size, 4096);
m_protected_ranges.push_back(std::make_tuple(key, protected_range_start, protected_range_size));
vm::page_protect(protected_range_start, protected_range_size, 0, 0, vm::page_writable);
}
bool data_cache::invalidate_address(u32 addr) noexcept
{
bool handled = false;
auto It = m_protected_ranges.begin(), E = m_protected_ranges.end();
for (; It != E;)
{
auto currentIt = It;
++It;
auto protectedTexture = *currentIt;
u32 protectedRangeStart = std::get<1>(protectedTexture), protectedRangeSize = std::get<2>(protectedTexture);
if (addr >= protectedRangeStart && addr <= protectedRangeSize + protectedRangeStart)
{
std::lock_guard<std::mutex> lock(m_mut);
u64 texadrr = std::get<0>(protectedTexture);
m_address_to_data[texadrr].first.m_is_dirty = true;
vm::page_protect(protectedRangeStart, protectedRangeSize, 0, vm::page_writable, 0);
m_protected_ranges.erase(currentIt);
handled = true;
}
}
return handled;
}
std::pair<texture_entry, ComPtr<ID3D12Resource> > *data_cache::find_data_if_available(u64 key) noexcept
{
std::lock_guard<std::mutex> lock(m_mut);
auto It = m_address_to_data.find(key);
if (It == m_address_to_data.end())
return nullptr;
return &It->second;
}
void data_cache::unprotect_all() noexcept
{
std::lock_guard<std::mutex> lock(m_mut);
for (auto &protectedTexture : m_protected_ranges)
{
u32 protectedRangeStart = std::get<1>(protectedTexture), protectedRangeSize = std::get<2>(protectedTexture);
vm::page_protect(protectedRangeStart, protectedRangeSize, 0, vm::page_writable, 0);
}
}
ComPtr<ID3D12Resource> data_cache::remove_from_cache(u64 key) noexcept
{
auto result = m_address_to_data[key].second;
m_address_to_data.erase(key);
return result;
}
void resource_storage::reset()
{
descriptors_heap_index = 0;
current_sampler_index = 0;
sampler_descriptors_heap_index = 0;
ThrowIfFailed(command_allocator->Reset());
set_new_command_list();
}
void resource_storage::set_new_command_list()
{
ThrowIfFailed(command_list->Reset(command_allocator.Get(), nullptr));
}
void resource_storage::init(ID3D12Device *device)
{
in_use = false;
m_device = device;
ram_framebuffer = nullptr;
// Create a global command allocator
ThrowIfFailed(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(command_allocator.GetAddressOf())));
ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator.Get(), nullptr, IID_PPV_ARGS(command_list.GetAddressOf())));
ThrowIfFailed(command_list->Close());
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(&descriptors_heap)));
D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2048, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[0])));
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[1])));
frame_finished_handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence_value = 0;
ThrowIfFailed(device->CreateFence(fence_value++, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(frame_finished_fence.GetAddressOf())));
}
void resource_storage::wait_and_clean()
{
if (in_use)
WaitForSingleObjectEx(frame_finished_handle, INFINITE, FALSE);
else
ThrowIfFailed(command_list->Close());
reset();
dirty_textures.clear();
ram_framebuffer = nullptr;
}
void resource_storage::release()
{
dirty_textures.clear();
// NOTE: Should be released only after gfx pipeline last command has been finished.
CloseHandle(frame_finished_handle);
}
#endif

View File

@ -0,0 +1,238 @@
#pragma once
#include "D3D12Utils.h"
#include "d3dx12.h"
template<typename T>
struct init_heap
{
static T* init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags);
};
template<>
struct init_heap<ID3D12Heap>
{
static ID3D12Heap* init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{
ID3D12Heap *result;
D3D12_HEAP_DESC heap_desc = {};
heap_desc.SizeInBytes = heap_size;
heap_desc.Properties.Type = type;
heap_desc.Flags = flags;
ThrowIfFailed(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&result)));
return result;
}
};
template<>
struct init_heap<ID3D12Resource>
{
static ID3D12Resource* init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{
ID3D12Resource *result;
D3D12_HEAP_PROPERTIES heap_properties = {};
heap_properties.Type = type;
ThrowIfFailed(device->CreateCommittedResource(&heap_properties,
flags,
&CD3DX12_RESOURCE_DESC::Buffer(heap_size),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&result))
);
return result;
}
};
/**
* Wrapper around a ID3D12Resource or a ID3D12Heap.
* Acts as a ring buffer : hold a get and put pointers,
* put pointer is used as storage space offset
* and get is used as beginning of in use data space.
* This wrapper checks that put pointer doesn't cross get one.
*/
template<typename T, size_t alignment>
struct data_heap
{
T *m_heap;
size_t m_size;
size_t m_put_pos; // Start of free space
size_t m_get_pos; // End of free space
void init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{
m_size = heap_size;
m_heap = init_heap<T>::init(device, heap_size, type, flags);
m_put_pos = 0;
m_get_pos = heap_size - 1;
}
/**
* Does alloc cross get position ?
*/
bool can_alloc(size_t size) const noexcept
{
size_t alloc_size = align(size, alignment);
if (m_put_pos + alloc_size < m_size)
{
// range before get
if (m_put_pos + alloc_size < m_get_pos)
return true;
// range after get
if (m_put_pos > m_get_pos)
return true;
return false;
}
else
{
// ..]....[..get..
if (m_put_pos < m_get_pos)
return false;
// ..get..]...[...
// Actually all resources extending beyond heap space starts at 0
if (alloc_size > m_get_pos)
return false;
return true;
}
}
size_t alloc(size_t size) noexcept
{
assert(can_alloc(size));
size_t alloc_size = align(size, alignment);
if (m_put_pos + alloc_size < m_size)
{
size_t old_put_pos = m_put_pos;
m_put_pos += alloc_size;
return old_put_pos;
}
else
{
m_put_pos = alloc_size;
return 0;
}
}
void release() noexcept
{
m_heap->Release();
}
/**
* return current putpos - 1
*/
size_t get_current_put_pos_minus_one() const noexcept
{
return (m_put_pos - 1 > 0) ? m_put_pos - 1 : m_size - 1;
}
};
struct texture_entry
{
int m_format;
size_t m_width;
size_t m_height;
size_t m_mipmap;
bool m_is_dirty;
texture_entry() : m_format(0), m_width(0), m_height(0), m_is_dirty(true)
{}
texture_entry(int f, size_t w, size_t h, size_t m) : m_format(f), m_width(w), m_height(h), m_is_dirty(false)
{}
bool operator==(const texture_entry &other)
{
return (m_format == other.m_format && m_width == other.m_width && m_height == other.m_height);
}
};
/**
* Manages cache of data (texture/vertex/index)
*/
struct data_cache
{
private:
/**
* Mutex protecting m_dataCache access
* Memory protection fault catch can be generated by any thread and
* modifies it.
*/
std::mutex m_mut;
std::unordered_map<u64, std::pair<texture_entry, ComPtr<ID3D12Resource>> > m_address_to_data; // Storage
std::list <std::tuple<u64, u32, u32> > m_protected_ranges; // address, start of protected range, size of protected range
public:
void store_and_protect_data(u64 key, u32 start, size_t size, int format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data) noexcept;
/**
* Make memory from start to start + size write protected.
* Associate key to this range so that when a write is detected, data at key is marked dirty.
*/
void protect_data(u64 key, u32 start, size_t size) noexcept;
/**
* Remove all data containing addr from cache, unprotect them. Returns false if no data is modified.
*/
bool invalidate_address(u32 addr) noexcept;
std::pair<texture_entry, ComPtr<ID3D12Resource> > *find_data_if_available(u64 key) noexcept;
void unprotect_all() noexcept;
/**
* Remove data stored at key, and returns a ComPtr owning it.
* The caller is responsible for releasing the ComPtr.
*/
ComPtr<ID3D12Resource> remove_from_cache(u64 key) noexcept;
};
/**
* Stores data that are "ping ponged" between frame.
* For instance command allocator : maintains 2 command allocators and
* swap between them when frame is flipped.
*/
struct resource_storage
{
bool in_use; // False until command list has been populated at least once
ComPtr<ID3D12Fence> frame_finished_fence;
UINT64 fence_value;
HANDLE frame_finished_handle;
// Pointer to device, not owned by ResourceStorage
ID3D12Device *m_device;
ComPtr<ID3D12CommandAllocator> command_allocator;
ComPtr<ID3D12GraphicsCommandList> command_list;
// Descriptor heap
ComPtr<ID3D12DescriptorHeap> descriptors_heap;
size_t descriptors_heap_index;
// Sampler heap
ComPtr<ID3D12DescriptorHeap> sampler_descriptor_heap[2];
size_t sampler_descriptors_heap_index;
size_t current_sampler_index;
ComPtr<ID3D12Resource> ram_framebuffer;
/// Texture that were invalidated
std::list<ComPtr<ID3D12Resource> > dirty_textures;
/**
* Start position in heaps of resources used for this frame.
* This means newer resources shouldn't allocate memory crossing this position
* until the frame rendering is over.
*/
size_t constants_heap_get_pos;
size_t vertex_index_heap_get_pos;
size_t texture_upload_heap_get_pos;
size_t readback_heap_get_pos;
size_t uav_heap_get_pos;
void reset();
void init(ID3D12Device *device);
void set_new_command_list();
void wait_and_clean();
void release();
};

View File

@ -48,7 +48,7 @@ ComPtr<ID3D12Resource> upload_single_texture(
const rsx::texture &texture,
ID3D12Device *device,
ID3D12GraphicsCommandList *command_list,
DataHeap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &texture_buffer_heap)
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &texture_buffer_heap)
{
size_t w = texture.width(), h = texture.height();
@ -56,7 +56,7 @@ ComPtr<ID3D12Resource> upload_single_texture(
DXGI_FORMAT dxgi_format = get_texture_format(format);
size_t buffer_size = get_placed_texture_storage_size(texture, 256);
assert(texture_buffer_heap.canAlloc(buffer_size));
assert(texture_buffer_heap.can_alloc(buffer_size));
size_t heap_offset = texture_buffer_heap.alloc(buffer_size);
void *buffer;
@ -93,7 +93,7 @@ ComPtr<ID3D12Resource> upload_single_texture(
void update_existing_texture(
const rsx::texture &texture,
ID3D12GraphicsCommandList *command_list,
DataHeap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &texture_buffer_heap,
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &texture_buffer_heap,
ID3D12Resource *existing_texture)
{
size_t w = texture.width(), h = texture.height();
@ -102,7 +102,7 @@ void update_existing_texture(
DXGI_FORMAT dxgi_format = get_texture_format(format);
size_t buffer_size = get_placed_texture_storage_size(texture, 256);
assert(texture_buffer_heap.canAlloc(buffer_size));
assert(texture_buffer_heap.can_alloc(buffer_size));
size_t heap_offset = texture_buffer_heap.alloc(buffer_size);
void *buffer;
@ -141,29 +141,29 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
ID3D12Resource *vram_texture;
std::unordered_map<u32, ID3D12Resource* >::const_iterator ItRTT = m_rtts.m_renderTargets.find(texaddr);
std::pair<TextureEntry, ComPtr<ID3D12Resource> > *cached_texture = m_textureCache.findDataIfAvailable(texaddr);
std::pair<texture_entry, ComPtr<ID3D12Resource> > *cached_texture = m_textureCache.find_data_if_available(texaddr);
bool isRenderTarget = false;
if (ItRTT != m_rtts.m_renderTargets.end())
{
vram_texture = ItRTT->second;
isRenderTarget = true;
}
else if (cached_texture != nullptr && (cached_texture->first == TextureEntry(format, w, h, textures[i].mipmap())))
else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].mipmap())))
{
if (cached_texture->first.m_isDirty)
if (cached_texture->first.m_is_dirty)
{
update_existing_texture(textures[i], command_list, m_textureUploadData, cached_texture->second.Get());
m_textureCache.protectData(texaddr, texaddr, get_texture_size(textures[i]));
m_textureCache.protect_data(texaddr, texaddr, get_texture_size(textures[i]));
}
vram_texture = cached_texture->second.Get();
}
else
{
if (cached_texture != nullptr)
getCurrentResourceStorage().m_dirtyTextures.push_back(m_textureCache.removeFromCache(texaddr));
getCurrentResourceStorage().dirty_textures.push_back(m_textureCache.remove_from_cache(texaddr));
ComPtr<ID3D12Resource> tex = upload_single_texture(textures[i], m_device.Get(), command_list, m_textureUploadData);
vram_texture = tex.Get();
m_textureCache.storeAndProtectData(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].mipmap(), tex);
m_textureCache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].mipmap(), tex);
}
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {};
@ -291,17 +291,17 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
}
m_device->CreateShaderResourceView(vram_texture, &shared_resource_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
.Offset((UINT)descriptor_index + (UINT)used_texture, g_descriptorStrideSRVCBVUAV));
if (getCurrentResourceStorage().m_currentSamplerIndex + 16 > 2048)
if (getCurrentResourceStorage().current_sampler_index + 16 > 2048)
{
getCurrentResourceStorage().m_samplerDescriptorHeapIndex = 1;
getCurrentResourceStorage().m_currentSamplerIndex = 0;
getCurrentResourceStorage().sampler_descriptors_heap_index = 1;
getCurrentResourceStorage().current_sampler_index = 0;
}
m_device->CreateSampler(&get_sampler_desc(textures[i]),
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart())
.Offset((UINT)getCurrentResourceStorage().m_currentSamplerIndex + (UINT)used_texture, g_descriptorStrideSamplers));
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().sampler_descriptor_heap[getCurrentResourceStorage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart())
.Offset((UINT)getCurrentResourceStorage().current_sampler_index + (UINT)used_texture, g_descriptorStrideSamplers));
used_texture++;
}
@ -319,7 +319,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0);
m_device->CreateShaderResourceView(m_dummyTexture, &shader_resource_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptor_index + (INT)used_texture, g_descriptorStrideSRVCBVUAV)
);
@ -329,8 +329,8 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
m_device->CreateSampler(&sampler_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)getCurrentResourceStorage().m_currentSamplerIndex + (INT)used_texture, g_descriptorStrideSamplers)
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().sampler_descriptor_heap[getCurrentResourceStorage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)getCurrentResourceStorage().current_sampler_index + (INT)used_texture, g_descriptorStrideSamplers)
);
}
}