mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 18:53:28 +01:00
d3d12: Move storage helpers to their dedicated files.
This commit is contained in:
parent
fdae12c52e
commit
124d0de325
@ -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" />
|
||||
|
@ -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>
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
131
rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.cpp
Normal file
131
rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.cpp
Normal 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
|
238
rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h
Normal file
238
rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h
Normal 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();
|
||||
};
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user