mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 03:08:36 +12:00
commit
d511fd6529
7 changed files with 126 additions and 118 deletions
|
@ -106,14 +106,15 @@ D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept
|
|||
case CELL_GCM_KEEP: return D3D12_STENCIL_OP_KEEP;
|
||||
case CELL_GCM_ZERO: return D3D12_STENCIL_OP_ZERO;
|
||||
case CELL_GCM_REPLACE: return D3D12_STENCIL_OP_REPLACE;
|
||||
default: // Jet Set Radio set some garbage, turns out OP_INCR is the intended behavior.
|
||||
case CELL_GCM_INCR: return D3D12_STENCIL_OP_INCR;
|
||||
case CELL_GCM_DECR: return D3D12_STENCIL_OP_DECR;
|
||||
case CELL_GCM_INCR_WRAP:
|
||||
case CELL_GCM_DECR_WRAP:
|
||||
unreachable("Unsupported Stencil Op %d");
|
||||
}
|
||||
unreachable("Wrong Stencil Op %d");
|
||||
// Jet Set Radio uses an unknow op but INCR seems to be the intended one
|
||||
LOG_WARNING(RSX, "Unknow stencil op %x, fallback to INCR", op);
|
||||
return D3D12_STENCIL_OP_INCR;
|
||||
}
|
||||
|
||||
D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept
|
||||
|
@ -237,7 +238,7 @@ namespace
|
|||
case CELL_GCM_TEXTURE_NEAREST:
|
||||
min = D3D12_FILTER_TYPE_POINT;
|
||||
mip = D3D12_FILTER_TYPE_POINT;
|
||||
return;;
|
||||
return;
|
||||
case CELL_GCM_TEXTURE_LINEAR:
|
||||
min = D3D12_FILTER_TYPE_LINEAR;
|
||||
mip = D3D12_FILTER_TYPE_POINT;
|
||||
|
@ -259,7 +260,10 @@ namespace
|
|||
mip = D3D12_FILTER_TYPE_LINEAR;
|
||||
return;
|
||||
case CELL_GCM_TEXTURE_CONVOLUTION_MIN:
|
||||
unreachable("Unsupported min filter");
|
||||
LOG_WARNING(RSX, "CELL_GCM_TEXTURE_CONVOLUTION_MIN not supported, fallback to bilinear filtering");
|
||||
min = D3D12_FILTER_TYPE_LINEAR;
|
||||
mip = D3D12_FILTER_TYPE_POINT;
|
||||
return;
|
||||
}
|
||||
unreachable("Wrong min filter");
|
||||
}
|
||||
|
@ -271,7 +275,9 @@ namespace
|
|||
case CELL_GCM_TEXTURE_NEAREST: return D3D12_FILTER_TYPE_POINT;
|
||||
case CELL_GCM_TEXTURE_LINEAR: return D3D12_FILTER_TYPE_LINEAR;
|
||||
}
|
||||
unreachable("Wrong mag filter");
|
||||
// Catherine uses this
|
||||
LOG_WARNING(RSX, "Unknow mag filter used %x, fallback to bilinear filtering", mag_filter);
|
||||
return D3D12_FILTER_TYPE_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,6 +333,7 @@ DXGI_FORMAT get_color_surface_format(u8 format) noexcept
|
|||
{
|
||||
case CELL_GCM_SURFACE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT;
|
||||
}
|
||||
unreachable("Wrong color surface format");
|
||||
}
|
||||
|
@ -351,7 +358,7 @@ DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept
|
|||
unreachable("Wrong depth stencil surface format");
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_depth_typeless_surface_format(u8 format) noexcept
|
||||
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) noexcept
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
|
@ -361,6 +368,16 @@ DXGI_FORMAT get_depth_typeless_surface_format(u8 format) noexcept
|
|||
unreachable("Wrong depth stencil surface format");
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_depth_samplable_surface_format(u8 format) noexcept
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_FLOAT;
|
||||
case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
|
||||
}
|
||||
unreachable("Wrong depth stencil surface format");
|
||||
}
|
||||
|
||||
BOOL get_front_face_ccw(u32 set_front_face_value) noexcept
|
||||
{
|
||||
switch (set_front_face_value)
|
||||
|
|
|
@ -79,9 +79,14 @@ DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept;
|
|||
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept;
|
||||
|
||||
/**
|
||||
* Convert depth surface format to DXGI_FORMAT using typeless for stencil
|
||||
* Convert depth surface format to a typeless DXGI_FORMAT
|
||||
*/
|
||||
DXGI_FORMAT get_depth_typeless_surface_format(u8 format) noexcept;
|
||||
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) noexcept;
|
||||
|
||||
/**
|
||||
* Convert depth surface format to a DXGI_FORMAT that can be depth sampled
|
||||
*/
|
||||
DXGI_FORMAT get_depth_samplable_surface_format(u8 format) noexcept;
|
||||
|
||||
/**
|
||||
* Convert front face value to bool value telling wheter front face is counterclockwise or not
|
||||
|
|
|
@ -197,14 +197,14 @@ D3D12GSRender::D3D12GSRender()
|
|||
IID_PPV_ARGS(&m_dummy_texture))
|
||||
);
|
||||
|
||||
m_readback_resources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
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_HEAP_FLAG_NONE);
|
||||
m_vertex_index_data.init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE);
|
||||
m_texture_upload_data.init(m_device.Get(), 1024 * 1024 * 512, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE);
|
||||
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);
|
||||
|
||||
if (rpcs3::config.rsx.d3d12.overlay.value())
|
||||
init_d2d_structures();
|
||||
|
|
|
@ -121,7 +121,7 @@ private:
|
|||
// 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<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> m_readback_resources;
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> m_readback_resources;
|
||||
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -27,15 +27,15 @@ struct init_heap<ID3D12Heap>
|
|||
template<>
|
||||
struct init_heap<ID3D12Resource>
|
||||
{
|
||||
static ID3D12Resource* init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
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;
|
||||
ThrowIfFailed(device->CreateCommittedResource(&heap_properties,
|
||||
flags,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&CD3DX12_RESOURCE_DESC::Buffer(heap_size),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
state,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&result))
|
||||
);
|
||||
|
@ -60,10 +60,11 @@ struct data_heap
|
|||
size_t m_put_pos; // Start of free space
|
||||
size_t m_get_pos; // End of free space
|
||||
|
||||
void init(ID3D12Device *device, size_t heap_size, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
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, flags);
|
||||
m_heap = init_heap<T>::init(device, heap_size, type, args...);
|
||||
m_put_pos = 0;
|
||||
m_get_pos = heap_size - 1;
|
||||
}
|
||||
|
|
|
@ -196,8 +196,11 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis
|
|||
std::array<float, 4> clear_color = get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]);
|
||||
for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
ComPtr<ID3D12Resource> old_render_target_resource;
|
||||
m_rtts.bound_render_targets[i] = m_rtts.bind_address_as_render_targets(m_device.Get(), copycmdlist, address_color[i], clip_width, clip_height, m_surface.color_format,
|
||||
clear_color);
|
||||
clear_color, old_render_target_resource);
|
||||
if (old_render_target_resource)
|
||||
get_current_resource_storage().dirty_textures.push_back(old_render_target_resource);
|
||||
m_rtts.bound_render_targets_address[i] = address_color[i];
|
||||
}
|
||||
|
||||
|
@ -261,20 +264,26 @@ void D3D12GSRender::set_rtt_and_ds(ID3D12GraphicsCommandList *command_list)
|
|||
}
|
||||
|
||||
ID3D12Resource *render_targets::bind_address_as_render_targets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address,
|
||||
size_t width, size_t height, u8 surfaceColorFormat, const std::array<float, 4> &clear_color)
|
||||
size_t width, size_t height, u8 surfaceColorFormat, const std::array<float, 4> &clear_color, ComPtr<ID3D12Resource> &dirtyRTT)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = get_color_surface_format(surfaceColorFormat);
|
||||
auto It = render_targets_storage.find(address);
|
||||
// TODO: Check if format and size match
|
||||
if (It != render_targets_storage.end())
|
||||
{
|
||||
ID3D12Resource* rtt;
|
||||
ComPtr<ID3D12Resource> rtt;
|
||||
rtt = It->second.Get();
|
||||
cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rtt, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
|
||||
return rtt;
|
||||
if (rtt->GetDesc().Format == dxgi_format)
|
||||
{
|
||||
cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rtt.Get(), D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
|
||||
return rtt.Get();
|
||||
}
|
||||
render_targets_storage.erase(address);
|
||||
dirtyRTT = rtt;
|
||||
}
|
||||
ComPtr<ID3D12Resource> rtt;
|
||||
LOG_WARNING(RSX, "Creating RTT");
|
||||
DXGI_FORMAT dxgi_format = get_color_surface_format(surfaceColorFormat);
|
||||
|
||||
D3D12_CLEAR_VALUE clear_color_value = {};
|
||||
clear_color_value.Format = dxgi_format;
|
||||
clear_color_value.Color[0] = clear_color[0];
|
||||
|
@ -318,7 +327,7 @@ ID3D12Resource * render_targets::bind_address_as_depth_stencil(ID3D12Device * de
|
|||
D3D12_CLEAR_VALUE clear_depth_value = {};
|
||||
clear_depth_value.DepthStencil.Depth = depthClear;
|
||||
|
||||
DXGI_FORMAT dxgi_format = get_depth_typeless_surface_format(surfaceDepthFormat);
|
||||
DXGI_FORMAT dxgi_format = get_depth_stencil_typeless_surface_format(surfaceDepthFormat);
|
||||
clear_depth_value.Format = get_depth_stencil_surface_clear_format(surfaceDepthFormat);
|
||||
|
||||
ComPtr<ID3D12Resource> new_depth_stencil;
|
||||
|
@ -348,13 +357,12 @@ void render_targets::init(ID3D12Device *device)//, u8 surfaceDepthFormat, size_t
|
|||
namespace
|
||||
{
|
||||
/**
|
||||
* Create a write back buffer resource and populate command_list with copy command to fill it
|
||||
* with color_surface data.
|
||||
*/
|
||||
ComPtr<ID3D12Resource> create_readback_buffer_and_download(
|
||||
* Populate command_list with copy command with color_surface data and return offset in readback buffer
|
||||
*/
|
||||
size_t download_to_readback_buffer(
|
||||
ID3D12Device *device,
|
||||
ID3D12GraphicsCommandList * command_list,
|
||||
data_heap<ID3D12Heap, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT> &readback_heap,
|
||||
data_heap<ID3D12Resource, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT> &readback_heap,
|
||||
ID3D12Resource * color_surface,
|
||||
int color_surface_format
|
||||
)
|
||||
|
@ -376,31 +384,22 @@ namespace
|
|||
|
||||
size_t buffer_size = row_pitch * clip_h;
|
||||
assert(readback_heap.can_alloc(buffer_size));
|
||||
size_t heapOffset = readback_heap.alloc(buffer_size);
|
||||
ComPtr<ID3D12Resource> Result;
|
||||
ThrowIfFailed(
|
||||
device->CreatePlacedResource(
|
||||
readback_heap.m_heap,
|
||||
heapOffset,
|
||||
&CD3DX12_RESOURCE_DESC::Buffer(row_pitch * clip_h),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(Result.GetAddressOf())
|
||||
)
|
||||
);
|
||||
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(Result.Get(), { 0,{ dxgi_format, (UINT)clip_w, (UINT)clip_h, 1, (UINT)row_pitch } }), 0, 0, 0,
|
||||
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,
|
||||
&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 Result;
|
||||
return heap_offset;
|
||||
}
|
||||
|
||||
void copy_readback_buffer_to_dest(void *dest, ID3D12Resource *res, size_t dst_pitch, size_t src_pitch, size_t height)
|
||||
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 *mapped_buffer;
|
||||
ThrowIfFailed(res->Map(0, nullptr, &mapped_buffer));
|
||||
void *buffer;
|
||||
// TODO: Use exact range
|
||||
ThrowIfFailed(readback_heap.m_heap->Map(0, nullptr, &buffer));
|
||||
void *mapped_buffer = (char*)buffer + offset_in_heap;
|
||||
for (unsigned row = 0; row < height; row++)
|
||||
{
|
||||
u32 *casted_dest = (u32*)((char*)dest + row * dst_pitch);
|
||||
|
@ -408,7 +407,7 @@ namespace
|
|||
for (unsigned col = 0; col < src_pitch / 4; col++)
|
||||
*casted_dest++ = _byteswap_ulong(*casted_src++);
|
||||
}
|
||||
res->Unmap(0, nullptr);
|
||||
readback_heap.m_heap->Unmap(0, nullptr);
|
||||
}
|
||||
|
||||
void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_queue)
|
||||
|
@ -431,9 +430,10 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
|||
int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
|
||||
int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16;
|
||||
|
||||
ComPtr<ID3D12Resource> depth_buffer_write_dest, depth_format_conversion_buffer;
|
||||
ComPtr<ID3D12Resource> depth_format_conversion_buffer;
|
||||
ComPtr<ID3D12DescriptorHeap> descriptor_heap;
|
||||
size_t depth_row_pitch = align(clip_w, 256);
|
||||
size_t depth_buffer_offset_in_heap = 0;
|
||||
|
||||
u32 context_dma_color[] =
|
||||
{
|
||||
|
@ -444,6 +444,24 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
|||
};
|
||||
u32 m_context_dma_z = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA];
|
||||
|
||||
u32 offset_color[] =
|
||||
{
|
||||
rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET],
|
||||
rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET],
|
||||
rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET],
|
||||
rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET]
|
||||
};
|
||||
u32 offset_zeta = rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET];
|
||||
|
||||
u32 address_color[] =
|
||||
{
|
||||
rsx::get_address(offset_color[0], context_dma_color[0]),
|
||||
rsx::get_address(offset_color[1], context_dma_color[1]),
|
||||
rsx::get_address(offset_color[2], context_dma_color[2]),
|
||||
rsx::get_address(offset_color[3], context_dma_color[3]),
|
||||
};
|
||||
u32 address_z = rsx::get_address(offset_zeta, m_context_dma_z);
|
||||
|
||||
bool need_transfer = false;
|
||||
|
||||
if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer)
|
||||
|
@ -463,27 +481,12 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
|||
)
|
||||
);
|
||||
|
||||
size_t buffer_size = depth_row_pitch * clip_h;
|
||||
assert(m_readback_resources.can_alloc(buffer_size));
|
||||
heap_offset = m_readback_resources.alloc(buffer_size);
|
||||
|
||||
ThrowIfFailed(
|
||||
m_device->CreatePlacedResource(
|
||||
m_readback_resources.m_heap,
|
||||
heap_offset,
|
||||
&CD3DX12_RESOURCE_DESC::Buffer(buffer_size),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(depth_buffer_write_dest.GetAddressOf())
|
||||
)
|
||||
);
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
|
||||
ThrowIfFailed(
|
||||
m_device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(descriptor_heap.GetAddressOf()))
|
||||
);
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {};
|
||||
m_surface.depth_format = get_depth_typeless_surface_format(m_surface.depth_format);
|
||||
shader_resource_view_desc.Format = get_depth_samplable_surface_format(m_surface.depth_format);
|
||||
shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
shader_resource_view_desc.Texture2D.MipLevels = 1;
|
||||
shader_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
|
@ -511,23 +514,23 @@ 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(depth_buffer_write_dest.Get(), { 0,{ DXGI_FORMAT_R8_UNORM, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0,
|
||||
&CD3DX12_TEXTURE_COPY_LOCATION(depth_buffer_write_dest.Get(), 0), nullptr);
|
||||
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,
|
||||
&CD3DX12_TEXTURE_COPY_LOCATION(depth_format_conversion_buffer.Get(), 0), nullptr);
|
||||
|
||||
invalidate_address(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], m_context_dma_z - 0xfeed0000));
|
||||
invalidate_address(address_z);
|
||||
|
||||
need_transfer = true;
|
||||
}
|
||||
|
||||
ComPtr<ID3D12Resource> readback_buffers[4];
|
||||
size_t color_buffer_offset_in_heap[4];
|
||||
if (rpcs3::state.config.rsx.opengl.write_color_buffers)
|
||||
{
|
||||
for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
if (!context_dma_color[i])
|
||||
if (!address_color[i])
|
||||
continue;
|
||||
readback_buffers[i] = create_readback_buffer_and_download(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, m_rtts.bound_render_targets[0], m_surface.color_format);
|
||||
invalidate_address(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[i] - 0xfeed0000));
|
||||
color_buffer_offset_in_heap[i] = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, m_rtts.bound_render_targets[i], m_surface.color_format);
|
||||
invalidate_address(address_color[i]);
|
||||
need_transfer = true;
|
||||
}
|
||||
}
|
||||
|
@ -541,13 +544,14 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
|||
//Wait for result
|
||||
wait_for_command_queue(m_device.Get(), m_command_queue.Get());
|
||||
|
||||
if (m_context_dma_z && rpcs3::state.config.rsx.opengl.write_depth_buffer)
|
||||
if (address_z && rpcs3::state.config.rsx.opengl.write_depth_buffer)
|
||||
{
|
||||
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], m_context_dma_z - 0xfeed0000);
|
||||
auto ptr = vm::base(address);
|
||||
auto ptr = vm::base(address_z);
|
||||
char *depth_buffer = (char*)ptr;
|
||||
unsigned char *mapped_buffer;
|
||||
ThrowIfFailed(depth_buffer_write_dest->Map(0, nullptr, (void**)&mapped_buffer));
|
||||
void *buffer;
|
||||
// TODO: Use exact range
|
||||
ThrowIfFailed(m_readback_resources.m_heap->Map(0, nullptr, &buffer));
|
||||
unsigned char *mapped_buffer = (unsigned char*)buffer + depth_buffer_offset_in_heap;
|
||||
|
||||
for (unsigned row = 0; row < (unsigned)clip_h; row++)
|
||||
{
|
||||
|
@ -560,6 +564,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);
|
||||
}
|
||||
|
||||
size_t srcPitch, dstPitch;
|
||||
|
@ -579,17 +584,17 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
|||
{
|
||||
void *dest_buffer[] =
|
||||
{
|
||||
vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[0] - 0xfeed0000)),
|
||||
vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[1] - 0xfeed0000)),
|
||||
vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[2] - 0xfeed0000)),
|
||||
vm::base(rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], context_dma_color[3] - 0xfeed0000))
|
||||
vm::base(address_color[0]),
|
||||
vm::base(address_color[1]),
|
||||
vm::base(address_color[2]),
|
||||
vm::base(address_color[3]),
|
||||
};
|
||||
|
||||
for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
if (!context_dma_color[i])
|
||||
if (!address_color[i])
|
||||
continue;
|
||||
copy_readback_buffer_to_dest(dest_buffer[i], readback_buffers[i].Get(), srcPitch, dstPitch, clip_h);
|
||||
copy_readback_buffer_to_dest(dest_buffer[i], m_readback_resources, color_buffer_offset_in_heap[i], srcPitch, dstPitch, clip_h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -597,7 +602,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
|||
|
||||
void D3D12GSRender::copy_render_targets_to_memory(void *buffer, u8 rtt)
|
||||
{
|
||||
ComPtr<ID3D12Resource> readback_buffer = create_readback_buffer_and_download(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, m_rtts.bound_render_targets[rtt], m_surface.color_format);
|
||||
size_t heap_offset = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, m_rtts.bound_render_targets[rtt], m_surface.color_format);
|
||||
|
||||
ThrowIfFailed(get_current_resource_storage().command_list->Close());
|
||||
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
|
||||
|
@ -620,7 +625,7 @@ void D3D12GSRender::copy_render_targets_to_memory(void *buffer, u8 rtt)
|
|||
dstPitch = clip_w * 8;
|
||||
break;
|
||||
}
|
||||
copy_readback_buffer_to_dest(buffer, readback_buffer.Get(), srcPitch, dstPitch, clip_h);
|
||||
copy_readback_buffer_to_dest(buffer, m_readback_resources, heap_offset, srcPitch, dstPitch, clip_h);
|
||||
}
|
||||
|
||||
void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer)
|
||||
|
@ -630,24 +635,13 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer)
|
|||
|
||||
size_t row_pitch = align(clip_w * 4, 256);
|
||||
|
||||
ComPtr<ID3D12Resource> readback_buffer;
|
||||
size_t buffer_size = row_pitch * clip_h;
|
||||
assert(m_readback_resources.can_alloc(buffer_size));
|
||||
size_t heapOffset = m_readback_resources.alloc(buffer_size);
|
||||
ThrowIfFailed(
|
||||
m_device->CreatePlacedResource(
|
||||
m_readback_resources.m_heap,
|
||||
heapOffset,
|
||||
&CD3DX12_RESOURCE_DESC::Buffer(buffer_size),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(readback_buffer.GetAddressOf())
|
||||
)
|
||||
);
|
||||
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(readback_buffer.Get(), { 0,{ 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.m_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));
|
||||
|
||||
|
@ -658,8 +652,9 @@ 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 *mapped_buffer;
|
||||
ThrowIfFailed(readback_buffer->Map(0, nullptr, &mapped_buffer));
|
||||
void *temp_buffer;
|
||||
ThrowIfFailed(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer));
|
||||
void *mapped_buffer = (char*)temp_buffer + heap_offset;
|
||||
for (unsigned row = 0; row < clip_h; row++)
|
||||
{
|
||||
u32 *casted_dest = (u32*)((char*)buffer + row * clip_w * 4);
|
||||
|
@ -667,7 +662,7 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer)
|
|||
for (unsigned col = 0; col < row_pitch / 4; col++)
|
||||
*casted_dest++ = *casted_src++;
|
||||
}
|
||||
readback_buffer->Unmap(0, nullptr);
|
||||
m_readback_resources.m_heap->Unmap(0, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -678,24 +673,13 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer)
|
|||
|
||||
size_t row_pitch = align(clip_w * 4, 256);
|
||||
|
||||
ComPtr<ID3D12Resource> readback_buffer;
|
||||
size_t buffer_size = row_pitch * clip_h;
|
||||
assert(m_readback_resources.can_alloc(buffer_size));
|
||||
size_t heapOffset = m_readback_resources.alloc(buffer_size);
|
||||
ThrowIfFailed(
|
||||
m_device->CreatePlacedResource(
|
||||
m_readback_resources.m_heap,
|
||||
heapOffset,
|
||||
&CD3DX12_RESOURCE_DESC::Buffer(buffer_size),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(readback_buffer.GetAddressOf())
|
||||
)
|
||||
);
|
||||
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(readback_buffer.Get(), { 0,{ 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.m_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));
|
||||
|
||||
|
@ -706,8 +690,9 @@ 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 *mapped_buffer;
|
||||
ThrowIfFailed(readback_buffer->Map(0, nullptr, &mapped_buffer));
|
||||
void *temp_buffer;
|
||||
ThrowIfFailed(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer));
|
||||
void *mapped_buffer = (char*)temp_buffer + heap_offset;
|
||||
for (unsigned row = 0; row < clip_h; row++)
|
||||
{
|
||||
char *casted_dest = (char*)buffer + row * clip_w;
|
||||
|
@ -715,7 +700,7 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer)
|
|||
for (unsigned col = 0; col < row_pitch; col++)
|
||||
*casted_dest++ = *casted_src++;
|
||||
}
|
||||
readback_buffer->Unmap(0, nullptr);
|
||||
m_readback_resources.m_heap->Unmap(0, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,7 @@ struct render_targets
|
|||
* returns the corresponding render target resource.
|
||||
*/
|
||||
ID3D12Resource *bind_address_as_render_targets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address,
|
||||
size_t width, size_t height, u8 surfaceColorFormat, const std::array<float, 4> &clearColor);
|
||||
size_t width, size_t height, u8 surfaceColorFormat, const std::array<float, 4> &clearColor, ComPtr<ID3D12Resource> &dirtyDS);
|
||||
|
||||
ID3D12Resource *bind_address_as_depth_stencil(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address,
|
||||
size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear, ComPtr<ID3D12Resource> &dirtyDS);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue