Merge pull request #1289 from vlj/d3d12

D3d12: Fixes
This commit is contained in:
Ivan 2015-11-14 14:01:26 +03:00
commit b46c66b4c7
8 changed files with 103 additions and 56 deletions

View file

@ -62,11 +62,13 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
namespace namespace
{ {
template<typename IndexType> template<typename IndexType>
void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) noexcept void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index) noexcept
{ {
for (u32 i = 0; i < indexCount; ++i) for (u32 i = 0; i < indexCount; ++i)
{ {
IndexType index = vm::ps3::_ref<IndexType>(address + i * sizeof(IndexType)); IndexType index = vm::ps3::_ref<IndexType>(address + i * sizeof(IndexType));
if (is_primitive_restart_enabled && index == (IndexType)primitive_restart_index)
index = (IndexType)-1;
(IndexType&)dst[i * sizeof(IndexType)] = index; (IndexType&)dst[i * sizeof(IndexType)] = index;
if (is_primitive_restart_enabled && index == (IndexType)-1) // Cut if (is_primitive_restart_enabled && index == (IndexType)-1) // Cut
continue; continue;
@ -75,16 +77,25 @@ void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_res
} }
} }
// FIXME: expanded primitive type may not support primitive restart correctly
template<typename IndexType> template<typename IndexType>
void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) noexcept void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index) noexcept
{ {
for (unsigned i = 0; i < indexCount - 2; i++) for (unsigned i = 0; i < indexCount - 2; i++)
{ {
IndexType index0 = vm::ps3::_ref<IndexType>(address); IndexType index0 = vm::ps3::_ref<IndexType>(address);
(IndexType&)dst[(3 * i) * sizeof(IndexType)] = index0; if (index0 == (IndexType)primitive_restart_index)
index0 = (IndexType)-1;
IndexType index1 = vm::ps3::_ref<IndexType>(address + (i + 2 - 1) * sizeof(IndexType)); IndexType index1 = vm::ps3::_ref<IndexType>(address + (i + 2 - 1) * sizeof(IndexType));
(IndexType&)dst[(3 * i + 1) * sizeof(IndexType)] = index1; if (index1 == (IndexType)primitive_restart_index)
index1 = (IndexType)-1;
IndexType index2 = vm::ps3::_ref<IndexType>(address + (i + 2) * sizeof(IndexType)); IndexType index2 = vm::ps3::_ref<IndexType>(address + (i + 2) * sizeof(IndexType));
if (index2 == (IndexType)primitive_restart_index)
index2 = (IndexType)-1;
(IndexType&)dst[(3 * i) * sizeof(IndexType)] = index0;
(IndexType&)dst[(3 * i + 1) * sizeof(IndexType)] = index1;
(IndexType&)dst[(3 * i + 2) * sizeof(IndexType)] = index2; (IndexType&)dst[(3 * i + 2) * sizeof(IndexType)] = index2;
if (!is_primitive_restart_enabled || index0 != (IndexType)-1) // Cut if (!is_primitive_restart_enabled || index0 != (IndexType)-1) // Cut
@ -106,20 +117,29 @@ void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is
} }
template<typename IndexType> template<typename IndexType>
void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) noexcept void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index) noexcept
{ {
for (unsigned i = 0; i < indexCount / 4; i++) for (unsigned i = 0; i < indexCount / 4; i++)
{ {
// First triangle
IndexType index0 = vm::ps3::_ref<IndexType>(address + 4 * i * sizeof(IndexType)); IndexType index0 = vm::ps3::_ref<IndexType>(address + 4 * i * sizeof(IndexType));
(IndexType&)dst[(6 * i) * sizeof(IndexType)] = index0; if (is_primitive_restart_enabled && index0 == (IndexType)primitive_restart_index)
index0 = (IndexType)-1;
IndexType index1 = vm::ps3::_ref<IndexType>(address + (4 * i + 1) * sizeof(IndexType)); IndexType index1 = vm::ps3::_ref<IndexType>(address + (4 * i + 1) * sizeof(IndexType));
(IndexType&)dst[(6 * i + 1) * sizeof(IndexType)] = index1; if (is_primitive_restart_enabled && index1 == (IndexType)primitive_restart_index)
index1 = (IndexType)-1;
IndexType index2 = vm::ps3::_ref<IndexType>(address + (4 * i + 2) * sizeof(IndexType)); IndexType index2 = vm::ps3::_ref<IndexType>(address + (4 * i + 2) * sizeof(IndexType));
if (is_primitive_restart_enabled && index2 == (IndexType)primitive_restart_index)
index2 = (IndexType)-1;
IndexType index3 = vm::ps3::_ref<IndexType>(address + (4 * i + 3) * sizeof(IndexType));
if (is_primitive_restart_enabled &&index3 == (IndexType)primitive_restart_index)
index3 = (IndexType)-1;
// First triangle
(IndexType&)dst[(6 * i) * sizeof(IndexType)] = index0;
(IndexType&)dst[(6 * i + 1) * sizeof(IndexType)] = index1;
(IndexType&)dst[(6 * i + 2) * sizeof(IndexType)] = index2; (IndexType&)dst[(6 * i + 2) * sizeof(IndexType)] = index2;
// Second triangle // Second triangle
(IndexType&)dst[(6 * i + 3) * sizeof(IndexType)] = index2; (IndexType&)dst[(6 * i + 3) * sizeof(IndexType)] = index2;
IndexType index3 = vm::ps3::_ref<IndexType>(address + (4 * i + 3) * sizeof(IndexType));
(IndexType&)dst[(6 * i + 4) * sizeof(IndexType)] = index3; (IndexType&)dst[(6 * i + 4) * sizeof(IndexType)] = index3;
(IndexType&)dst[(6 * i + 5) * sizeof(IndexType)] = index0; (IndexType&)dst[(6 * i + 5) * sizeof(IndexType)] = index0;
@ -234,6 +254,7 @@ void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned
u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET];
u32 base_index = 0;//rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; u32 base_index = 0;//rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX];
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]; bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
u32 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX];
switch (m_draw_mode) switch (m_draw_mode)
{ {
@ -248,10 +269,10 @@ void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned
switch (type) switch (type)
{ {
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32:
uploadAsIt<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, min_index, max_index); uploadAsIt<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return; return;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16:
uploadAsIt<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, min_index, max_index); uploadAsIt<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return; return;
} }
return; return;
@ -259,20 +280,20 @@ void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned
switch (type) switch (type)
{ {
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32:
expandIndexedTriangleFan<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, min_index, max_index); expandIndexedTriangleFan<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return; return;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16:
expandIndexedTriangleFan<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, min_index, max_index); expandIndexedTriangleFan<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return; return;
} }
case CELL_GCM_PRIMITIVE_QUADS: case CELL_GCM_PRIMITIVE_QUADS:
switch (type) switch (type)
{ {
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32:
expandIndexedQuads<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, min_index, max_index); expandIndexedQuads<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return; return;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16:
expandIndexedQuads<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, min_index, max_index); expandIndexedQuads<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return; return;
} }
} }

