DX11 tweaks/caching
This commit is contained in:
parent
9f04712dd3
commit
a09ef8d4f6
|
@ -52,7 +52,7 @@ static void SetD3DDebugObjectName(ID3D11DeviceChild* obj, const std::string_view
|
|||
namespace Host {
|
||||
extern bool IsFullscreen();
|
||||
extern void SetFullscreen(bool enabled);
|
||||
}
|
||||
} // namespace Host
|
||||
|
||||
D3D11StreamBuffer::D3D11StreamBuffer() : m_size(0), m_position(0)
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ void D3D11StreamBuffer::Release()
|
|||
m_buffer.Reset();
|
||||
}
|
||||
|
||||
D3D11StreamBuffer::MappingResult D3D11StreamBuffer::Map(ID3D11DeviceContext* context, u32 alignment, u32 min_size)
|
||||
D3D11StreamBuffer::MappingResult D3D11StreamBuffer::Map(ID3D11DeviceContext1* context, u32 alignment, u32 min_size)
|
||||
{
|
||||
m_position = Common::AlignUp(m_position, alignment);
|
||||
if ((m_position + min_size) >= m_size || !m_use_map_no_overwrite)
|
||||
|
@ -151,7 +151,7 @@ D3D11StreamBuffer::MappingResult D3D11StreamBuffer::Map(ID3D11DeviceContext* con
|
|||
(m_size - m_position) / alignment};
|
||||
}
|
||||
|
||||
void D3D11StreamBuffer::Unmap(ID3D11DeviceContext* context, u32 used_size)
|
||||
void D3D11StreamBuffer::Unmap(ID3D11DeviceContext1* context, u32 used_size)
|
||||
{
|
||||
context->Unmap(m_buffer.Get(), 0);
|
||||
m_position += used_size;
|
||||
|
@ -255,10 +255,10 @@ void D3D11Device::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 d
|
|||
{
|
||||
DebugAssert(src_level < src->GetLevels() && src_layer < src->GetLayers());
|
||||
DebugAssert((src_x + width) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipHeight(src_level));
|
||||
DebugAssert(dst_level < dst->GetLevels() && dst_layer < dst->GetLayers());
|
||||
DebugAssert((dst_x + width) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipHeight(dst_level));
|
||||
|
||||
D3D11Texture* dst11 = static_cast<D3D11Texture*>(dst);
|
||||
D3D11Texture* src11 = static_cast<D3D11Texture*>(src);
|
||||
|
@ -300,10 +300,10 @@ void D3D11Device::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
|
|||
{
|
||||
DebugAssert(src_level < src->GetLevels() && src_layer < src->GetLayers());
|
||||
DebugAssert((src_x + width) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipHeight(src_level));
|
||||
DebugAssert(dst_level < dst->GetLevels() && dst_layer < dst->GetLayers());
|
||||
DebugAssert((dst_x + width) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipHeight(dst_level));
|
||||
DebugAssert(!dst->IsMultisampled() && src->IsMultisampled());
|
||||
|
||||
// DX11 can't resolve partial rects.
|
||||
|
@ -320,6 +320,27 @@ void D3D11Device::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
|
|||
dst11->GetDXGIFormat());
|
||||
}
|
||||
|
||||
void D3D11Device::ClearRenderTarget(GPUTexture* t, u32 c)
|
||||
{
|
||||
GPUDevice::ClearRenderTarget(t, c);
|
||||
if (m_current_framebuffer && m_current_framebuffer->GetRT() == t)
|
||||
static_cast<D3D11Texture*>(t)->CommitClear(m_context.Get());
|
||||
}
|
||||
|
||||
void D3D11Device::ClearDepth(GPUTexture* t, float d)
|
||||
{
|
||||
GPUDevice::ClearDepth(t, d);
|
||||
if (m_current_framebuffer && m_current_framebuffer->GetDS() == t)
|
||||
static_cast<D3D11Texture*>(t)->CommitClear(m_context.Get());
|
||||
}
|
||||
|
||||
void D3D11Device::InvalidateRenderTarget(GPUTexture* t)
|
||||
{
|
||||
GPUDevice::InvalidateRenderTarget(t);
|
||||
if (m_current_framebuffer && (m_current_framebuffer->GetRT() == t || m_current_framebuffer->GetDS() == t))
|
||||
static_cast<D3D11Texture*>(t)->CommitClear(m_context.Get());
|
||||
}
|
||||
|
||||
bool D3D11Device::GetHostRefreshRate(float* refresh_rate)
|
||||
{
|
||||
if (m_swap_chain && m_is_exclusive_fullscreen)
|
||||
|
@ -344,10 +365,10 @@ void D3D11Device::SetVSync(bool enabled)
|
|||
m_vsync_enabled = enabled;
|
||||
}
|
||||
|
||||
bool D3D11Device::CreateDevice(const std::string_view& adapter, bool debug_device)
|
||||
bool D3D11Device::CreateDevice(const std::string_view& adapter)
|
||||
{
|
||||
UINT create_flags = 0;
|
||||
if (debug_device)
|
||||
if (m_debug_device)
|
||||
create_flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
|
||||
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
||||
|
@ -410,7 +431,7 @@ bool D3D11Device::CreateDevice(const std::string_view& adapter, bool debug_devic
|
|||
return false;
|
||||
}
|
||||
|
||||
if (debug_device && IsDebuggerPresent())
|
||||
if (m_debug_device && IsDebuggerPresent())
|
||||
{
|
||||
ComPtr<ID3D11InfoQueue> info;
|
||||
hr = m_device.As(&info);
|
||||
|
@ -422,7 +443,7 @@ bool D3D11Device::CreateDevice(const std::string_view& adapter, bool debug_devic
|
|||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (debug_device)
|
||||
if (m_debug_device)
|
||||
m_context.As(&m_annotation);
|
||||
#endif
|
||||
|
||||
|
@ -778,7 +799,7 @@ void D3D11Device::DestroySurface()
|
|||
DestroySwapChain();
|
||||
}
|
||||
|
||||
std::string D3D11Device::GetShaderCacheBaseName(const std::string_view& type, bool debug) const
|
||||
std::string D3D11Device::GetShaderCacheBaseName(const std::string_view& type) const
|
||||
{
|
||||
std::string_view flname;
|
||||
switch (m_device->GetFeatureLevel())
|
||||
|
@ -790,7 +811,7 @@ std::string D3D11Device::GetShaderCacheBaseName(const std::string_view& type, bo
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
return fmt::format("d3d_{}_{}{}", type, flname, debug ? "_debug" : "");
|
||||
return fmt::format("d3d_{}_{}{}", type, flname, m_debug_device ? "_debug" : "");
|
||||
}
|
||||
|
||||
void D3D11Device::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||
|
@ -832,6 +853,8 @@ bool D3D11Device::CreateBuffers()
|
|||
return false;
|
||||
}
|
||||
|
||||
// Index buffer never changes :)
|
||||
m_context->IASetIndexBuffer(m_index_buffer.GetD3DBuffer(), DXGI_FORMAT_R16_UINT, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1095,7 +1118,10 @@ D3D11Framebuffer::D3D11Framebuffer(GPUTexture* rt, GPUTexture* ds, u32 width, u3
|
|||
{
|
||||
}
|
||||
|
||||
D3D11Framebuffer::~D3D11Framebuffer() = default;
|
||||
D3D11Framebuffer::~D3D11Framebuffer()
|
||||
{
|
||||
D3D11Device::GetInstance().UnbindFramebuffer(this);
|
||||
}
|
||||
|
||||
void D3D11Framebuffer::SetDebugName(const std::string_view& name)
|
||||
{
|
||||
|
@ -1105,12 +1131,12 @@ void D3D11Framebuffer::SetDebugName(const std::string_view& name)
|
|||
SetD3DDebugObjectName(m_dsv.Get(), fmt::format("{} DSV", name));
|
||||
}
|
||||
|
||||
void D3D11Framebuffer::CommitClear(ID3D11DeviceContext* context)
|
||||
void D3D11Framebuffer::CommitClear(ID3D11DeviceContext1* context)
|
||||
{
|
||||
if (UNLIKELY(m_rt && m_rt->GetState() != GPUTexture::State::Dirty))
|
||||
{
|
||||
if (m_rt->GetState() == GPUTexture::State::Invalidated)
|
||||
; // m_context->DiscardView(m_rtv.Get());
|
||||
context->DiscardView(m_rtv.Get());
|
||||
else
|
||||
context->ClearRenderTargetView(m_rtv.Get(), m_rt->GetUNormClearColor().data());
|
||||
|
||||
|
@ -1120,7 +1146,7 @@ void D3D11Framebuffer::CommitClear(ID3D11DeviceContext* context)
|
|||
if (UNLIKELY(m_ds && m_ds->GetState() != GPUTexture::State::Dirty))
|
||||
{
|
||||
if (m_ds->GetState() == GPUTexture::State::Invalidated)
|
||||
; // m_context->DiscardView(m_dsv.Get());
|
||||
context->DiscardView(m_dsv.Get());
|
||||
else
|
||||
context->ClearDepthStencilView(m_dsv.Get(), D3D11_CLEAR_DEPTH, m_ds->GetClearDepth(), 0);
|
||||
|
||||
|
@ -1379,13 +1405,6 @@ std::unique_ptr<GPUShader> D3D11Device::CreateShaderFromBinary(GPUShaderStage st
|
|||
std::unique_ptr<GPUShader> D3D11Device::CreateShaderFromSource(GPUShaderStage stage, const std::string_view& source,
|
||||
std::vector<u8>* out_binary /* = nullptr */)
|
||||
{
|
||||
// TODO: This shouldn't be dependent on build type.
|
||||
#ifdef _DEBUG
|
||||
constexpr bool debug = true;
|
||||
#else
|
||||
constexpr bool debug = false;
|
||||
#endif
|
||||
|
||||
const char* target;
|
||||
switch (m_device->GetFeatureLevel())
|
||||
{
|
||||
|
@ -1426,7 +1445,7 @@ std::unique_ptr<GPUShader> D3D11Device::CreateShaderFromSource(GPUShaderStage st
|
|||
ComPtr<ID3DBlob> error_blob;
|
||||
const HRESULT hr =
|
||||
D3DCompile(source.data(), source.size(), "0", nullptr, nullptr, "main", target,
|
||||
debug ? flags_debug : flags_non_debug, 0, blob.GetAddressOf(), error_blob.GetAddressOf());
|
||||
m_debug_device ? flags_debug : flags_non_debug, 0, blob.GetAddressOf(), error_blob.GetAddressOf());
|
||||
|
||||
std::string error_string;
|
||||
if (error_blob)
|
||||
|
@ -1467,31 +1486,24 @@ std::unique_ptr<GPUShader> D3D11Device::CreateShaderFromSource(GPUShaderStage st
|
|||
|
||||
D3D11Pipeline::D3D11Pipeline(ComPtr<ID3D11RasterizerState> rs, ComPtr<ID3D11DepthStencilState> ds,
|
||||
ComPtr<ID3D11BlendState> bs, ComPtr<ID3D11InputLayout> il, ComPtr<ID3D11VertexShader> vs,
|
||||
ComPtr<ID3D11PixelShader> ps, D3D11_PRIMITIVE_TOPOLOGY topology)
|
||||
ComPtr<ID3D11PixelShader> ps, D3D11_PRIMITIVE_TOPOLOGY topology, u32 vertex_stride,
|
||||
u32 blend_factor)
|
||||
: m_rs(std::move(rs)), m_ds(std::move(ds)), m_bs(std::move(bs)), m_il(std::move(il)), m_vs(std::move(vs)),
|
||||
m_ps(std::move(ps)), m_topology(topology)
|
||||
m_ps(std::move(ps)), m_topology(topology), m_vertex_stride(vertex_stride), m_blend_factor(blend_factor),
|
||||
m_blend_factor_float(GPUDevice::RGBA8ToFloat(blend_factor))
|
||||
{
|
||||
}
|
||||
|
||||
D3D11Pipeline::~D3D11Pipeline() = default;
|
||||
D3D11Pipeline::~D3D11Pipeline()
|
||||
{
|
||||
D3D11Device::GetInstance().UnbindPipeline(this);
|
||||
}
|
||||
|
||||
void D3D11Pipeline::SetDebugName(const std::string_view& name)
|
||||
{
|
||||
// can't label this directly
|
||||
}
|
||||
|
||||
void D3D11Pipeline::Bind(ID3D11DeviceContext* context)
|
||||
{
|
||||
// TODO: constant blend factor
|
||||
context->IASetInputLayout(GetInputLayout());
|
||||
context->IASetPrimitiveTopology(GetPrimitiveTopology());
|
||||
context->RSSetState(GetRasterizerState());
|
||||
context->OMSetDepthStencilState(GetDepthStencilState(), 0);
|
||||
context->OMSetBlendState(GetBlendState(), nullptr, 0xFFFFFFFFu);
|
||||
context->VSSetShader(GetVertexShader(), nullptr, 0);
|
||||
context->PSSetShader(GetPixelShader(), nullptr, 0);
|
||||
}
|
||||
|
||||
D3D11Device::ComPtr<ID3D11RasterizerState> D3D11Device::GetRasterizationState(const GPUPipeline::RasterizationState& rs)
|
||||
{
|
||||
ComPtr<ID3D11RasterizerState> drs;
|
||||
|
@ -1627,12 +1639,6 @@ D3D11Device::ComPtr<ID3D11InputLayout> D3D11Device::GetInputLayout(const GPUPipe
|
|||
return dil;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static constexpr std::array<const char*, static_cast<u32>(GPUPipeline::VertexAttribute::MaxAttributes)> semantics = {
|
||||
{"ATTR0", "ATTR1", "ATTR2", "ATTR3", "ATTR4", "ATTR5", "ATTR6", "ATTR7", "ATTR8", "ATTR9", "ATTR10", "ATTR11",
|
||||
"ATTR12", "ATTR13", "ATTR14", "ATTR15"}};
|
||||
#endif
|
||||
|
||||
static constexpr u32 MAX_COMPONENTS = 4;
|
||||
static constexpr const DXGI_FORMAT
|
||||
format_mapping[static_cast<u8>(GPUPipeline::VertexAttribute::Type::MaxCount)][MAX_COMPONENTS] = {
|
||||
|
@ -1683,9 +1689,11 @@ std::unique_ptr<GPUPipeline> D3D11Device::CreatePipeline(const GPUPipeline::Grap
|
|||
return {};
|
||||
|
||||
ComPtr<ID3D11InputLayout> il;
|
||||
u32 vertex_stride = 0;
|
||||
if (!config.input_layout.vertex_attributes.empty())
|
||||
{
|
||||
il = GetInputLayout(config.input_layout, static_cast<const D3D11Shader*>(config.vertex_shader));
|
||||
vertex_stride = config.input_layout.vertex_stride;
|
||||
if (!il)
|
||||
return {};
|
||||
}
|
||||
|
@ -1702,7 +1710,7 @@ std::unique_ptr<GPUPipeline> D3D11Device::CreatePipeline(const GPUPipeline::Grap
|
|||
new D3D11Pipeline(std::move(rs), std::move(ds), std::move(bs), std::move(il),
|
||||
static_cast<const D3D11Shader*>(config.vertex_shader)->GetVertexShader(),
|
||||
static_cast<const D3D11Shader*>(config.fragment_shader)->GetPixelShader(),
|
||||
primitives[static_cast<u8>(config.primitive)]));
|
||||
primitives[static_cast<u8>(config.primitive)], vertex_stride, config.blend.constant));
|
||||
}
|
||||
|
||||
D3D11Texture::D3D11Texture() = default;
|
||||
|
@ -1748,23 +1756,22 @@ D3D11_TEXTURE2D_DESC D3D11Texture::GetDesc() const
|
|||
return desc;
|
||||
}
|
||||
|
||||
void D3D11Texture::CommitClear(ID3D11DeviceContext* context)
|
||||
void D3D11Texture::CommitClear(ID3D11DeviceContext1* context)
|
||||
{
|
||||
if (m_state == GPUTexture::State::Dirty)
|
||||
return;
|
||||
|
||||
// TODO: 11.1
|
||||
if (IsDepthStencil())
|
||||
{
|
||||
if (m_state == GPUTexture::State::Invalidated)
|
||||
; // context->DiscardView(GetD3DDSV());
|
||||
context->DiscardView(GetD3DDSV());
|
||||
else
|
||||
context->ClearDepthStencilView(GetD3DDSV(), D3D11_CLEAR_DEPTH, GetClearDepth(), 0);
|
||||
}
|
||||
else if (IsRenderTarget())
|
||||
{
|
||||
if (m_state == GPUTexture::State::Invalidated)
|
||||
; // context->DiscardView(GetD3DRTV());
|
||||
context->DiscardView(GetD3DRTV());
|
||||
else
|
||||
context->ClearRenderTargetView(GetD3DRTV(), GetUNormClearColor().data());
|
||||
}
|
||||
|
@ -1796,7 +1803,7 @@ bool D3D11Texture::Update(u32 x, u32 y, u32 width, u32 height, const void* data,
|
|||
static_cast<LONG>(y + height), 1);
|
||||
const u32 srnum = D3D11CalcSubresource(level, layer, m_levels);
|
||||
|
||||
ID3D11DeviceContext* context = D3D11Device::GetD3DContext();
|
||||
ID3D11DeviceContext1* context = D3D11Device::GetD3DContext();
|
||||
CommitClear(context);
|
||||
context->UpdateSubresource(m_texture.Get(), srnum, &box, data, pitch, 0);
|
||||
m_state = GPUTexture::State::Dirty;
|
||||
|
@ -1815,7 +1822,7 @@ bool D3D11Texture::Map(void** map, u32* map_stride, u32 x, u32 y, u32 width, u32
|
|||
const bool discard = (width == m_width && height == m_height);
|
||||
const u32 srnum = D3D11CalcSubresource(level, layer, m_levels);
|
||||
|
||||
ID3D11DeviceContext* context = D3D11Device::GetD3DContext();
|
||||
ID3D11DeviceContext1* context = D3D11Device::GetD3DContext();
|
||||
CommitClear(context);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE sr;
|
||||
|
@ -1950,6 +1957,7 @@ bool D3D11Texture::Create(ID3D11Device* device, u32 width, u32 height, u32 layer
|
|||
m_layers = static_cast<u8>(layers);
|
||||
m_levels = static_cast<u8>(levels);
|
||||
m_samples = static_cast<u8>(samples);
|
||||
m_type = type;
|
||||
m_format = format;
|
||||
m_dynamic = dynamic;
|
||||
return true;
|
||||
|
@ -2021,6 +2029,7 @@ bool D3D11Texture::Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture)
|
|||
|
||||
void D3D11Texture::Destroy()
|
||||
{
|
||||
D3D11Device::GetInstance().UnbindTexture(this);
|
||||
m_rtv_dsv.Reset();
|
||||
m_srv.Reset();
|
||||
m_texture.Reset();
|
||||
|
@ -2130,10 +2139,6 @@ void D3D11Device::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_
|
|||
void D3D11Device::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
|
||||
{
|
||||
m_vertex_buffer.Unmap(m_context.Get(), vertex_size * vertex_count);
|
||||
|
||||
// TODO: cache - should come from pipeline
|
||||
const UINT offset = 0;
|
||||
m_context->IASetVertexBuffers(0, 1, m_vertex_buffer.GetD3DBufferArray(), &vertex_size, &offset);
|
||||
}
|
||||
|
||||
void D3D11Device::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
|
||||
|
@ -2147,7 +2152,6 @@ void D3D11Device::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_
|
|||
void D3D11Device::UnmapIndexBuffer(u32 used_index_count)
|
||||
{
|
||||
m_index_buffer.Unmap(m_context.Get(), sizeof(DrawIndex) * used_index_count);
|
||||
m_context->IASetIndexBuffer(m_index_buffer.GetD3DBuffer(), DXGI_FORMAT_R16_UINT, 0);
|
||||
}
|
||||
|
||||
void D3D11Device::PushUniformBuffer(const void* data, u32 data_size)
|
||||
|
@ -2193,6 +2197,33 @@ void D3D11Device::SetFramebuffer(GPUFramebuffer* fb)
|
|||
return;
|
||||
}
|
||||
|
||||
// Make sure textures aren't bound.
|
||||
if (D3D11Texture* rt = static_cast<D3D11Texture*>(fb->GetRT()); rt)
|
||||
{
|
||||
const ID3D11ShaderResourceView* srv = rt->GetD3DSRV();
|
||||
for (u32 i = 0; i < MAX_TEXTURE_SAMPLERS; i++)
|
||||
{
|
||||
if (m_current_textures[i] == srv)
|
||||
{
|
||||
m_current_textures[i] = nullptr;
|
||||
m_context->PSSetShaderResources(i, 1, &m_current_textures[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (D3D11Texture* ds = static_cast<D3D11Texture*>(fb->GetDS()); ds)
|
||||
{
|
||||
const ID3D11ShaderResourceView* srv = ds->GetD3DSRV();
|
||||
for (u32 i = 0; i < MAX_TEXTURE_SAMPLERS; i++)
|
||||
{
|
||||
if (m_current_textures[i] == srv)
|
||||
{
|
||||
m_current_textures[i] = nullptr;
|
||||
m_context->PSSetShaderResources(i, 1, &m_current_textures[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_current_framebuffer->CommitClear(m_context.Get());
|
||||
m_context->OMSetRenderTargets(m_current_framebuffer->GetNumRTVs(), m_current_framebuffer->GetRTVArray(),
|
||||
m_current_framebuffer->GetDSV());
|
||||
}
|
||||
|
@ -2208,10 +2239,62 @@ void D3D11Device::UnbindFramebuffer(D3D11Framebuffer* fb)
|
|||
|
||||
void D3D11Device::SetPipeline(GPUPipeline* pipeline)
|
||||
{
|
||||
D3D11Pipeline* PL = static_cast<D3D11Pipeline*>(pipeline);
|
||||
if (m_current_pipeline == pipeline)
|
||||
return;
|
||||
|
||||
// TODO: cache
|
||||
PL->Bind(m_context.Get());
|
||||
D3D11Pipeline* const PL = static_cast<D3D11Pipeline*>(pipeline);
|
||||
m_current_pipeline = PL;
|
||||
|
||||
if (ID3D11InputLayout* il = PL->GetInputLayout(); m_current_input_layout != il)
|
||||
{
|
||||
m_current_input_layout = il;
|
||||
m_context->IASetInputLayout(il);
|
||||
}
|
||||
|
||||
if (const u32 vertex_stride = PL->GetVertexStride(); m_current_vertex_stride != vertex_stride)
|
||||
{
|
||||
const UINT offset = 0;
|
||||
m_current_vertex_stride = PL->GetVertexStride();
|
||||
m_context->IASetVertexBuffers(0, 1, m_vertex_buffer.GetD3DBufferArray(), &m_current_vertex_stride, &offset);
|
||||
}
|
||||
|
||||
if (D3D_PRIMITIVE_TOPOLOGY topology = PL->GetPrimitiveTopology(); m_current_primitive_topology != topology)
|
||||
{
|
||||
m_current_primitive_topology = topology;
|
||||
m_context->IASetPrimitiveTopology(topology);
|
||||
}
|
||||
|
||||
if (ID3D11VertexShader* vs = PL->GetVertexShader(); m_current_vertex_shader != vs)
|
||||
{
|
||||
m_current_vertex_shader = vs;
|
||||
m_context->VSSetShader(vs, nullptr, 0);
|
||||
}
|
||||
|
||||
if (ID3D11PixelShader* ps = PL->GetPixelShader(); m_current_pixel_shader != ps)
|
||||
{
|
||||
m_current_pixel_shader = ps;
|
||||
m_context->PSSetShader(ps, nullptr, 0);
|
||||
}
|
||||
|
||||
if (ID3D11RasterizerState* rs = PL->GetRasterizerState(); m_current_rasterizer_state != rs)
|
||||
{
|
||||
m_current_rasterizer_state = rs;
|
||||
m_context->RSSetState(rs);
|
||||
}
|
||||
|
||||
if (ID3D11DepthStencilState* ds = PL->GetDepthStencilState(); m_current_depth_state != ds)
|
||||
{
|
||||
m_current_depth_state = ds;
|
||||
m_context->OMSetDepthStencilState(ds, 0);
|
||||
}
|
||||
|
||||
if (ID3D11BlendState* bs = PL->GetBlendState();
|
||||
m_current_blend_state != bs || m_current_blend_factor != PL->GetBlendFactor())
|
||||
{
|
||||
m_current_blend_state = bs;
|
||||
m_current_blend_factor = PL->GetBlendFactor();
|
||||
m_context->OMSetBlendState(bs, RGBA8ToFloat(m_current_blend_factor).data(), 0xFFFFFFFFu);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11Device::UnbindPipeline(D3D11Pipeline* pl)
|
||||
|
@ -2219,27 +2302,57 @@ void D3D11Device::UnbindPipeline(D3D11Pipeline* pl)
|
|||
if (m_current_pipeline != pl)
|
||||
return;
|
||||
|
||||
// Let the runtime deal with the dead objects...
|
||||
m_current_pipeline = nullptr;
|
||||
}
|
||||
|
||||
void D3D11Device::SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler)
|
||||
{
|
||||
// TODO: cache when old rt == tex
|
||||
D3D11Texture* T = static_cast<D3D11Texture*>(texture);
|
||||
D3D11Sampler* S = static_cast<D3D11Sampler*>(sampler);
|
||||
m_context->PSSetShaderResources(0, 1, T->GetD3DSRVArray());
|
||||
m_context->PSSetSamplers(0, 1, S->GetSamplerStateArray());
|
||||
ID3D11ShaderResourceView* T = texture ? static_cast<D3D11Texture*>(texture)->GetD3DSRV() : nullptr;
|
||||
ID3D11SamplerState* S = sampler ? static_cast<D3D11Sampler*>(sampler)->GetSamplerState() : nullptr;
|
||||
|
||||
// Runtime will null these if we don't...
|
||||
DebugAssert(!m_current_framebuffer || !texture ||
|
||||
(m_current_framebuffer->GetRT() != texture && m_current_framebuffer->GetDS() != texture));
|
||||
|
||||
if (m_current_textures[slot] != T)
|
||||
{
|
||||
m_current_textures[slot] = T;
|
||||
m_context->PSSetShaderResources(slot, 1, &T);
|
||||
}
|
||||
if (m_current_samplers[slot] != S)
|
||||
{
|
||||
m_current_samplers[slot] = S;
|
||||
m_context->PSSetSamplers(slot, 1, &S);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11Device::SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer)
|
||||
{
|
||||
D3D11TextureBuffer* B = static_cast<D3D11TextureBuffer*>(buffer);
|
||||
m_context->PSSetShaderResources(0, 1, B->GetSRVArray());
|
||||
ID3D11ShaderResourceView* B = buffer ? static_cast<D3D11TextureBuffer*>(buffer)->GetSRV() : nullptr;
|
||||
if (m_current_textures[slot] != B)
|
||||
{
|
||||
m_current_textures[slot] = B;
|
||||
m_context->PSSetShaderResources(slot, 1, &B);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11Device::UnbindTexture(D3D11Texture* tex)
|
||||
{
|
||||
// TODO
|
||||
if (const ID3D11ShaderResourceView* srv = tex->GetD3DSRV(); srv)
|
||||
{
|
||||
for (u32 i = 0; i < MAX_TEXTURE_SAMPLERS; i++)
|
||||
{
|
||||
if (m_current_textures[i] == srv)
|
||||
{
|
||||
m_current_textures[i] = nullptr;
|
||||
m_context->PSSetShaderResources(i, 1, &m_current_textures[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_current_framebuffer && m_current_framebuffer->GetRT() == tex)
|
||||
SetFramebuffer(nullptr);
|
||||
}
|
||||
|
||||
void D3D11Device::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
||||
|
@ -2255,20 +2368,12 @@ void D3D11Device::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
|||
m_context->RSSetScissorRects(1, &rc);
|
||||
}
|
||||
|
||||
void D3D11Device::PreDrawCheck()
|
||||
{
|
||||
if (m_current_framebuffer)
|
||||
m_current_framebuffer->CommitClear(m_context.Get());
|
||||
}
|
||||
|
||||
void D3D11Device::Draw(u32 vertex_count, u32 base_vertex)
|
||||
{
|
||||
PreDrawCheck();
|
||||
m_context->Draw(vertex_count, base_vertex);
|
||||
}
|
||||
|
||||
void D3D11Device::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
|
||||
{
|
||||
PreDrawCheck();
|
||||
m_context->DrawIndexed(index_count, base_index, base_vertex);
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ public:
|
|||
u32 space_aligned; // remaining space / alignment
|
||||
};
|
||||
|
||||
MappingResult Map(ID3D11DeviceContext* context, u32 alignment, u32 min_size);
|
||||
void Unmap(ID3D11DeviceContext* context, u32 used_size);
|
||||
MappingResult Map(ID3D11DeviceContext1* context, u32 alignment, u32 min_size);
|
||||
void Unmap(ID3D11DeviceContext1* context, u32 used_size);
|
||||
|
||||
private:
|
||||
ComPtr<ID3D11Buffer> m_buffer;
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
ALWAYS_INLINE ID3D11DepthStencilView* GetDSV() const { return m_dsv.Get(); }
|
||||
|
||||
void SetDebugName(const std::string_view& name) override;
|
||||
void CommitClear(ID3D11DeviceContext* context);
|
||||
void CommitClear(ID3D11DeviceContext1* context);
|
||||
|
||||
private:
|
||||
D3D11Framebuffer(GPUTexture* rt, GPUTexture* ds, u32 width, u32 height, ComPtr<ID3D11RenderTargetView> rtv,
|
||||
|
@ -146,13 +146,14 @@ public:
|
|||
ALWAYS_INLINE ID3D11VertexShader* GetVertexShader() const { return m_vs.Get(); }
|
||||
ALWAYS_INLINE ID3D11PixelShader* GetPixelShader() const { return m_ps.Get(); }
|
||||
ALWAYS_INLINE D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology() const { return m_topology; }
|
||||
|
||||
void Bind(ID3D11DeviceContext* context);
|
||||
ALWAYS_INLINE u32 GetVertexStride() const { return m_vertex_stride; }
|
||||
ALWAYS_INLINE u32 GetBlendFactor() const { return m_blend_factor; }
|
||||
ALWAYS_INLINE const std::array<float, 4>& GetBlendFactorFloat() const { return m_blend_factor_float; }
|
||||
|
||||
private:
|
||||
D3D11Pipeline(ComPtr<ID3D11RasterizerState> rs, ComPtr<ID3D11DepthStencilState> ds, ComPtr<ID3D11BlendState> bs,
|
||||
ComPtr<ID3D11InputLayout> il, ComPtr<ID3D11VertexShader> vs, ComPtr<ID3D11PixelShader> ps,
|
||||
D3D11_PRIMITIVE_TOPOLOGY topology);
|
||||
D3D11_PRIMITIVE_TOPOLOGY topology, u32 vertex_stride, u32 blend_factor);
|
||||
|
||||
ComPtr<ID3D11RasterizerState> m_rs;
|
||||
ComPtr<ID3D11DepthStencilState> m_ds;
|
||||
|
@ -161,6 +162,9 @@ private:
|
|||
ComPtr<ID3D11VertexShader> m_vs;
|
||||
ComPtr<ID3D11PixelShader> m_ps;
|
||||
D3D11_PRIMITIVE_TOPOLOGY m_topology;
|
||||
u32 m_vertex_stride;
|
||||
u32 m_blend_factor;
|
||||
std::array<float, 4> m_blend_factor_float;
|
||||
};
|
||||
|
||||
class D3D11Texture final : public GPUTexture
|
||||
|
@ -215,7 +219,7 @@ public:
|
|||
void Destroy();
|
||||
|
||||
D3D11_TEXTURE2D_DESC GetDesc() const;
|
||||
void CommitClear(ID3D11DeviceContext* context);
|
||||
void CommitClear(ID3D11DeviceContext1* context);
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
|
@ -265,7 +269,7 @@ public:
|
|||
|
||||
ALWAYS_INLINE static D3D11Device& GetInstance() { return *static_cast<D3D11Device*>(g_gpu_device.get()); }
|
||||
ALWAYS_INLINE static ID3D11Device* GetD3DDevice() { return GetInstance().m_device.Get(); }
|
||||
ALWAYS_INLINE static ID3D11DeviceContext* GetD3DContext() { return GetInstance().m_context.Get(); }
|
||||
ALWAYS_INLINE static ID3D11DeviceContext1* GetD3DContext() { return GetInstance().m_context.Get(); }
|
||||
|
||||
// returns the fullscreen mode to use for the specified dimensions
|
||||
static bool GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const RECT& window_rect, u32 width,
|
||||
|
@ -282,7 +286,7 @@ public:
|
|||
AdapterAndModeList GetAdapterAndModeList() override;
|
||||
void DestroySurface() override;
|
||||
|
||||
std::string GetShaderCacheBaseName(const std::string_view& type, bool debug) const override;
|
||||
std::string GetShaderCacheBaseName(const std::string_view& type) const override;
|
||||
|
||||
std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||
GPUTexture::Type type, GPUTexture::Format format,
|
||||
|
@ -298,6 +302,9 @@ public:
|
|||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ClearRenderTarget(GPUTexture* t, u32 c) override;
|
||||
void ClearDepth(GPUTexture* t, float d) override;
|
||||
void InvalidateRenderTarget(GPUTexture* t) override;
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt = nullptr, u32 rt_layer = 0, u32 rt_level = 0,
|
||||
GPUTexture* ds = nullptr, u32 ds_layer = 0,
|
||||
|
@ -346,7 +353,7 @@ public:
|
|||
static AdapterAndModeList StaticGetAdapterAndModeList();
|
||||
|
||||
protected:
|
||||
bool CreateDevice(const std::string_view& adapter, bool debug_device) override;
|
||||
bool CreateDevice(const std::string_view& adapter) override;
|
||||
void DestroyDevice() override;
|
||||
|
||||
private:
|
||||
|
@ -366,8 +373,6 @@ private:
|
|||
|
||||
void SetFeatures();
|
||||
|
||||
void PreDrawCheck();
|
||||
|
||||
bool CheckStagingBufferSize(u32 width, u32 height, DXGI_FORMAT format);
|
||||
void DestroyStagingBuffer();
|
||||
|
||||
|
@ -418,6 +423,19 @@ private:
|
|||
D3D11Framebuffer* m_current_framebuffer = nullptr;
|
||||
D3D11Pipeline* m_current_pipeline = nullptr;
|
||||
|
||||
ID3D11InputLayout* m_current_input_layout = nullptr;
|
||||
ID3D11VertexShader* m_current_vertex_shader = nullptr;
|
||||
ID3D11PixelShader* m_current_pixel_shader = nullptr;
|
||||
ID3D11RasterizerState* m_current_rasterizer_state = nullptr;
|
||||
ID3D11DepthStencilState* m_current_depth_state = nullptr;
|
||||
ID3D11BlendState* m_current_blend_state = nullptr;
|
||||
D3D_PRIMITIVE_TOPOLOGY m_current_primitive_topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
u32 m_current_vertex_stride = 0;
|
||||
u32 m_current_blend_factor = 0;
|
||||
|
||||
std::array<ID3D11ShaderResourceView*, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
||||
std::array<ID3D11SamplerState*, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
||||
|
||||
std::array<std::array<ComPtr<ID3D11Query>, 3>, NUM_TIMESTAMP_QUERIES> m_timestamp_queries = {};
|
||||
u8 m_read_timestamp_query = 0;
|
||||
u8 m_write_timestamp_query = 0;
|
||||
|
|
|
@ -237,6 +237,7 @@ bool GPUDevice::Create(const std::string_view& adapter, const std::string_view&
|
|||
bool vsync)
|
||||
{
|
||||
m_vsync_enabled = vsync;
|
||||
m_debug_device = debug_device;
|
||||
|
||||
if (!AcquireWindow(true))
|
||||
{
|
||||
|
@ -244,14 +245,14 @@ bool GPUDevice::Create(const std::string_view& adapter, const std::string_view&
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!CreateDevice(adapter, debug_device))
|
||||
if (!CreateDevice(adapter))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create device.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!shader_cache_path.empty())
|
||||
OpenShaderCache(shader_cache_path, debug_device);
|
||||
OpenShaderCache(shader_cache_path);
|
||||
else
|
||||
Log_WarningPrintf("Shader cache is disabled.");
|
||||
|
||||
|
@ -284,10 +285,10 @@ bool GPUDevice::SupportsExclusiveFullscreen() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void GPUDevice::OpenShaderCache(const std::string_view& base_path, bool debug)
|
||||
void GPUDevice::OpenShaderCache(const std::string_view& base_path)
|
||||
{
|
||||
// TODO: option to disable shader cache
|
||||
const std::string basename = GetShaderCacheBaseName("shaders", debug);
|
||||
const std::string basename = GetShaderCacheBaseName("shaders");
|
||||
const std::string filename = Path::Combine(base_path, basename);
|
||||
if (!m_shader_cache.Open(filename.c_str()))
|
||||
Log_WarningPrintf("Failed to open shader cache.");
|
||||
|
@ -418,7 +419,7 @@ bool GPUDevice::SetPostProcessingChain(const std::string_view& config)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string GPUDevice::GetShaderCacheBaseName(const std::string_view& type, bool debug) const
|
||||
std::string GPUDevice::GetShaderCacheBaseName(const std::string_view& type) const
|
||||
{
|
||||
Panic("Not implemented");
|
||||
return {};
|
||||
|
@ -648,7 +649,7 @@ void GPUDevice::InvalidateRenderTarget(GPUTexture* t)
|
|||
t->SetState(GPUTexture::State::Invalidated);
|
||||
}
|
||||
|
||||
bool GPUDevice::CreateDevice(const std::string_view& adapter, bool debug_device)
|
||||
bool GPUDevice::CreateDevice(const std::string_view& adapter)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
|
@ -811,6 +812,13 @@ std::string GPUDevice::GetShaderDumpPath(const std::string_view& name)
|
|||
return Path::Combine(EmuFolders::Dumps, name);
|
||||
}
|
||||
|
||||
std::array<float, 4> GPUDevice::RGBA8ToFloat(u32 rgba)
|
||||
{
|
||||
return std::array<float, 4>{static_cast<float>(rgba & 0xFF) / 255.0f, static_cast<float>((rgba >> 8) & 0xFF) / 255.0f,
|
||||
static_cast<float>((rgba >> 16) & 0xFF) / 255.0f,
|
||||
static_cast<float>((rgba >> 24) & 0xFF) / 255.0f};
|
||||
}
|
||||
|
||||
bool GPUDevice::UpdateImGuiFontTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
|
|
@ -447,6 +447,9 @@ public:
|
|||
/// Returns the directory bad shaders are saved to.
|
||||
static std::string GetShaderDumpPath(const std::string_view& name);
|
||||
|
||||
/// Converts a RGBA8 value to 4 floating-point values.
|
||||
static std::array<float, 4> RGBA8ToFloat(u32 rgba);
|
||||
|
||||
ALWAYS_INLINE const Features& GetFeatures() const { return m_features; }
|
||||
ALWAYS_INLINE u32 GetMaxTextureSize() const { return m_max_texture_size; }
|
||||
ALWAYS_INLINE u32 GetMaxMultisamples() const { return m_max_multisamples; }
|
||||
|
@ -489,7 +492,7 @@ public:
|
|||
|
||||
virtual bool SetPostProcessingChain(const std::string_view& config);
|
||||
|
||||
virtual std::string GetShaderCacheBaseName(const std::string_view& type, bool debug) const;
|
||||
virtual std::string GetShaderCacheBaseName(const std::string_view& type) const;
|
||||
|
||||
/// Call when the window size changes externally to recreate any resources.
|
||||
virtual void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale);
|
||||
|
@ -509,9 +512,9 @@ public:
|
|||
virtual void ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
||||
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
||||
u32 height);
|
||||
void ClearRenderTarget(GPUTexture* t, u32 c);
|
||||
void ClearDepth(GPUTexture* t, float d);
|
||||
void InvalidateRenderTarget(GPUTexture* t);
|
||||
virtual void ClearRenderTarget(GPUTexture* t, u32 c);
|
||||
virtual void ClearDepth(GPUTexture* t, float d);
|
||||
virtual void InvalidateRenderTarget(GPUTexture* t);
|
||||
|
||||
/// Framebuffer abstraction.
|
||||
virtual std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt = nullptr, u32 rt_layer = 0,
|
||||
|
@ -627,7 +630,7 @@ public:
|
|||
bool WriteScreenshotToFile(std::string filename, bool internal_resolution = false, bool compress_on_thread = false);
|
||||
|
||||
protected:
|
||||
virtual bool CreateDevice(const std::string_view& adapter, bool debug_device);
|
||||
virtual bool CreateDevice(const std::string_view& adapter);
|
||||
virtual void DestroyDevice();
|
||||
|
||||
virtual std::unique_ptr<GPUShader> CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data);
|
||||
|
@ -649,12 +652,13 @@ protected:
|
|||
|
||||
bool m_gpu_timing_enabled = false;
|
||||
bool m_vsync_enabled = false;
|
||||
bool m_debug_device = false;
|
||||
|
||||
private:
|
||||
ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast<bool>(m_cursor_texture); }
|
||||
ALWAYS_INLINE bool HasDisplayTexture() const { return (m_display_texture != nullptr); }
|
||||
|
||||
void OpenShaderCache(const std::string_view& base_path, bool debug);
|
||||
void OpenShaderCache(const std::string_view& base_path);
|
||||
bool CreateResources();
|
||||
void DestroyResources();
|
||||
|
||||
|
|
|
@ -208,6 +208,9 @@ public:
|
|||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ClearRenderTarget(GPUTexture* t, u32 c) override;
|
||||
void ClearDepth(GPUTexture* t, float d) override;
|
||||
void InvalidateRenderTarget(GPUTexture* t) override;
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt = nullptr, u32 rt_layer = 0, u32 rt_level = 0,
|
||||
GPUTexture* ds = nullptr, u32 ds_layer = 0,
|
||||
|
|
|
@ -1292,10 +1292,10 @@ void MetalDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 d
|
|||
{
|
||||
DebugAssert(src_level < src->GetLevels() && src_layer < src->GetLayers());
|
||||
DebugAssert((src_x + width) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipHeight(src_level));
|
||||
DebugAssert(dst_level < dst->GetLevels() && dst_layer < dst->GetLayers());
|
||||
DebugAssert((dst_x + width) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipHeight(dst_level));
|
||||
|
||||
MetalTexture* D = static_cast<MetalTexture*>(dst);
|
||||
MetalTexture* S = static_cast<MetalTexture*>(src);
|
||||
|
@ -1349,10 +1349,10 @@ void MetalDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
|
|||
#if 0
|
||||
DebugAssert(src_level < src->GetLevels() && src_layer < src->GetLayers());
|
||||
DebugAssert((src_x + width) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipHeight(src_level));
|
||||
DebugAssert(dst_level < dst->GetLevels() && dst_layer < dst->GetLayers());
|
||||
DebugAssert((dst_x + width) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipHeight(dst_level));
|
||||
DebugAssert(!dst->IsMultisampled() && src->IsMultisampled());
|
||||
|
||||
// DX11 can't resolve partial rects.
|
||||
|
|
|
@ -191,6 +191,27 @@ void OpenGLDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u
|
|||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void OpenGLDevice::ClearRenderTarget(GPUTexture* t, u32 c)
|
||||
{
|
||||
GPUDevice::ClearRenderTarget(t, c);
|
||||
if (m_current_framebuffer && m_current_framebuffer->GetRT() == t)
|
||||
CommitClear(m_current_framebuffer);
|
||||
}
|
||||
|
||||
void OpenGLDevice::ClearDepth(GPUTexture* t, float d)
|
||||
{
|
||||
GPUDevice::ClearDepth(t, d);
|
||||
if (m_current_framebuffer && m_current_framebuffer->GetDS() == t)
|
||||
CommitClear(m_current_framebuffer);
|
||||
}
|
||||
|
||||
void OpenGLDevice::InvalidateRenderTarget(GPUTexture* t)
|
||||
{
|
||||
GPUDevice::InvalidateRenderTarget(t);
|
||||
if (m_current_framebuffer && (m_current_framebuffer->GetRT() == t || m_current_framebuffer->GetDS() == t))
|
||||
CommitClear(m_current_framebuffer);
|
||||
}
|
||||
|
||||
void OpenGLDevice::PushDebugGroup(const char* fmt, ...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
|
@ -268,7 +289,7 @@ bool OpenGLDevice::HasSurface() const
|
|||
return m_window_info.type != WindowInfo::Type::Surfaceless;
|
||||
}
|
||||
|
||||
bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool debug_device)
|
||||
bool OpenGLDevice::CreateDevice(const std::string_view& adapter)
|
||||
{
|
||||
m_gl_context = GL::Context::Create(m_window_info);
|
||||
if (!m_gl_context)
|
||||
|
@ -307,7 +328,7 @@ bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool debug_devi
|
|||
|
||||
Log_VerbosePrintf("Using PBO for uploads: %s", OpenGLTexture::s_use_pbo_for_uploads ? "yes" : "no");
|
||||
|
||||
if (debug_device && GLAD_GL_KHR_debug)
|
||||
if (m_debug_device && GLAD_GL_KHR_debug)
|
||||
{
|
||||
if (m_gl_context->IsGLES())
|
||||
glDebugMessageCallbackKHR(GLDebugCallback, nullptr);
|
||||
|
@ -493,9 +514,9 @@ void OpenGLDevice::DestroySurface()
|
|||
Log_ErrorPrintf("Failed to switch to surfaceless");
|
||||
}
|
||||
|
||||
std::string OpenGLDevice::GetShaderCacheBaseName(const std::string_view& type, bool debug) const
|
||||
std::string OpenGLDevice::GetShaderCacheBaseName(const std::string_view& type) const
|
||||
{
|
||||
return fmt::format("opengl_{}{}", type, debug ? "_debug" : "");
|
||||
return fmt::format("opengl_{}{}", type, m_debug_device ? "_debug" : "");
|
||||
}
|
||||
|
||||
bool OpenGLDevice::CreateBuffers()
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
AdapterAndModeList GetAdapterAndModeList() override;
|
||||
|
||||
std::string GetShaderCacheBaseName(const std::string_view& type, bool debug) const override;
|
||||
std::string GetShaderCacheBaseName(const std::string_view& type) const override;
|
||||
|
||||
std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||
GPUTexture::Type type, GPUTexture::Format format,
|
||||
|
@ -64,6 +64,9 @@ public:
|
|||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ClearRenderTarget(GPUTexture* t, u32 c) override;
|
||||
void ClearDepth(GPUTexture* t, float d) override;
|
||||
void InvalidateRenderTarget(GPUTexture* t) override;
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt = nullptr, u32 rt_layer = 0, u32 rt_level = 0,
|
||||
GPUTexture* ds = nullptr, u32 ds_layer = 0,
|
||||
|
@ -134,7 +137,7 @@ protected:
|
|||
OpenGLPipeline::VertexArrayCache m_vao_cache;
|
||||
OpenGLPipeline::ProgramCache m_program_cache;
|
||||
|
||||
bool CreateDevice(const std::string_view& adapter, bool debug_device) override;
|
||||
bool CreateDevice(const std::string_view& adapter) override;
|
||||
void DestroyDevice() override;
|
||||
|
||||
bool CreateBuffers();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "gpu_hw.h"
|
||||
|
@ -182,7 +182,7 @@ bool GPU_HW::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
|
|||
}
|
||||
|
||||
g_gpu_device->CopyTextureRegion(m_vram_texture.get(), 0, 0, 0, 0, tex, 0, 0, 0, 0, tex->GetWidth(),
|
||||
tex->GetHeight());
|
||||
tex->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -202,7 +202,7 @@ bool GPU_HW::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
|
|||
}
|
||||
|
||||
g_gpu_device->CopyTextureRegion(tex, 0, 0, 0, 0, m_vram_texture.get(), 0, 0, 0, 0, tex->GetWidth(),
|
||||
tex->GetHeight());
|
||||
tex->GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,37 +227,6 @@ void GPU_HW::RestoreGraphicsAPIState()
|
|||
}
|
||||
|
||||
void GPU_HW::UpdateSettings()
|
||||
{
|
||||
// TODO: Merge UpdateHWSettings() into here.
|
||||
bool framebuffer_changed, shaders_changed;
|
||||
UpdateHWSettings(&framebuffer_changed, &shaders_changed);
|
||||
|
||||
if (framebuffer_changed)
|
||||
{
|
||||
RestoreGraphicsAPIState();
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
g_gpu_device->ClearDisplayTexture();
|
||||
CreateBuffers();
|
||||
}
|
||||
|
||||
if (shaders_changed)
|
||||
{
|
||||
DestroyPipelines();
|
||||
if (!CompilePipelines())
|
||||
Panic("Failed to recompile pipelnes.");
|
||||
}
|
||||
|
||||
if (framebuffer_changed)
|
||||
{
|
||||
RestoreGraphicsAPIState();
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr, false, false);
|
||||
UpdateDepthBufferFromMaskBit();
|
||||
UpdateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Merge into UpdateSettings()
|
||||
void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
|
||||
{
|
||||
const u32 resolution_scale = CalculateResolutionScale();
|
||||
const u32 multisamples = std::min(m_max_multisamples, g_settings.gpu_multisamples);
|
||||
|
@ -266,9 +235,9 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
|
|||
const bool use_uv_limits = ShouldUseUVLimits();
|
||||
const bool disable_color_perspective = m_supports_disable_color_perspective && ShouldDisableColorPerspective();
|
||||
|
||||
*framebuffer_changed =
|
||||
const bool framebuffer_changed =
|
||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode);
|
||||
*shaders_changed =
|
||||
const bool shaders_changed =
|
||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples ||
|
||||
m_true_color != g_settings.gpu_true_color || m_per_sample_shading != per_sample_shading ||
|
||||
m_scaled_dithering != g_settings.gpu_scaled_dithering || m_texture_filtering != g_settings.gpu_texture_filter ||
|
||||
|
@ -301,6 +270,15 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
|
|||
}
|
||||
}
|
||||
|
||||
// Back up VRAM if we're recreating the framebuffer.
|
||||
if (framebuffer_changed)
|
||||
{
|
||||
RestoreGraphicsAPIState();
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
g_gpu_device->ClearDisplayTexture();
|
||||
DestroyBuffers();
|
||||
}
|
||||
|
||||
m_resolution_scale = resolution_scale;
|
||||
m_multisamples = multisamples;
|
||||
m_per_sample_shading = per_sample_shading;
|
||||
|
@ -326,6 +304,25 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
|
|||
UpdateSoftwareRenderer(true);
|
||||
|
||||
PrintSettingsToLog();
|
||||
|
||||
if (shaders_changed)
|
||||
{
|
||||
DestroyPipelines();
|
||||
if (!CompilePipelines())
|
||||
Panic("Failed to recompile pipelnes.");
|
||||
}
|
||||
|
||||
if (framebuffer_changed)
|
||||
{
|
||||
// TODO: weird vram loss when rapidly changing resolutions
|
||||
if (!CreateBuffers())
|
||||
Panic("Failed to recreate buffers.");
|
||||
|
||||
RestoreGraphicsAPIState();
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr, false, false);
|
||||
UpdateDepthBufferFromMaskBit();
|
||||
UpdateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
u32 GPU_HW::CalculateResolutionScale() const
|
||||
|
@ -426,17 +423,17 @@ bool GPU_HW::CreateBuffers()
|
|||
const u8 samples = static_cast<u8>(m_multisamples);
|
||||
|
||||
if (!(m_vram_texture = g_gpu_device->CreateTexture(texture_width, texture_height, 1, 1, samples,
|
||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
||||
!(m_vram_depth_texture = g_gpu_device->CreateTexture(texture_width, texture_height, 1, 1, samples,
|
||||
GPUTexture::Type::DepthStencil, VRAM_DS_FORMAT)) ||
|
||||
GPUTexture::Type::DepthStencil, VRAM_DS_FORMAT)) ||
|
||||
!(m_vram_read_texture = g_gpu_device->CreateTexture(texture_width, texture_height, 1, 1, 1,
|
||||
GPUTexture::Type::Texture, VRAM_RT_FORMAT)) ||
|
||||
GPUTexture::Type::Texture, VRAM_RT_FORMAT)) ||
|
||||
!(m_display_texture = g_gpu_device->CreateTexture(
|
||||
((m_downsample_mode == GPUDownsampleMode::Adaptive) ? VRAM_WIDTH : GPU_MAX_DISPLAY_WIDTH) *
|
||||
m_resolution_scale,
|
||||
GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale, 1, 1, 1, GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
||||
!(m_vram_readback_texture = g_gpu_device->CreateTexture(VRAM_WIDTH / 2, VRAM_HEIGHT, 1, 1, 1,
|
||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)))
|
||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -460,7 +457,7 @@ bool GPU_HW::CreateBuffers()
|
|||
|
||||
// TODO: check caps
|
||||
if (!(m_vram_upload_buffer = g_gpu_device->CreateTextureBuffer(GPUTextureBuffer::Format::R16UI,
|
||||
VRAM_UPDATE_TEXTURE_BUFFER_SIZE / sizeof(u16))))
|
||||
VRAM_UPDATE_TEXTURE_BUFFER_SIZE / sizeof(u16))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -505,7 +502,7 @@ bool GPU_HW::CreateBuffers()
|
|||
if (m_downsample_mode == GPUDownsampleMode::Box)
|
||||
{
|
||||
if (!(m_downsample_texture = g_gpu_device->CreateTexture(VRAM_WIDTH, VRAM_HEIGHT, 1, 1, 1,
|
||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
||||
!(m_downsample_framebuffer = g_gpu_device->CreateFramebuffer(m_downsample_texture.get())))
|
||||
{
|
||||
return false;
|
||||
|
@ -780,8 +777,8 @@ bool GPU_HW::CompilePipelines()
|
|||
// TODO: SSBO path here...
|
||||
{
|
||||
const bool use_ssbo = features.texture_buffers_emulated_with_ssbo;
|
||||
std::unique_ptr<GPUShader> fs = g_gpu_device->CreateShader(
|
||||
GPUShaderStage::Fragment, shadergen.GenerateVRAMWriteFragmentShader(use_ssbo));
|
||||
std::unique_ptr<GPUShader> fs =
|
||||
g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GenerateVRAMWriteFragmentShader(use_ssbo));
|
||||
if (!fs)
|
||||
return false;
|
||||
|
||||
|
@ -1002,14 +999,14 @@ void GPU_HW::UpdateVRAMReadTexture()
|
|||
if (m_vram_texture->IsMultisampled())
|
||||
{
|
||||
g_gpu_device->ResolveTextureRegion(m_vram_read_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
m_vram_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
scaled_rect.GetWidth(), scaled_rect.GetHeight());
|
||||
m_vram_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
scaled_rect.GetWidth(), scaled_rect.GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
g_gpu_device->CopyTextureRegion(m_vram_read_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
m_vram_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
scaled_rect.GetWidth(), scaled_rect.GetHeight());
|
||||
m_vram_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
scaled_rect.GetWidth(), scaled_rect.GetHeight());
|
||||
}
|
||||
|
||||
m_renderer_stats.num_vram_read_texture_updates++;
|
||||
|
@ -1844,7 +1841,7 @@ bool GPU_HW::BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u3
|
|||
|
||||
if (!(m_vram_replacement_texture =
|
||||
g_gpu_device->CreateTexture(tex->GetWidth(), tex->GetHeight(), 1, 1, 1, GPUTexture::Type::Texture,
|
||||
GPUTexture::Format::RGBA8, tex->GetPixels(), tex->GetPitch(), true)))
|
||||
GPUTexture::Format::RGBA8, tex->GetPixels(), tex->GetPitch(), true)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2053,13 +2050,12 @@ void GPU_HW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
Common::Rectangle<u32>::FromExtents(x, y, width, height).Clamped(0, 0, VRAM_WIDTH, VRAM_HEIGHT));
|
||||
|
||||
g_gpu_device->SetPipeline(m_vram_fill_pipelines[BoolToUInt8(IsVRAMFillOversized(x, y, width, height))]
|
||||
[BoolToUInt8(IsInterlacedRenderingEnabled())]
|
||||
.get());
|
||||
[BoolToUInt8(IsInterlacedRenderingEnabled())]
|
||||
.get());
|
||||
|
||||
const Common::Rectangle<u32> bounds(GetVRAMTransferBounds(x, y, width, height));
|
||||
g_gpu_device->SetViewportAndScissor(bounds.left * m_resolution_scale, bounds.top * m_resolution_scale,
|
||||
bounds.GetWidth() * m_resolution_scale,
|
||||
bounds.GetHeight() * m_resolution_scale);
|
||||
bounds.GetWidth() * m_resolution_scale, bounds.GetHeight() * m_resolution_scale);
|
||||
|
||||
const VRAMFillUBOData uniforms = GetVRAMFillUBOData(x, y, width, height, color);
|
||||
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
||||
|
@ -2089,11 +2085,12 @@ void GPU_HW::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
|||
g_gpu_device->SetViewportAndScissor(0, 0, encoded_width, encoded_height);
|
||||
g_gpu_device->PushUniformBuffer(uniforms, sizeof(uniforms));
|
||||
g_gpu_device->Draw(3, 0);
|
||||
m_vram_readback_texture->MakeReadyForSampling();
|
||||
|
||||
// Stage the readback and copy it into our shadow buffer.
|
||||
g_gpu_device->DownloadTexture(m_vram_readback_texture.get(), 0, 0, encoded_width, encoded_height,
|
||||
reinterpret_cast<u32*>(&m_vram_shadow[copy_rect.top * VRAM_WIDTH + copy_rect.left]),
|
||||
VRAM_WIDTH * sizeof(u16));
|
||||
reinterpret_cast<u32*>(&m_vram_shadow[copy_rect.top * VRAM_WIDTH + copy_rect.left]),
|
||||
VRAM_WIDTH * sizeof(u16));
|
||||
|
||||
RestoreGraphicsAPIState();
|
||||
}
|
||||
|
@ -2133,8 +2130,7 @@ void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, b
|
|||
|
||||
// the viewport should already be set to the full vram, so just adjust the scissor
|
||||
const Common::Rectangle<u32> scaled_bounds = bounds * m_resolution_scale;
|
||||
g_gpu_device->SetScissor(scaled_bounds.left, scaled_bounds.top, scaled_bounds.GetWidth(),
|
||||
scaled_bounds.GetHeight());
|
||||
g_gpu_device->SetScissor(scaled_bounds.left, scaled_bounds.top, scaled_bounds.GetWidth(), scaled_bounds.GetHeight());
|
||||
g_gpu_device->SetPipeline(m_vram_write_pipelines[BoolToUInt8(check_mask && !m_pgxp_depth_buffer)].get());
|
||||
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
||||
g_gpu_device->SetTextureBuffer(0, m_vram_upload_buffer.get());
|
||||
|
@ -2161,7 +2157,7 @@ void GPU_HW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32
|
|||
// VRAM read texture should already be bound.
|
||||
const Common::Rectangle<u32> dst_bounds_scaled(dst_bounds * m_resolution_scale);
|
||||
g_gpu_device->SetViewportAndScissor(dst_bounds_scaled.left, dst_bounds_scaled.top, dst_bounds_scaled.GetWidth(),
|
||||
dst_bounds_scaled.GetHeight());
|
||||
dst_bounds_scaled.GetHeight());
|
||||
g_gpu_device->SetPipeline(
|
||||
m_vram_copy_pipelines[BoolToUInt8(m_GPUSTAT.check_mask_before_draw && !m_pgxp_depth_buffer)].get());
|
||||
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
||||
|
@ -2193,8 +2189,8 @@ void GPU_HW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32
|
|||
}
|
||||
|
||||
g_gpu_device->CopyTextureRegion(m_vram_texture.get(), dst_x * m_resolution_scale, dst_y * m_resolution_scale, 0, 0,
|
||||
m_vram_read_texture.get(), src_x * m_resolution_scale, src_y * m_resolution_scale,
|
||||
0, 0, width * m_resolution_scale, height * m_resolution_scale);
|
||||
m_vram_read_texture.get(), src_x * m_resolution_scale, src_y * m_resolution_scale, 0,
|
||||
0, width * m_resolution_scale, height * m_resolution_scale);
|
||||
}
|
||||
|
||||
void GPU_HW::DispatchRenderCommand()
|
||||
|
@ -2352,23 +2348,23 @@ void GPU_HW::UpdateDisplay()
|
|||
{
|
||||
UpdateVRAMReadTexture();
|
||||
g_gpu_device->SetDisplayTexture(m_vram_read_texture.get(), 0, 0, m_vram_read_texture->GetWidth(),
|
||||
m_vram_read_texture->GetHeight());
|
||||
m_vram_read_texture->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
g_gpu_device->SetDisplayTexture(m_vram_texture.get(), 0, 0, m_vram_texture->GetWidth(),
|
||||
m_vram_texture->GetHeight());
|
||||
m_vram_texture->GetHeight());
|
||||
}
|
||||
|
||||
g_gpu_device->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_gpu_device->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
|
||||
const u32 resolution_scale = m_GPUSTAT.display_area_color_depth_24 ? 1 : m_resolution_scale;
|
||||
const u32 vram_offset_x = m_crtc_state.display_vram_left;
|
||||
|
@ -2398,7 +2394,7 @@ void GPU_HW::UpdateDisplay()
|
|||
else
|
||||
{
|
||||
g_gpu_device->SetDisplayTexture(m_vram_texture.get(), scaled_vram_offset_x, scaled_vram_offset_y,
|
||||
scaled_display_width, scaled_display_height);
|
||||
scaled_display_width, scaled_display_height);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -20,7 +20,7 @@ class GPU_SW_Backend;
|
|||
struct GPUBackendCommand;
|
||||
struct GPUBackendDrawCommand;
|
||||
|
||||
class GPU_HW : public GPU
|
||||
class GPU_HW final : public GPU
|
||||
{
|
||||
public:
|
||||
enum class BatchRenderMode : u8
|
||||
|
@ -209,8 +209,6 @@ protected:
|
|||
static_cast<float>(rgba >> 24) * (1.0f / 255.0f));
|
||||
}
|
||||
|
||||
void UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed);
|
||||
|
||||
bool CreateBuffers();
|
||||
void ClearFramebuffer();
|
||||
void DestroyBuffers();
|
||||
|
@ -461,8 +459,8 @@ protected:
|
|||
|
||||
std::unique_ptr<GPUTexture> m_downsample_texture;
|
||||
std::unique_ptr<GPUFramebuffer> m_downsample_framebuffer;
|
||||
//std::unique_ptr<GPUTexture> m_downsample_weight_texture;
|
||||
//std::unique_ptr<GPUFramebuffer> m_downsample_weight_framebuffer;
|
||||
// std::unique_ptr<GPUTexture> m_downsample_weight_texture;
|
||||
// std::unique_ptr<GPUFramebuffer> m_downsample_weight_framebuffer;
|
||||
std::unique_ptr<GPUPipeline> m_downsample_first_pass_pipeline;
|
||||
std::unique_ptr<GPUPipeline> m_downsample_mid_pass_pipeline;
|
||||
std::unique_ptr<GPUPipeline> m_downsample_blur_pass_pipeline;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#if 0
|
||||
|
||||
#include "gpu_hw_d3d12.h"
|
||||
#include "common/align.h"
|
||||
#include "common/assert.h"
|
||||
|
@ -1165,3 +1167,5 @@ std::unique_ptr<GPU> GPU::CreateHardwareD3D12Renderer()
|
|||
return gpu;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -2,6 +2,8 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#if 0
|
||||
#include "common/dimensional_array.h"
|
||||
#include "gpu/d3d12/staging_texture.h"
|
||||
#include "gpu/d3d12/stream_buffer.h"
|
||||
|
@ -101,3 +103,5 @@ private:
|
|||
D3D12::Texture m_vram_write_replacement_texture;
|
||||
D3D12::StreamBuffer m_texture_replacment_stream_buffer;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#if 0
|
||||
|
||||
#include "gpu_hw_vulkan.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/log.h"
|
||||
|
@ -1858,3 +1860,5 @@ void GPU_HW_Vulkan::DownsampleFramebufferAdaptive(Vulkan::Texture& source, u32 l
|
|||
|
||||
g_gpu_device->SetDisplayTexture(&m_display_texture, left, top, width, height);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,6 +2,9 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#if 0
|
||||
|
||||
#include "common/dimensional_array.h"
|
||||
#include "gpu/vulkan/stream_buffer.h"
|
||||
#include "gpu/vulkan/texture.h"
|
||||
|
@ -155,3 +158,5 @@ private:
|
|||
VkPipeline m_downsample_blur_pass_pipeline = VK_NULL_HANDLE;
|
||||
VkPipeline m_downsample_composite_pass_pipeline = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -458,8 +458,10 @@ void EmuThread::startFullscreenUI()
|
|||
setInitialState(s_start_fullscreen_ui_fullscreen ? std::optional<bool>(true) : std::optional<bool>());
|
||||
m_run_fullscreen_ui = true;
|
||||
|
||||
if (!Host::CreateGPUDevice(Settings::GetRenderAPIForRenderer(g_settings.gpu_renderer)))
|
||||
if (!Host::CreateGPUDevice(Settings::GetRenderAPIForRenderer(g_settings.gpu_renderer)) || !FullscreenUI::Initialize())
|
||||
{
|
||||
Host::ReleaseGPUDevice();
|
||||
Host::ReleaseRenderWindow();
|
||||
m_run_fullscreen_ui = false;
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue