mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
d3d12: Gather constant and vtx/idx heap and turn readback heap to buffer
This commit is contained in:
parent
d08ce79d04
commit
0c5cfdddba
6 changed files with 157 additions and 232 deletions
|
@ -13,18 +13,14 @@ namespace
|
|||
/**
|
||||
*
|
||||
*/
|
||||
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)
|
||||
D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector<u8> &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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<float>(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<D3D12_VERTEX_BUFFER_VIEW> 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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<void>(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<D3D12_VERTEX_BUFFER_VIEW> 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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<void>(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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<void>(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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<void>(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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<int>(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<float>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
m_pso_cache.fill_fragment_constans_buffer({ mapped_buffer, gsl::narrow<int>(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<D3D12_VERTEX_BUFFER_VIEW, size_t> 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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||
void *mapped_buffer = m_buffer_data.map<void>(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<D3D12_INDEX_BUFFER_VIEW, size_t> 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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
size_t first = 0;
|
||||
for (const auto &pair : vertex_ranges)
|
||||
{
|
||||
|
@ -297,9 +274,9 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> 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<bool, size_t> 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<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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<void>(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<bool, size_t> 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)
|
||||
};
|
||||
|
|
|
@ -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<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(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<void>(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);
|
||||
|
|
|
@ -112,14 +112,9 @@ private:
|
|||
resource_storage &get_current_resource_storage();
|
||||
resource_storage &get_non_current_resource_storage();
|
||||
|
||||
// Constants storage
|
||||
data_heap<ID3D12Resource, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT> m_constants_data;
|
||||
// Vertex storage
|
||||
data_heap<ID3D12Resource, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT> m_vertex_index_data;
|
||||
// Texture storage
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> m_texture_upload_data;
|
||||
data_heap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> m_uav_heap;
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> m_readback_resources;
|
||||
// Textures, constants, index and vertex buffers storage
|
||||
data_heap m_buffer_data;
|
||||
data_heap m_readback_resources;
|
||||
|
||||
render_targets m_rtts;
|
||||
|
||||
|
|
|
@ -3,48 +3,6 @@
|
|||
#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;
|
||||
CHECK_HRESULT(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_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<ID3D12Resource>
|
|||
* 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
|
||||
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 <typename... arg_type>
|
||||
void init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, arg_type... args)
|
||||
{
|
||||
m_size = heap_size;
|
||||
m_heap = init_heap<T>::init(device, heap_size, type, args...);
|
||||
m_put_pos = 0;
|
||||
m_get_pos = heap_size - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does alloc cross get position ?
|
||||
*/
|
||||
template<int Alignement>
|
||||
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<ID3D12Resource> m_heap;
|
||||
public:
|
||||
size_t m_get_pos; // End of free space
|
||||
|
||||
template <typename... arg_type>
|
||||
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<int Alignement>
|
||||
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<Alignement>(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<typename T>
|
||||
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<T*>(mapped_buffer);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<T*>(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);
|
||||
|
|
|
@ -366,7 +366,7 @@ namespace
|
|||
size_t download_to_readback_buffer(
|
||||
ID3D12Device *device,
|
||||
ID3D12GraphicsCommandList * command_list,
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &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<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(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<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &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<void>(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<u32>::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<u8>(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<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(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<void>(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<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(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<void>(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
|
||||
|
|
|
@ -49,7 +49,7 @@ ComPtr<ID3D12Resource> upload_single_texture(
|
|||
const rsx::texture &texture,
|
||||
ID3D12Device *device,
|
||||
ID3D12GraphicsCommandList *command_list,
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &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<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.can_alloc(buffer_size));
|
||||
size_t heap_offset = texture_buffer_heap.alloc(buffer_size);
|
||||
size_t heap_offset = texture_buffer_heap.alloc<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(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<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
std::vector<MipmapLevelInfo> 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<ID3D12Resource> result;
|
||||
CHECK_HRESULT(device->CreateCommittedResource(
|
||||
|
@ -83,7 +80,7 @@ ComPtr<ID3D12Resource> 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<ID3D12Resource> upload_single_texture(
|
|||
void update_existing_texture(
|
||||
const rsx::texture &texture,
|
||||
ID3D12GraphicsCommandList *command_list,
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &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<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(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<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
std::vector<MipmapLevelInfo> 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<ID3D12Resource> tex = upload_single_texture(textures[i], m_device.Get(), command_list, m_texture_upload_data);
|
||||
ComPtr<ID3D12Resource> 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();
|
||||
|
|
Loading…
Add table
Reference in a new issue