View file

@ -364,8 +364,8 @@ BOOL get_front_face_ccw(u32 set_front_face_value) noexcept
{ {
switch (set_front_face_value) switch (set_front_face_value)
{ {
case CELL_GCM_CW: return FALSE;
default: // Disgaea 3 pass some garbage value at startup, this is needed to survive. default: // Disgaea 3 pass some garbage value at startup, this is needed to survive.
case CELL_GCM_CW: return FALSE;
case CELL_GCM_CCW: return TRUE; case CELL_GCM_CCW: return TRUE;
} }
unreachable("Wrong front face value"); unreachable("Wrong front face value");
@ -465,4 +465,14 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
} }
unreachable("Wrong type"); unreachable("Wrong type");
} }
D3D12_RECT get_scissor(u32 horizontal, u32 vertical) noexcept
{
return{
horizontal & 0xFFFF,
vertical & 0xFFFF,
(horizontal & 0xFFFF) + (horizontal >> 16),
(vertical & 0xFFFF) + (vertical >> 16)
};
}
#endif #endif

View file

@ -97,3 +97,8 @@ DXGI_FORMAT get_index_type(u8 index_type) noexcept;
* Convert vertex attribute format and size to DXGI_FORMAT * Convert vertex attribute format and size to DXGI_FORMAT
*/ */
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept; DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept;
/**
* Convert scissor register value to D3D12_RECT
*/
D3D12_RECT get_scissor(u32 horizontal, u32 vertical) noexcept;

View file

@ -346,19 +346,12 @@ void D3D12GSRender::end()
0.f, 0.f,
(float)clip_w, (float)clip_w,
(float)clip_h, (float)clip_h,
-1.f, (f32&)rsx::method_registers[NV4097_SET_CLIP_MIN],
1.f (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]
}; };
getCurrentResourceStorage().command_list->RSSetViewports(1, &viewport); getCurrentResourceStorage().command_list->RSSetViewports(1, &viewport);
D3D12_RECT box = getCurrentResourceStorage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]));
{
0,
0,
(LONG)clip_w,
(LONG)clip_h,
};
getCurrentResourceStorage().command_list->RSSetScissorRects(1, &box);
getCurrentResourceStorage().command_list->IASetPrimitiveTopology(get_primitive_topology(draw_mode)); getCurrentResourceStorage().command_list->IASetPrimitiveTopology(get_primitive_topology(draw_mode));

View file

@ -74,6 +74,8 @@ void resource_storage::reset()
descriptors_heap_index = 0; descriptors_heap_index = 0;
current_sampler_index = 0; current_sampler_index = 0;
sampler_descriptors_heap_index = 0; sampler_descriptors_heap_index = 0;
render_targets_descriptors_heap_index = 0;
depth_stencil_descriptor_heap_index = 0;
ThrowIfFailed(command_allocator->Reset()); ThrowIfFailed(command_allocator->Reset());
set_new_command_list(); set_new_command_list();
@ -102,6 +104,12 @@ void resource_storage::init(ID3D12Device *device)
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[0])));
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[1]))); ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[1])));
D3D12_DESCRIPTOR_HEAP_DESC ds_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_DSV , 10000};
device->CreateDescriptorHeap(&ds_descriptor_heap_desc, IID_PPV_ARGS(&depth_stencil_descriptor_heap));
D3D12_DESCRIPTOR_HEAP_DESC rtv_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV , 10000 };
device->CreateDescriptorHeap(&rtv_descriptor_heap_desc, IID_PPV_ARGS(&render_targets_descriptors_heap));
frame_finished_handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); frame_finished_handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence_value = 0; fence_value = 0;
ThrowIfFailed(device->CreateFence(fence_value++, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(frame_finished_fence.GetAddressOf()))); ThrowIfFailed(device->CreateFence(fence_value++, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(frame_finished_fence.GetAddressOf())));

View file

@ -214,6 +214,11 @@ struct resource_storage
size_t sampler_descriptors_heap_index; size_t sampler_descriptors_heap_index;
size_t current_sampler_index; size_t current_sampler_index;
size_t render_targets_descriptors_heap_index;
ComPtr<ID3D12DescriptorHeap> render_targets_descriptors_heap;
size_t depth_stencil_descriptor_heap_index;
ComPtr<ID3D12DescriptorHeap> depth_stencil_descriptor_heap;
ComPtr<ID3D12Resource> ram_framebuffer; ComPtr<ID3D12Resource> ram_framebuffer;
/// Texture that were invalidated /// Texture that were invalidated

View file

@ -76,25 +76,34 @@ void D3D12GSRender::clear_surface(u32 arg)
m_timers.m_rttDuration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count(); m_timers.m_rttDuration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
if (arg & 0x1 || arg & 0x2) if (arg & 0x1 || arg & 0x2)
m_rtts.bind_depth_stencil(m_device.Get(), m_surface.depth_format, m_rtts.depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart());
if (arg & 0x1)
{ {
u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart())
u32 max_depth_value = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff; .Offset(getCurrentResourceStorage().depth_stencil_descriptor_heap_index * g_descriptorStrideRTV);
getCurrentResourceStorage().command_list->ClearDepthStencilView(m_rtts.depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, 0, nullptr); m_rtts.bind_depth_stencil(m_device.Get(), m_surface.depth_format, handle);
} getCurrentResourceStorage().depth_stencil_descriptor_heap_index++;
if (arg & 0x2) if (arg & 0x1)
getCurrentResourceStorage().command_list->ClearDepthStencilView(m_rtts.depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f, {
get_clear_stencil(rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE]), 0, nullptr); 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().command_list->ClearDepthStencilView(handle, D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0,
1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]));
}
if (arg & 0x2)
getCurrentResourceStorage().command_list->ClearDepthStencilView(handle, D3D12_CLEAR_FLAG_STENCIL, 0.f, get_clear_stencil(rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE]),
1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]));
}
if (arg & 0xF0) if (arg & 0xF0)
{ {
size_t rtt_index = m_rtts.bind_render_targets(m_device.Get(), m_surface.color_format, m_rtts.render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart()); CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart())
.Offset(getCurrentResourceStorage().render_targets_descriptors_heap_index * g_descriptorStrideRTV);
size_t rtt_index = m_rtts.bind_render_targets(m_device.Get(), m_surface.color_format, handle);
getCurrentResourceStorage().render_targets_descriptors_heap_index += rtt_index;
for (unsigned i = 0; i < rtt_index; i++) for (unsigned i = 0; i < rtt_index; i++)
getCurrentResourceStorage().command_list->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart()).Offset(i, g_descriptorStrideRTV), getCurrentResourceStorage().command_list->ClearRenderTargetView(handle.Offset(i, g_descriptorStrideRTV), get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(),
get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(), 0, nullptr); 1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]));
} }
std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now();
@ -220,7 +229,7 @@ size_t render_targets::bind_render_targets(ID3D12Device *device, u32 color_forma
if (bound_render_targets[i] == nullptr) if (bound_render_targets[i] == nullptr)
continue; continue;
device->CreateRenderTargetView(bound_render_targets[i], &rtt_view_desc, device->CreateRenderTargetView(bound_render_targets[i], &rtt_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart()).Offset((INT)rtt_index * g_descriptor_stride_rtv)); CD3DX12_CPU_DESCRIPTOR_HANDLE(handle).Offset((INT)rtt_index * g_descriptor_stride_rtv));
rtt_index++; rtt_index++;
} }
return rtt_index; return rtt_index;
@ -233,16 +242,22 @@ size_t render_targets::bind_depth_stencil(ID3D12Device *device, u32 depth_format
D3D12_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc = {}; D3D12_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc = {};
depth_stencil_view_desc.Format = get_depth_stencil_surface_format(depth_format); depth_stencil_view_desc.Format = get_depth_stencil_surface_format(depth_format);
depth_stencil_view_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; depth_stencil_view_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
device->CreateDepthStencilView(bound_depth_stencil, &depth_stencil_view_desc, depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart()); device->CreateDepthStencilView(bound_depth_stencil, &depth_stencil_view_desc, handle);
return 1; return 1;
} }
void D3D12GSRender::set_rtt_and_ds(ID3D12GraphicsCommandList *command_list) void D3D12GSRender::set_rtt_and_ds(ID3D12GraphicsCommandList *command_list)
{ {
size_t num_rtt = m_rtts.bind_render_targets(m_device.Get(), m_surface.color_format, m_rtts.render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart()); CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart())
size_t num_ds = m_rtts.bind_depth_stencil(m_device.Get(), m_surface.depth_format, m_rtts.depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart()); .Offset(getCurrentResourceStorage().render_targets_descriptors_heap_index * g_descriptorStrideRTV);
command_list->OMSetRenderTargets((UINT)num_rtt, num_rtt > 0 ? &m_rtts.render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart() : nullptr, !!num_rtt, size_t num_rtt = m_rtts.bind_render_targets(m_device.Get(), m_surface.color_format, handle);
num_ds > 0 ? &CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart()) : nullptr); getCurrentResourceStorage().render_targets_descriptors_heap_index += num_rtt;
CD3DX12_CPU_DESCRIPTOR_HANDLE depth_stencil_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart())
.Offset(getCurrentResourceStorage().depth_stencil_descriptor_heap_index * g_descriptorStrideRTV);
size_t num_ds = m_rtts.bind_depth_stencil(m_device.Get(), m_surface.depth_format, depth_stencil_handle);
getCurrentResourceStorage().depth_stencil_descriptor_heap_index += num_ds;
command_list->OMSetRenderTargets((UINT)num_rtt, num_rtt > 0 ? &handle : nullptr, !!num_rtt,
num_ds > 0 ? &depth_stencil_handle : nullptr);
} }
ID3D12Resource *render_targets::bind_address_as_render_targets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address, ID3D12Resource *render_targets::bind_address_as_render_targets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address,
@ -322,15 +337,6 @@ ID3D12Resource * render_targets::bind_address_as_depth_stencil(ID3D12Device * de
void render_targets::init(ID3D12Device *device)//, u8 surfaceDepthFormat, size_t width, size_t height, float clearColor[4], float clearDepth) void render_targets::init(ID3D12Device *device)//, u8 surfaceDepthFormat, size_t width, size_t height, float clearColor[4], float clearDepth)
{ {
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = {};
descriptor_heap_desc.NumDescriptors = 1;
descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(depth_stencil_descriptor_heap.GetAddressOf()));
descriptor_heap_desc.NumDescriptors = 4;
descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(render_targets_descriptors_heap.GetAddressOf()));
memset(bound_render_targets_address, 0, 4 * sizeof(u32)); memset(bound_render_targets_address, 0, 4 * sizeof(u32));
memset(bound_render_targets, 0, 4 * sizeof(ID3D12Resource*)); memset(bound_render_targets, 0, 4 * sizeof(ID3D12Resource*));
bound_depth_stencil = nullptr; bound_depth_stencil = nullptr;
@ -338,6 +344,7 @@ void render_targets::init(ID3D12Device *device)//, u8 surfaceDepthFormat, size_t
g_descriptor_stride_rtv = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); g_descriptor_stride_rtv = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
} }
namespace namespace
{ {
/** /**

View file

@ -11,8 +11,6 @@ struct render_targets
std::unordered_map<u32, ComPtr<ID3D12Resource> > depth_stencil_storage; std::unordered_map<u32, ComPtr<ID3D12Resource> > depth_stencil_storage;
ID3D12Resource *bound_depth_stencil; ID3D12Resource *bound_depth_stencil;
u32 bound_depth_stencil_address; u32 bound_depth_stencil_address;
ComPtr<ID3D12DescriptorHeap> render_targets_descriptors_heap;
ComPtr<ID3D12DescriptorHeap> depth_stencil_descriptor_heap;
size_t bind_render_targets(ID3D12Device *, u32 color_format, D3D12_CPU_DESCRIPTOR_HANDLE); size_t bind_render_targets(ID3D12Device *, u32 color_format, D3D12_CPU_DESCRIPTOR_HANDLE);
size_t bind_depth_stencil(ID3D12Device *, u32 depth_format, D3D12_CPU_DESCRIPTOR_HANDLE); size_t bind_depth_stencil(ID3D12Device *, u32 depth_format, D3D12_CPU_DESCRIPTOR_HANDLE);