mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 23:41:26 +12:00
d3d12: Remove all shared code with other backends
This commit is contained in:
parent
0d906d6974
commit
db5d56a22d
2 changed files with 222 additions and 109 deletions
|
@ -1,4 +1,4 @@
|
|||
#ifdef _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_d3d12.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)
|
||||
{
|
||||
u32 addr = rsx::get_address(tiles[tile].offset, tiles[tile].location);
|
||||
m_rtts.invalidate_surface_address(addr, false);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,10 +8,226 @@
|
|||
|
||||
#include "D3D12Formats.h"
|
||||
#include "D3D12MemoryHelpers.h"
|
||||
#include "../Common/surface_store.h"
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -55,18 +271,6 @@ struct render_target_traits
|
|||
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
|
||||
void prepare_rtt_for_drawing(
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
)
|
||||
{
|
||||
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get();
|
||||
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);
|
||||
return {};
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -203,30 +363,7 @@ struct render_target_traits
|
|||
ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store
|
||||
)
|
||||
{
|
||||
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get();
|
||||
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);
|
||||
return {};
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -236,29 +373,7 @@ struct render_target_traits
|
|||
ID3D12Device* device, ID3D12CommandQueue* command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store
|
||||
)
|
||||
{
|
||||
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get();
|
||||
|
||||
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);
|
||||
return {};
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue