diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index fed8ad14e9..0c88a57585 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -13,18 +13,14 @@ namespace /** * */ -D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector &vertex_data, ID3D12Device *device, data_heap &vertex_index_heap) +D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector &vertex_data, ID3D12Device *device, data_heap &vertex_index_heap) { size_t buffer_size = vertex_data.size(); - assert(vertex_index_heap.can_alloc(buffer_size)); - size_t heap_offset = vertex_index_heap.alloc(buffer_size); + size_t heap_offset = vertex_index_heap.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(vertex_index_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer)); - void *bufferMap = (char*)buffer + heap_offset; - memcpy(bufferMap, vertex_data.data(), vertex_data.size()); - vertex_index_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); - return vertex_index_heap.m_heap->GetGPUVirtualAddress() + heap_offset; + memcpy(vertex_index_heap.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)), vertex_data.data(), vertex_data.size()); + vertex_index_heap.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + return vertex_index_heap.get_heap()->GetGPUVirtualAddress() + heap_offset; } } @@ -63,22 +59,19 @@ std::vector D3D12GSRender::upload_vertex_attributes(co u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); size_t buffer_size = element_size * vertex_count; - assert(m_vertex_index_data.can_alloc(buffer_size)); - size_t heap_offset = m_vertex_index_data.alloc(buffer_size); + size_t heap_offset = m_buffer_data.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); for (const auto &range : vertex_ranges) { write_vertex_array_data_to_buffer(mapped_buffer, range.first, range.second, index, info); mapped_buffer = (char*)mapped_buffer + range.second * element_size; } - m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = { - m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size, (UINT)element_size }; @@ -106,17 +99,14 @@ std::vector D3D12GSRender::upload_vertex_attributes(co u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); size_t buffer_size = data.size(); - assert(m_vertex_index_data.can_alloc(buffer_size)); - size_t heap_offset = m_vertex_index_data.alloc(buffer_size); + size_t heap_offset = m_buffer_data.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); memcpy(mapped_buffer, data.data(), data.size()); - m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = { - m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size, (UINT)element_size }; @@ -143,18 +133,16 @@ void D3D12GSRender::load_vertex_index_data(u32 first, u32 count) void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) { - assert(m_constants_data.can_alloc(256)); - size_t heap_offset = m_constants_data.alloc(256); + size_t heap_offset = m_buffer_data.alloc(256); // Scale offset buffer // Separate constant buffer - void *mapped_buffer; - CHECK_HRESULT(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256), &mapped_buffer)); - fill_scale_offset_data((char*)mapped_buffer + heap_offset); + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + 256)); + fill_scale_offset_data(mapped_buffer); int is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]); float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF]; - memcpy((char*)mapped_buffer + heap_offset + 16 * sizeof(float), &is_alpha_tested, sizeof(int)); - memcpy((char*)mapped_buffer + heap_offset + 17 * sizeof(float), &alpha_ref, sizeof(float)); + memcpy((char*)mapped_buffer + 16 * sizeof(float), &is_alpha_tested, sizeof(int)); + memcpy((char*)mapped_buffer + 17 * sizeof(float), &alpha_ref, sizeof(float)); size_t tex_idx = 0; for (u32 i = 0; i < rsx::limits::textures_count; ++i) @@ -162,19 +150,19 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) if (!textures[i].enabled()) { int is_unorm = false; - memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); + memcpy((char*)mapped_buffer + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); continue; } size_t w = textures[i].width(), h = textures[i].height(); // if (!w || !h) continue; int is_unorm = (textures[i].format() & CELL_GCM_TEXTURE_UN); - memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); + memcpy((char*)mapped_buffer + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); } - m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 256)); D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = { - m_constants_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, 256 }; m_device->CreateConstantBufferView(&constant_buffer_view_desc, @@ -186,16 +174,14 @@ void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_in { size_t buffer_size = 512 * 4 * sizeof(float); - assert(m_constants_data.can_alloc(buffer_size)); - size_t heap_offset = m_constants_data.alloc(buffer_size); + size_t heap_offset = m_buffer_data.alloc(buffer_size); - void *mapped_buffer; - CHECK_HRESULT(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer)); - fill_vertex_program_constants_data((char*)mapped_buffer + heap_offset); - m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + fill_vertex_program_constants_data(mapped_buffer); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = { - m_constants_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size }; m_device->CreateConstantBufferView(&constant_buffer_view_desc, @@ -210,18 +196,15 @@ void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_ // Multiple of 256 never 0 buffer_size = (buffer_size + 255) & ~255; - assert(m_constants_data.can_alloc(buffer_size)); - size_t heap_offset = m_constants_data.alloc(buffer_size); + size_t heap_offset = m_buffer_data.alloc(buffer_size); size_t offset = 0; - void *mapped_buffer; - CHECK_HRESULT(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer)); - float *buffer = (float*)((char*)mapped_buffer + heap_offset); - m_pso_cache.fill_fragment_constans_buffer({ buffer, gsl::narrow(buffer_size) }, fragment_program); - m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + float *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + m_pso_cache.fill_fragment_constans_buffer({ mapped_buffer, gsl::narrow(buffer_size) }, fragment_program); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = { - m_constants_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size }; m_device->CreateConstantBufferView(&constant_buffer_view_desc, @@ -257,17 +240,14 @@ std::tuple D3D12GSRender::upload_inlined_verte // Copy inline buffer size_t buffer_size = inline_vertex_array.size() * sizeof(int); - assert(m_vertex_index_data.can_alloc(buffer_size)); - size_t heap_offset = m_vertex_index_data.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + size_t heap_offset = m_buffer_data.alloc(buffer_size); + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); write_inline_array_to_buffer(mapped_buffer); - m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = { - m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size, (UINT)offset }; @@ -283,12 +263,9 @@ std::tuple D3D12GSRender::generate_index_buffer // Alloc size_t buffer_size = align(index_count * sizeof(u16), 64); - assert(m_vertex_index_data.can_alloc(buffer_size)); - size_t heap_offset = m_vertex_index_data.alloc(buffer_size); + size_t heap_offset = m_buffer_data.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); size_t first = 0; for (const auto &pair : vertex_ranges) { @@ -297,9 +274,9 @@ std::tuple D3D12GSRender::generate_index_buffer mapped_buffer = (char*)mapped_buffer + element_count * sizeof(u16); first += pair.second; } - m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_INDEX_BUFFER_VIEW index_buffer_view = { - m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size, DXGI_FORMAT_R16_UINT }; @@ -359,12 +336,9 @@ std::tuple D3D12GSRender::upload_and_set_vertex_index_data(ID3D12G // Alloc size_t buffer_size = align(index_count * index_size, 64); - assert(m_vertex_index_data.can_alloc(buffer_size)); - size_t heap_offset = m_vertex_index_data.alloc(buffer_size); + size_t heap_offset = m_buffer_data.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); u32 min_index = (u32)-1, max_index = 0; for (const auto &pair : m_first_count_pairs) { @@ -372,9 +346,9 @@ std::tuple D3D12GSRender::upload_and_set_vertex_index_data(ID3D12G write_index_array_data_to_buffer((char*)mapped_buffer, draw_mode, pair.first, pair.second, min_index, max_index); mapped_buffer = (char*)mapped_buffer + element_count * index_size; } - m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); D3D12_INDEX_BUFFER_VIEW index_buffer_view = { - m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset, + m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset, (UINT)buffer_size, get_index_type(indexed_type) }; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 4bfe538f92..19decce16f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -195,14 +195,9 @@ D3D12GSRender::D3D12GSRender() IID_PPV_ARGS(&m_dummy_texture)) ); - m_readback_resources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST); - m_uav_heap.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_constants_data.init(m_device.Get(), 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); - m_vertex_index_data.init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); - m_texture_upload_data.init(m_device.Get(), 1024 * 1024 * 512, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); + m_readback_resources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST); + m_buffer_data.init(m_device.Get(), 1024 * 1024 * 896, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); if (rpcs3::config.rsx.d3d12.overlay.value()) init_d2d_structures(); @@ -215,11 +210,6 @@ D3D12GSRender::~D3D12GSRender() m_texture_cache.unprotect_all(); gfxHandler = [this](u32) { return false; }; - m_constants_data.release(); - m_vertex_index_data.release(); - m_texture_upload_data.release(); - m_uav_heap.m_heap->Release(); - m_readback_resources.m_heap->Release(); m_dummy_texture->Release(); m_convertPSO->Release(); m_convertRootSignature->Release(); @@ -405,15 +395,12 @@ void D3D12GSRender::flip(int buffer) row_pitch = align(w * 4, 256); size_t texture_size = row_pitch * h; // * 4 for mipmap levels - assert(m_texture_upload_data.can_alloc(texture_size)); - size_t heap_offset = m_texture_upload_data.alloc(texture_size); + size_t heap_offset = m_buffer_data.alloc(texture_size); - void *buffer; - CHECK_HRESULT(m_texture_upload_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + texture_size), &buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = m_buffer_data.map(heap_offset); for (unsigned row = 0; row < h; row++) memcpy((char*)mapped_buffer + row * row_pitch, (char*)src_buffer + row * w * 4, w * 4); - m_texture_upload_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + texture_size)); + m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + texture_size)); offset = heap_offset; } @@ -428,7 +415,7 @@ void D3D12GSRender::flip(int buffer) ) ); get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.ram_framebuffer.Get(), 0), 0, 0, 0, - &CD3DX12_TEXTURE_COPY_LOCATION(m_texture_upload_data.m_heap, { offset, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)row_pitch } }), nullptr); + &CD3DX12_TEXTURE_COPY_LOCATION(m_buffer_data.get_heap(), { offset, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)row_pitch } }), nullptr); get_current_resource_storage().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(); @@ -550,11 +537,8 @@ void D3D12GSRender::flip(int buffer) // 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.constants_heap_get_pos = m_constants_data.get_current_put_pos_minus_one(); - storage.vertex_index_heap_get_pos = m_vertex_index_data.get_current_put_pos_minus_one(); - storage.texture_upload_heap_get_pos = m_texture_upload_data.get_current_put_pos_minus_one(); + storage.buffer_heap_get_pos = m_buffer_data.get_current_put_pos_minus_one(); storage.readback_heap_get_pos = m_readback_resources.get_current_put_pos_minus_one(); - storage.uav_heap_get_pos = m_uav_heap.get_current_put_pos_minus_one(); // Now get ready for next frame resource_storage &new_storage = get_current_resource_storage(); @@ -562,11 +546,8 @@ void D3D12GSRender::flip(int buffer) new_storage.wait_and_clean(); if (new_storage.in_use) { - m_constants_data.m_get_pos = new_storage.constants_heap_get_pos; - m_vertex_index_data.m_get_pos = new_storage.vertex_index_heap_get_pos; - m_texture_upload_data.m_get_pos = new_storage.texture_upload_heap_get_pos; + m_buffer_data.m_get_pos = new_storage.buffer_heap_get_pos; m_readback_resources.m_get_pos = new_storage.readback_heap_get_pos; - m_uav_heap.m_get_pos = new_storage.uav_heap_get_pos; } m_frame->flip(nullptr); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index dbaa4ab0bd..775f31c7c1 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -112,14 +112,9 @@ private: resource_storage &get_current_resource_storage(); resource_storage &get_non_current_resource_storage(); - // Constants storage - data_heap m_constants_data; - // Vertex storage - data_heap m_vertex_index_data; - // Texture storage - data_heap m_texture_upload_data; - data_heap m_uav_heap; - data_heap m_readback_resources; + // Textures, constants, index and vertex buffers storage + data_heap m_buffer_data; + data_heap m_readback_resources; render_targets m_rtts; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h b/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h index 62d7f8e1c6..3e9af2d640 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h @@ -3,48 +3,6 @@ #include "d3dx12.h" -template -struct init_heap -{ - static T* init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags); -}; - -template<> -struct init_heap -{ - 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; - CHECK_HRESULT(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&result))); - return result; - } -}; - -template<> -struct init_heap -{ - static ID3D12Resource* init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_RESOURCE_STATES state) - { - ID3D12Resource *result; - D3D12_HEAP_PROPERTIES heap_properties = {}; - heap_properties.Type = type; - CHECK_HRESULT(device->CreateCommittedResource(&heap_properties, - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(heap_size), - state, - 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, @@ -52,43 +10,30 @@ struct init_heap * and get is used as beginning of in use data space. * This wrapper checks that put pointer doesn't cross get one. */ -template -struct data_heap +class 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 - - template - void init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, arg_type... args) - { - m_size = heap_size; - m_heap = init_heap::init(device, heap_size, type, args...); - m_put_pos = 0; - m_get_pos = heap_size - 1; - } - /** * Does alloc cross get position ? */ + template bool can_alloc(size_t size) const { - size_t alloc_size = align(size, alignment); - if (m_put_pos + alloc_size < m_size) + size_t alloc_size = align(size, Alignement); + size_t aligned_put_pos = align(m_put_pos, Alignement); + if (aligned_put_pos + alloc_size < m_size) { // range before get - if (m_put_pos + alloc_size < m_get_pos) + if (aligned_put_pos + alloc_size < m_get_pos) return true; // range after get - if (m_put_pos > m_get_pos) + if (aligned_put_pos > m_get_pos) return true; return false; } else { // ..]....[..get.. - if (m_put_pos < m_get_pos) + if (aligned_put_pos < m_get_pos) return false; // ..get..]...[... // Actually all resources extending beyond heap space starts at 0 @@ -98,15 +43,40 @@ struct data_heap } } + size_t m_size; + size_t m_put_pos; // Start of free space + ComPtr m_heap; +public: + size_t m_get_pos; // End of free space + + template + void init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_RESOURCE_STATES state) + { + m_size = heap_size; + m_put_pos = 0; + m_get_pos = heap_size - 1; + + D3D12_HEAP_PROPERTIES heap_properties = {}; + heap_properties.Type = type; + CHECK_HRESULT(device->CreateCommittedResource(&heap_properties, + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(heap_size), + state, + nullptr, + IID_PPV_ARGS(m_heap.GetAddressOf())) + ); + } + + template size_t alloc(size_t size) { - assert(can_alloc(size)); - size_t alloc_size = align(size, alignment); - if (m_put_pos + alloc_size < m_size) + if (!can_alloc(size)) throw EXCEPTION("Working buffer not big enough"); + size_t alloc_size = align(size, Alignement); + size_t aligned_put_pos = align(m_put_pos, Alignement); + if (aligned_put_pos + alloc_size < m_size) { - size_t old_put_pos = m_put_pos; - m_put_pos += alloc_size; - return old_put_pos; + m_put_pos = aligned_put_pos + alloc_size; + return aligned_put_pos; } else { @@ -115,9 +85,37 @@ struct data_heap } } - void release() + template + T* map(const D3D12_RANGE &range) { - m_heap->Release(); + void *buffer; + CHECK_HRESULT(m_heap->Map(0, &range, &buffer)); + void *mapped_buffer = (char*)buffer + range.Begin; + return static_cast(mapped_buffer); + } + + template + T* map(size_t heap_offset) + { + void *buffer; + CHECK_HRESULT(m_heap->Map(0, nullptr, &buffer)); + void *mapped_buffer = (char*)buffer + heap_offset; + return static_cast(mapped_buffer); + } + + void unmap(const D3D12_RANGE &range) + { + m_heap->Unmap(0, &range); + } + + void unmap() + { + m_heap->Unmap(0, nullptr); + } + + ID3D12Resource* get_heap() + { + return m_heap.Get(); } /** @@ -230,11 +228,8 @@ struct resource_storage * 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 buffer_heap_get_pos; size_t readback_heap_get_pos; - size_t uav_heap_get_pos; void reset(); void init(ID3D12Device *device); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index c940631c59..7289595104 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -366,7 +366,7 @@ namespace size_t download_to_readback_buffer( ID3D12Device *device, ID3D12GraphicsCommandList * command_list, - data_heap &readback_heap, + data_heap &readback_heap, ID3D12Resource * color_surface, int color_surface_format ) @@ -390,23 +390,20 @@ namespace } size_t buffer_size = row_pitch * clip_h; - assert(readback_heap.can_alloc(buffer_size)); - size_t heap_offset = readback_heap.alloc(buffer_size); + size_t heap_offset = readback_heap.alloc(buffer_size); command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(color_surface, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE)); - command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(readback_heap.m_heap, { heap_offset, { dxgi_format, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, + command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(readback_heap.get_heap(), { heap_offset, { dxgi_format, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, &CD3DX12_TEXTURE_COPY_LOCATION(color_surface, 0), nullptr); command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(color_surface, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); return heap_offset; } - void copy_readback_buffer_to_dest(void *dest, data_heap &readback_heap, size_t offset_in_heap, size_t dst_pitch, size_t src_pitch, size_t height) + void copy_readback_buffer_to_dest(void *dest, data_heap &readback_heap, size_t offset_in_heap, size_t dst_pitch, size_t src_pitch, size_t height) { - void *buffer; // TODO: Use exact range - CHECK_HRESULT(readback_heap.m_heap->Map(0, nullptr, &buffer)); - void *mapped_buffer = (char*)buffer + offset_in_heap; + void *mapped_buffer = readback_heap.map(offset_in_heap); for (unsigned row = 0; row < height; row++) { u32 *casted_dest = (u32*)((char*)dest + row * dst_pitch); @@ -414,7 +411,7 @@ namespace for (unsigned col = 0; col < src_pitch / 4; col++) *casted_dest++ = se_storage::swap(*casted_src++); } - readback_heap.m_heap->Unmap(0, nullptr); + readback_heap.unmap(); } void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_queue) @@ -474,13 +471,11 @@ void D3D12GSRender::copy_render_target_to_dma_location() if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer) { size_t uav_size = clip_w * clip_h * 2; - assert(m_uav_heap.can_alloc(uav_size)); - size_t heap_offset = m_uav_heap.alloc(uav_size); CHECK_HRESULT( - m_device->CreatePlacedResource( - m_uav_heap.m_heap, - heap_offset, + m_device->CreateCommittedResource( + &D3D12_HEAP_PROPERTIES{D3D12_HEAP_TYPE_DEFAULT}, + D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM, clip_w, clip_h, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, @@ -521,7 +516,7 @@ void D3D12GSRender::copy_render_target_to_dma_location() }; get_current_resource_storage().command_list->ResourceBarrier(2, barriers); get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depth_format_conversion_buffer.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); - get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.m_heap, { depth_buffer_offset_in_heap,{ DXGI_FORMAT_R8_UNORM, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0, + get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { depth_buffer_offset_in_heap,{ DXGI_FORMAT_R8_UNORM, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0, &CD3DX12_TEXTURE_COPY_LOCATION(depth_format_conversion_buffer.Get(), 0), nullptr); invalidate_address(address_z); @@ -555,10 +550,7 @@ void D3D12GSRender::copy_render_target_to_dma_location() { auto ptr = vm::base(address_z); char *depth_buffer = (char*)ptr; - void *buffer; - // TODO: Use exact range - CHECK_HRESULT(m_readback_resources.m_heap->Map(0, nullptr, &buffer)); - unsigned char *mapped_buffer = (unsigned char*)buffer + depth_buffer_offset_in_heap; + u8 *mapped_buffer = m_readback_resources.map(depth_buffer_offset_in_heap); for (unsigned row = 0; row < (unsigned)clip_h; row++) { @@ -571,7 +563,7 @@ void D3D12GSRender::copy_render_target_to_dma_location() depth_buffer[4 * (row * clip_w + i) + 3] = c; } } - m_readback_resources.m_heap->Unmap(0, nullptr); + m_readback_resources.unmap(); } size_t srcPitch, dstPitch; @@ -651,12 +643,11 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer) size_t row_pitch = align(clip_w * 4, 256); size_t buffer_size = row_pitch * clip_h; - assert(m_readback_resources.can_alloc(buffer_size)); - size_t heap_offset = m_readback_resources.alloc(buffer_size); + size_t heap_offset = m_readback_resources.alloc(buffer_size); get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.bound_depth_stencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE)); - get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.m_heap, { heap_offset,{ DXGI_FORMAT_R32_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, + get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { heap_offset,{ DXGI_FORMAT_R32_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, &CD3DX12_TEXTURE_COPY_LOCATION(m_rtts.bound_depth_stencil, 0), nullptr); get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.bound_depth_stencil, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); @@ -667,9 +658,7 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer) wait_for_command_queue(m_device.Get(), m_command_queue.Get()); m_readback_resources.m_get_pos = m_readback_resources.get_current_put_pos_minus_one(); - void *temp_buffer; - CHECK_HRESULT(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer)); - void *mapped_buffer = (char*)temp_buffer + heap_offset; + void *mapped_buffer = m_readback_resources.map(heap_offset); for (unsigned row = 0; row < clip_h; row++) { u32 *casted_dest = (u32*)((char*)buffer + row * clip_w * 4); @@ -677,7 +666,7 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer) for (unsigned col = 0; col < row_pitch / 4; col++) *casted_dest++ = *casted_src++; } - m_readback_resources.m_heap->Unmap(0, nullptr); + m_readback_resources.unmap(); } @@ -689,12 +678,11 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer) size_t row_pitch = align(clip_w * 4, 256); size_t buffer_size = row_pitch * clip_h; - assert(m_readback_resources.can_alloc(buffer_size)); - size_t heap_offset = m_readback_resources.alloc(buffer_size); + size_t heap_offset = m_readback_resources.alloc(buffer_size); get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.bound_depth_stencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE)); - get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.m_heap, { heap_offset, { DXGI_FORMAT_R8_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, + get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { heap_offset, { DXGI_FORMAT_R8_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0, &CD3DX12_TEXTURE_COPY_LOCATION(m_rtts.bound_depth_stencil, 1), nullptr); get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.bound_depth_stencil, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); @@ -705,9 +693,7 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer) wait_for_command_queue(m_device.Get(), m_command_queue.Get()); m_readback_resources.m_get_pos = m_readback_resources.get_current_put_pos_minus_one(); - void *temp_buffer; - CHECK_HRESULT(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer)); - void *mapped_buffer = (char*)temp_buffer + heap_offset; + void *mapped_buffer = m_readback_resources.map(heap_offset); for (unsigned row = 0; row < clip_h; row++) { char *casted_dest = (char*)buffer + row * clip_w; @@ -715,7 +701,7 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer) for (unsigned col = 0; col < row_pitch; col++) *casted_dest++ = *casted_src++; } - m_readback_resources.m_heap->Unmap(0, nullptr); + m_readback_resources.unmap(); } #endif diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 09eb91b5ac..da8a4adeee 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -49,7 +49,7 @@ ComPtr upload_single_texture( const rsx::texture &texture, ID3D12Device *device, ID3D12GraphicsCommandList *command_list, - data_heap &texture_buffer_heap) + data_heap &texture_buffer_heap) { size_t w = texture.width(), h = texture.height(); size_t depth = texture.depth(); @@ -60,14 +60,11 @@ ComPtr 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.can_alloc(buffer_size)); - size_t heap_offset = texture_buffer_heap.alloc(buffer_size); + size_t heap_offset = texture_buffer_heap.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(texture_buffer_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = texture_buffer_heap.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); std::vector mipInfos = upload_placed_texture(texture, 256, mapped_buffer); - texture_buffer_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + texture_buffer_heap.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); ComPtr result; CHECK_HRESULT(device->CreateCommittedResource( @@ -83,7 +80,7 @@ ComPtr upload_single_texture( for (const MipmapLevelInfo mli : mipInfos) { command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(result.Get(), (UINT)mip_level), 0, 0, 0, - &CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.m_heap, { heap_offset + mli.offset, { dxgi_format, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr); + &CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.get_heap(), { heap_offset + mli.offset, { dxgi_format, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr); mip_level++; } @@ -97,7 +94,7 @@ ComPtr upload_single_texture( void update_existing_texture( const rsx::texture &texture, ID3D12GraphicsCommandList *command_list, - data_heap &texture_buffer_heap, + data_heap &texture_buffer_heap, ID3D12Resource *existing_texture) { size_t w = texture.width(), h = texture.height(); @@ -106,21 +103,18 @@ 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.can_alloc(buffer_size)); - size_t heap_offset = texture_buffer_heap.alloc(buffer_size); + size_t heap_offset = texture_buffer_heap.alloc(buffer_size); - void *buffer; - CHECK_HRESULT(texture_buffer_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &buffer)); - void *mapped_buffer = (char*)buffer + heap_offset; + void *mapped_buffer = texture_buffer_heap.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); std::vector mipInfos = upload_placed_texture(texture, 256, mapped_buffer); - texture_buffer_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); + texture_buffer_heap.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size)); command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(existing_texture, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_COPY_DEST)); size_t miplevel = 0; for (const MipmapLevelInfo mli : mipInfos) { command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(existing_texture, (UINT)miplevel), 0, 0, 0, - &CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.m_heap, { heap_offset + mli.offset,{ dxgi_format, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr); + &CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.get_heap(), { heap_offset + mli.offset,{ dxgi_format, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr); miplevel++; } @@ -191,7 +185,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ { if (cached_texture->first.m_is_dirty) { - update_existing_texture(textures[i], command_list, m_texture_upload_data, cached_texture->second.Get()); + update_existing_texture(textures[i], command_list, m_buffer_data, cached_texture->second.Get()); m_texture_cache.protect_data(texaddr, texaddr, get_texture_size(textures[i])); } vram_texture = cached_texture->second.Get(); @@ -200,7 +194,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_ { if (cached_texture != nullptr) get_current_resource_storage().dirty_textures.push_back(m_texture_cache.remove_from_cache(texaddr)); - ComPtr tex = upload_single_texture(textures[i], m_device.Get(), command_list, m_texture_upload_data); + ComPtr tex = upload_single_texture(textures[i], m_device.Get(), command_list, m_buffer_data); std::wstring name = L"texture_@" + std::to_wstring(texaddr); tex->SetName(name.c_str()); vram_texture = tex.Get();