d3d12: Remove all shared code with other backends

This commit is contained in:
kd-11 2019-05-21 15:49:39 +03:00 committed by kd-11
parent 0d906d6974
commit db5d56a22d
2 changed files with 222 additions and 109 deletions

View file

@ -1,4 +1,4 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#include "stdafx.h" #include "stdafx.h"
#include "stdafx_d3d12.h" #include "stdafx_d3d12.h"
#include "D3D12PipelineState.h" #include "D3D12PipelineState.h"
@ -321,7 +321,5 @@ std::pair<std::string, std::string> D3D12GSRender::get_programs() const
void D3D12GSRender::notify_tile_unbound(u32 tile) void D3D12GSRender::notify_tile_unbound(u32 tile)
{ {
u32 addr = rsx::get_address(tiles[tile].offset, tiles[tile].location);
m_rtts.invalidate_surface_address(addr, false);
} }
#endif #endif

View file

@ -8,10 +8,226 @@
#include "D3D12Formats.h" #include "D3D12Formats.h"
#include "D3D12MemoryHelpers.h" #include "D3D12MemoryHelpers.h"
#include "../Common/surface_store.h"
namespace rsx namespace rsx
{ {
namespace utility
{
std::vector<u8> get_rtt_indexes(surface_target color_target);
size_t get_aligned_pitch(surface_color_format format, u32 width);
size_t get_packed_pitch(surface_color_format format, u32 width);
}
template<typename Traits>
struct surface_store_deprecated
{
template<typename T, typename U>
void copy_pitched_src_to_dst(gsl::span<T> dest, gsl::span<const U> src, size_t src_pitch_in_bytes, size_t width, size_t height)
{
for (unsigned row = 0; row < height; row++)
{
for (unsigned col = 0; col < width; col++)
dest[col] = src[col];
src = src.subspan(src_pitch_in_bytes / sizeof(U));
dest = dest.subspan(width);
}
}
public:
using surface_storage_type = typename Traits::surface_storage_type;
using surface_type = typename Traits::surface_type;
using command_list_type = typename Traits::command_list_type;
using download_buffer_object = typename Traits::download_buffer_object;
protected:
std::unordered_map<u32, surface_storage_type> m_render_targets_storage = {};
std::unordered_map<u32, surface_storage_type> m_depth_stencil_storage = {};
public:
std::pair<u8, u8> m_bound_render_targets_config = {};
std::array<std::pair<u32, surface_type>, 4> m_bound_render_targets = {};
std::pair<u32, surface_type> m_bound_depth_stencil = {};
std::list<surface_storage_type> invalidated_resources;
surface_store_deprecated() = default;
~surface_store_deprecated() = default;
surface_store_deprecated(const surface_store_deprecated&) = delete;
protected:
/**
* If render target already exists at address, issue state change operation on cmdList.
* Otherwise create one with width, height, clearColor info.
* returns the corresponding render target resource.
*/
template <typename ...Args>
surface_type bind_address_as_render_targets(
command_list_type command_list,
u32 address,
surface_color_format color_format,
surface_antialiasing antialias,
size_t width, size_t height, size_t pitch,
Args&&... extra_params)
{
// Check if render target already exists
auto It = m_render_targets_storage.find(address);
if (It != m_render_targets_storage.end())
{
surface_storage_type &rtt = It->second;
if (Traits::rtt_has_format_width_height(rtt, color_format, width, height))
{
Traits::prepare_rtt_for_drawing(command_list, Traits::get(rtt));
return Traits::get(rtt);
}
invalidated_resources.push_back(std::move(rtt));
m_render_targets_storage.erase(It);
}
m_render_targets_storage[address] = Traits::create_new_surface(address, color_format, width, height, pitch, std::forward<Args>(extra_params)...);
return Traits::get(m_render_targets_storage[address]);
}
template <typename ...Args>
surface_type bind_address_as_depth_stencil(
command_list_type command_list,
u32 address,
surface_depth_format depth_format,
surface_antialiasing antialias,
size_t width, size_t height, size_t pitch,
Args&&... extra_params)
{
auto It = m_depth_stencil_storage.find(address);
if (It != m_depth_stencil_storage.end())
{
surface_storage_type &ds = It->second;
if (Traits::ds_has_format_width_height(ds, depth_format, width, height))
{
Traits::prepare_ds_for_drawing(command_list, Traits::get(ds));
return Traits::get(ds);
}
invalidated_resources.push_back(std::move(ds));
m_depth_stencil_storage.erase(It);
}
m_depth_stencil_storage[address] = Traits::create_new_surface(address, depth_format, width, height, pitch, std::forward<Args>(extra_params)...);
return Traits::get(m_depth_stencil_storage[address]);
}
public:
/**
* Update bound color and depth surface.
* Must be called everytime surface format, clip, or addresses changes.
*/
template <typename ...Args>
void prepare_render_target(
command_list_type command_list,
surface_color_format color_format, surface_depth_format depth_format,
u32 clip_horizontal_reg, u32 clip_vertical_reg,
surface_target set_surface_target,
surface_antialiasing antialias,
const std::array<u32, 4> &surface_addresses, u32 address_z,
const std::array<u32, 4> &surface_pitch, u32 zeta_pitch,
Args&&... extra_params)
{
u32 clip_width = clip_horizontal_reg;
u32 clip_height = clip_vertical_reg;
// Make previous RTTs sampleable
for (int i = m_bound_render_targets_config.first, count = 0;
count < m_bound_render_targets_config.second;
++i, ++count)
{
auto &rtt = m_bound_render_targets[i];
Traits::prepare_rtt_for_sampling(command_list, std::get<1>(rtt));
rtt = std::make_pair(0, nullptr);
}
const auto rtt_indices = utility::get_rtt_indexes(set_surface_target);
if (LIKELY(!rtt_indices.empty()))
{
m_bound_render_targets_config = { rtt_indices.front(), 0 };
// Create/Reuse requested rtts
for (u8 surface_index : rtt_indices)
{
if (surface_addresses[surface_index] == 0)
continue;
m_bound_render_targets[surface_index] = std::make_pair(surface_addresses[surface_index],
bind_address_as_render_targets(command_list, surface_addresses[surface_index], color_format, antialias,
clip_width, clip_height, surface_pitch[surface_index], std::forward<Args>(extra_params)...));
m_bound_render_targets_config.second++;
}
}
else
{
m_bound_render_targets_config = { 0, 0 };
}
// Same for depth buffer
if (std::get<1>(m_bound_depth_stencil) != nullptr)
Traits::prepare_ds_for_sampling(command_list, std::get<1>(m_bound_depth_stencil));
m_bound_depth_stencil = std::make_pair(0, nullptr);
if (!address_z)
return;
m_bound_depth_stencil = std::make_pair(address_z,
bind_address_as_depth_stencil(command_list, address_z, depth_format, antialias,
clip_width, clip_height, zeta_pitch, std::forward<Args>(extra_params)...));
}
/**
* Search for given address in stored color surface
* Return an empty surface_type otherwise.
*/
surface_type get_texture_from_render_target_if_applicable(u32 address)
{
auto It = m_render_targets_storage.find(address);
if (It != m_render_targets_storage.end())
return Traits::get(It->second);
return surface_type();
}
/**
* Search for given address in stored depth stencil surface
* Return an empty surface_type otherwise.
*/
surface_type get_texture_from_depth_stencil_if_applicable(u32 address)
{
auto It = m_depth_stencil_storage.find(address);
if (It != m_depth_stencil_storage.end())
return Traits::get(It->second);
return surface_type();
}
/**
* Get bound color surface raw data.
*/
template <typename... Args>
std::array<std::vector<gsl::byte>, 4> get_render_targets_data(
surface_color_format color_format, size_t width, size_t height,
Args&& ...args
)
{
return {};
}
/**
* Get bound color surface raw data.
*/
template <typename... Args>
std::array<std::vector<gsl::byte>, 2> get_depth_stencil_data(
surface_depth_format depth_format, size_t width, size_t height,
Args&& ...args
)
{
return {};
}
};
struct render_target_traits struct render_target_traits
{ {
@ -55,18 +271,6 @@ struct render_target_traits
return rtt; return rtt;
} }
static
void get_surface_info(ID3D12Resource *surface, rsx::surface_format_info *info)
{
//TODO
auto desc = surface->GetDesc();
info->rsx_pitch = static_cast<u16>(desc.Width);
info->native_pitch = static_cast<u16>(desc.Width);
info->surface_width = static_cast<u32>(desc.Width);
info->surface_height = static_cast<u32>(desc.Height);
info->bpp = 1;
}
static static
void prepare_rtt_for_drawing( void prepare_rtt_for_drawing(
ID3D12GraphicsCommandList* command_list, ID3D12GraphicsCommandList* command_list,
@ -128,27 +332,6 @@ struct render_target_traits
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
} }
static
void invalidate_surface_contents(
ID3D12GraphicsCommandList*,
ID3D12Resource*,
u32, size_t)
{}
static
void notify_surface_invalidated(const ComPtr<ID3D12Resource>&)
{}
static
void notify_surface_persist(const ComPtr<ID3D12Resource>&)
{}
static
bool surface_is_pitch_compatible(const ComPtr<ID3D12Resource>&, size_t)
{
return true;
}
static static
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height, bool=false) bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height, bool=false)
{ {
@ -170,30 +353,7 @@ struct render_target_traits
ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store
) )
{ {
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get(); return {};
DXGI_FORMAT dxgi_format = get_color_surface_format(color_format);
size_t row_pitch = rsx::utility::get_aligned_pitch(color_format, ::narrow<u32>(width));
size_t buffer_size = row_pitch * height;
size_t heap_offset = readback_heap.alloc<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rtt, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE));
command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(readback_heap.get_heap(), { heap_offset,{ dxgi_format, (UINT)width, (UINT)height, 1, (UINT)row_pitch } }), 0, 0, 0,
&CD3DX12_TEXTURE_COPY_LOCATION(rtt, 0), nullptr);
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rtt, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));
CHECK_HRESULT(command_list->Close());
command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)res_store.command_list.GetAddressOf());
res_store.set_new_command_list();
ComPtr<ID3D12Fence> fence;
CHECK_HRESULT(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence->SetEventOnCompletion(1, handle);
command_queue->Signal(fence.Get(), 1);
return std::make_tuple(heap_offset, buffer_size, readback_heap.get_current_put_pos_minus_one(), fence, handle);
} }
static static
@ -203,30 +363,7 @@ struct render_target_traits
ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store
) )
{ {
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get(); return {};
DXGI_FORMAT dxgi_format = (depth_format == surface_depth_format::z24s8) ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_R16_TYPELESS;
size_t row_pitch = align(width * 4, 256);
size_t buffer_size = row_pitch * height;
size_t heap_offset = readback_heap.alloc<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE));
command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(readback_heap.get_heap(), { heap_offset,{ dxgi_format, (UINT)width, (UINT)height, 1, (UINT)row_pitch } }), 0, 0, 0,
&CD3DX12_TEXTURE_COPY_LOCATION(ds, 0), nullptr);
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE));
CHECK_HRESULT(command_list->Close());
command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)res_store.command_list.GetAddressOf());
res_store.set_new_command_list();
ComPtr<ID3D12Fence> fence;
CHECK_HRESULT(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence->SetEventOnCompletion(1, handle);
command_queue->Signal(fence.Get(), 1);
return std::make_tuple(heap_offset, buffer_size, readback_heap.get_current_put_pos_minus_one(), fence, handle);
} }
static static
@ -236,29 +373,7 @@ struct render_target_traits
ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store
) )
{ {
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get(); return {};
size_t row_pitch = align(width, 256);
size_t buffer_size = row_pitch * height;
size_t heap_offset = readback_heap.alloc<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(stencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE));
command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(readback_heap.get_heap(), { heap_offset,{ DXGI_FORMAT_R8_TYPELESS, (UINT)width, (UINT)height, 1, (UINT)row_pitch } }), 0, 0, 0,
&CD3DX12_TEXTURE_COPY_LOCATION(stencil, 1), nullptr);
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(stencil, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE));
CHECK_HRESULT(command_list->Close());
command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)res_store.command_list.GetAddressOf());
res_store.set_new_command_list();
ComPtr<ID3D12Fence> fence;
CHECK_HRESULT(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence->SetEventOnCompletion(1, handle);
command_queue->Signal(fence.Get(), 1);
return std::make_tuple(heap_offset, buffer_size, readback_heap.get_current_put_pos_minus_one(), fence, handle);
} }
static static
@ -291,7 +406,7 @@ struct render_target_traits
} }
}; };
struct render_targets : public rsx::surface_store<render_target_traits> struct render_targets : public rsx::surface_store_deprecated<render_target_traits>
{ {
INT g_descriptor_stride_rtv; INT g_descriptor_stride_rtv;