FBs don't need multi-level now
This commit is contained in:
parent
df789e8df9
commit
febf864220
|
@ -510,7 +510,6 @@ void D3D11Device::SetFeatures()
|
|||
|
||||
m_features.dual_source_blend = true;
|
||||
m_features.per_sample_shading = (feature_level >= D3D_FEATURE_LEVEL_10_1);
|
||||
m_features.mipmapped_render_targets = true;
|
||||
m_features.noperspective_interpolation = true;
|
||||
m_features.supports_texture_buffers = true;
|
||||
m_features.texture_buffers_emulated_with_ssbo = false;
|
||||
|
@ -1153,121 +1152,29 @@ void D3D11Framebuffer::CommitClear(ID3D11DeviceContext1* context)
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> D3D11Device::CreateFramebuffer(GPUTexture* rt, u32 rt_layer, u32 rt_level,
|
||||
GPUTexture* ds, u32 ds_layer, u32 ds_level)
|
||||
std::unique_ptr<GPUFramebuffer> D3D11Device::CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds)
|
||||
{
|
||||
DebugAssert((rt_or_ds || ds) && (!rt_or_ds || rt_or_ds->IsRenderTarget() || (rt_or_ds->IsDepthStencil() && !ds)));
|
||||
D3D11Texture* RT = static_cast<D3D11Texture*>((rt_or_ds && rt_or_ds->IsDepthStencil()) ? nullptr : rt_or_ds);
|
||||
D3D11Texture* DS = static_cast<D3D11Texture*>((rt_or_ds && rt_or_ds->IsDepthStencil()) ? rt_or_ds : ds);
|
||||
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
if (RT)
|
||||
{
|
||||
rtv = RT->GetD3DRTV();
|
||||
Assert(rtv);
|
||||
}
|
||||
|
||||
ComPtr<ID3D11DepthStencilView> dsv;
|
||||
HRESULT hr;
|
||||
|
||||
Assert(rt || ds);
|
||||
Assert(!rt || (rt_layer < rt->GetLayers() && rt_level < rt->GetLevels()));
|
||||
Assert(!ds || (ds_layer < ds->GetLevels() && ds_level < ds->GetLevels()));
|
||||
Assert(!rt || !ds ||
|
||||
(rt->GetMipWidth(rt_level) == ds->GetMipWidth(ds_level) &&
|
||||
rt->GetMipHeight(rt_level) == ds->GetMipHeight(ds_level)));
|
||||
|
||||
if (rt)
|
||||
if (DS)
|
||||
{
|
||||
if (rt_layer == 0 && rt_level == 0)
|
||||
{
|
||||
rtv = static_cast<D3D11Texture*>(rt)->GetD3DRTV();
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = {};
|
||||
rtv_desc.Format = static_cast<D3D11Texture*>(rt)->GetDXGIFormat();
|
||||
if (rt->IsMultisampled())
|
||||
{
|
||||
Assert(rt_level == 0);
|
||||
if (rt->GetLayers() > 1)
|
||||
{
|
||||
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
|
||||
rtv_desc.Texture2DMSArray.ArraySize = rt->GetLayers();
|
||||
rtv_desc.Texture2DMSArray.FirstArraySlice = rt_layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rt->GetLayers() > 1)
|
||||
{
|
||||
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||
rtv_desc.Texture2DArray.ArraySize = rt->GetLayers();
|
||||
rtv_desc.Texture2DArray.FirstArraySlice = rt_layer;
|
||||
rtv_desc.Texture2DArray.MipSlice = rt_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtv_desc.Texture2D.MipSlice = rt_level;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_device->CreateRenderTargetView(static_cast<D3D11Texture*>(rt)->GetD3DTexture(), &rtv_desc,
|
||||
rtv.GetAddressOf())))
|
||||
{
|
||||
Log_ErrorPrintf("CreateRenderTargetView() failed: %08X", hr);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
dsv = DS->GetD3DDSV();
|
||||
Assert(dsv);
|
||||
}
|
||||
|
||||
if (ds)
|
||||
{
|
||||
if (ds_layer == 0 && ds_level == 0)
|
||||
{
|
||||
dsv = static_cast<D3D11Texture*>(ds)->GetD3DDSV();
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = {};
|
||||
dsv_desc.Format = static_cast<D3D11Texture*>(ds)->GetDXGIFormat();
|
||||
if (ds->IsMultisampled())
|
||||
{
|
||||
Assert(rt_level == 0);
|
||||
if (ds->GetLayers() > 1)
|
||||
{
|
||||
dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
|
||||
dsv_desc.Texture2DMSArray.ArraySize = ds->GetLayers();
|
||||
dsv_desc.Texture2DMSArray.FirstArraySlice = rt_layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ds->GetLayers() > 1)
|
||||
{
|
||||
dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
|
||||
dsv_desc.Texture2DArray.ArraySize = ds->GetLayers();
|
||||
dsv_desc.Texture2DArray.FirstArraySlice = rt_layer;
|
||||
dsv_desc.Texture2DArray.MipSlice = rt_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||
dsv_desc.Texture2D.MipSlice = rt_level;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr = m_device->CreateDepthStencilView(static_cast<D3D11Texture*>(ds)->GetD3DTexture(), &dsv_desc,
|
||||
dsv.GetAddressOf())))
|
||||
{
|
||||
Log_ErrorPrintf("CreateDepthStencilView() failed: %08X", hr);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::unique_ptr<GPUFramebuffer>(
|
||||
new D3D11Framebuffer(rt, ds, rt ? rt->GetMipWidth(rt_level) : ds->GetMipWidth(ds_level),
|
||||
rt ? rt->GetMipHeight(rt_level) : ds->GetMipHeight(ds_level), std::move(rtv), std::move(dsv)));
|
||||
return std::unique_ptr<GPUFramebuffer>(new D3D11Framebuffer(RT, DS, RT ? RT->GetWidth() : DS->GetWidth(),
|
||||
RT ? RT->GetHeight() : DS->GetHeight(), std::move(rtv),
|
||||
std::move(dsv)));
|
||||
}
|
||||
|
||||
D3D11Sampler::D3D11Sampler(ComPtr<ID3D11SamplerState> ss) : m_ss(std::move(ss))
|
||||
|
@ -1854,13 +1761,8 @@ bool D3D11Texture::Create(ID3D11Device* device, u32 width, u32 height, u32 layer
|
|||
Format format, const void* initial_data /* = nullptr */, u32 initial_data_stride /* = 0 */,
|
||||
bool dynamic /* = false */)
|
||||
{
|
||||
if (width > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION || height > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION ||
|
||||
layers > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION || (layers > 1 && samples > 1))
|
||||
{
|
||||
Log_ErrorPrintf("Texture bounds (%ux%ux%u, %u mips, %u samples) are too large", width, height, layers, levels,
|
||||
samples);
|
||||
if (!ValidateConfig(width, height, layers, layers, samples, type, format))
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 bind_flags = 0;
|
||||
switch (type)
|
||||
|
|
|
@ -306,9 +306,7 @@ public:
|
|||
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,
|
||||
u32 ds_level = 0) override;
|
||||
std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds = nullptr) override;
|
||||
|
||||
std::unique_ptr<GPUShader> CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data) override;
|
||||
std::unique_ptr<GPUShader> CreateShaderFromSource(GPUShaderStage stage, const std::string_view& source,
|
||||
|
|
|
@ -273,13 +273,6 @@ void GPUDevice::Destroy()
|
|||
DestroyDevice();
|
||||
}
|
||||
|
||||
bool GPUDevice::UpdateWindow()
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GPUDevice::SupportsExclusiveFullscreen() const
|
||||
{
|
||||
return false;
|
||||
|
@ -419,18 +412,6 @@ bool GPUDevice::SetPostProcessingChain(const std::string_view& config)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string GPUDevice::GetShaderCacheBaseName(const std::string_view& type) const
|
||||
{
|
||||
Panic("Not implemented");
|
||||
return {};
|
||||
}
|
||||
|
||||
void GPUDevice::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::RenderImGui()
|
||||
{
|
||||
GL_SCOPE("RenderImGui");
|
||||
|
@ -483,30 +464,6 @@ void GPUDevice::RenderImGui()
|
|||
}
|
||||
}
|
||||
|
||||
void GPUDevice::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_ptr, u32* map_space, u32* map_base_vertex)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::UnmapIndexBuffer(u32 used_index_count)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::UploadVertexBuffer(const void* vertices, u32 vertex_size, u32 vertex_count, u32* base_vertex)
|
||||
{
|
||||
void* map;
|
||||
|
@ -525,25 +482,6 @@ void GPUDevice::UploadIndexBuffer(const u16* indices, u32 index_count, u32* base
|
|||
UnmapIndexBuffer(index_count);
|
||||
}
|
||||
|
||||
void GPUDevice::PushUniformBuffer(const void* data, u32 data_size)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void* GPUDevice::MapUniformBuffer(u32 size)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GPUDevice::UnmapUniformBuffer(u32 size)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::UploadUniformBuffer(const void* data, u32 data_size)
|
||||
{
|
||||
void* map = MapUniformBuffer(data_size);
|
||||
|
@ -551,89 +489,12 @@ void GPUDevice::UploadUniformBuffer(const void* data, u32 data_size)
|
|||
UnmapUniformBuffer(data_size);
|
||||
}
|
||||
|
||||
void GPUDevice::SetFramebuffer(GPUFramebuffer* fb)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::SetPipeline(GPUPipeline* pipeline)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
// GL needs to invert if writing to the window framebuffer
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::SetViewportAndScissor(s32 x, s32 y, s32 width, s32 height)
|
||||
{
|
||||
SetViewport(x, y, width, height);
|
||||
SetScissor(x, y, width, height);
|
||||
}
|
||||
|
||||
void GPUDevice::Draw(u32 base_vertex, u32 vertex_count)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::DrawIndexed(u32 base_index, u32 index_count, u32 base_vertex)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
bool GPUDevice::BeginPresent(bool skip_present)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPUDevice::EndPresent()
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::CopyTextureRegion(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)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::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)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::ClearRenderTarget(GPUTexture* t, u32 c)
|
||||
{
|
||||
t->SetClearColor(c);
|
||||
|
@ -649,75 +510,6 @@ void GPUDevice::InvalidateRenderTarget(GPUTexture* t)
|
|||
t->SetState(GPUTexture::State::Invalidated);
|
||||
}
|
||||
|
||||
bool GPUDevice::CreateDevice(const std::string_view& adapter)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPUDevice::DestroyDevice()
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUShader> GPUDevice::CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUShader> GPUDevice::CreateShaderFromSource(GPUShaderStage stage, const std::string_view& source,
|
||||
std::vector<u8>* out_binary /* = nullptr */)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUPipeline> GPUDevice::CreatePipeline(const GPUPipeline::GraphicsConfig& config)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return {};
|
||||
}
|
||||
|
||||
void GPUDevice::PushDebugGroup(const char* fmt, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void GPUDevice::PopDebugGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void GPUDevice::InsertDebugMessage(const char* fmt, ...)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUSampler> GPUDevice::CreateSampler(const GPUSampler::Config& config)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUTextureBuffer> GPUDevice::CreateTextureBuffer(GPUTextureBuffer::Format format, u32 size_in_elements)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> GPUDevice::CreateFramebuffer(GPUTexture* rt, u32 rt_layer, u32 rt_level, GPUTexture* ds,
|
||||
u32 ds_layer, u32 ds_level)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUShader> GPUDevice::CreateShader(GPUShaderStage stage, const std::string_view& source)
|
||||
{
|
||||
std::unique_ptr<GPUShader> shader;
|
||||
|
@ -1646,7 +1438,8 @@ std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
|
|||
{
|
||||
#ifdef WITH_VULKAN
|
||||
case RenderAPI::Vulkan:
|
||||
return std::make_unique<VulkanGPUDevice>();
|
||||
// return std::make_unique<VulkanGPUDevice>();
|
||||
return {};
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENGL
|
||||
|
@ -1657,7 +1450,8 @@ std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
|
|||
|
||||
#ifdef _WIN32
|
||||
case RenderAPI::D3D12:
|
||||
return std::make_unique<D3D12GPUDevice>();
|
||||
// return std::make_unique<D3D12GPUDevice>();
|
||||
return {};
|
||||
|
||||
case RenderAPI::D3D11:
|
||||
return std::make_unique<D3D11Device>();
|
||||
|
|
|
@ -416,7 +416,6 @@ public:
|
|||
{
|
||||
bool dual_source_blend : 1;
|
||||
bool per_sample_shading : 1;
|
||||
bool mipmapped_render_targets : 1;
|
||||
bool noperspective_interpolation : 1;
|
||||
bool supports_texture_buffers : 1;
|
||||
bool texture_buffers_emulated_with_ssbo : 1;
|
||||
|
@ -488,83 +487,81 @@ public:
|
|||
|
||||
virtual bool HasSurface() const = 0;
|
||||
virtual void DestroySurface() = 0;
|
||||
virtual bool UpdateWindow();
|
||||
virtual bool UpdateWindow() = 0;
|
||||
|
||||
virtual bool SupportsExclusiveFullscreen() const;
|
||||
virtual AdapterAndModeList GetAdapterAndModeList() = 0;
|
||||
|
||||
virtual bool SetPostProcessingChain(const std::string_view& config);
|
||||
|
||||
virtual std::string GetShaderCacheBaseName(const std::string_view& type) const;
|
||||
virtual std::string GetShaderCacheBaseName(const std::string_view& type) const = 0;
|
||||
|
||||
/// 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);
|
||||
virtual void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) = 0;
|
||||
|
||||
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
|
||||
virtual std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||
GPUTexture::Type type, GPUTexture::Format format,
|
||||
const void* data = nullptr, u32 data_stride = 0,
|
||||
bool dynamic = false) = 0;
|
||||
virtual std::unique_ptr<GPUSampler> CreateSampler(const GPUSampler::Config& config);
|
||||
virtual std::unique_ptr<GPUTextureBuffer> CreateTextureBuffer(GPUTextureBuffer::Format format, u32 size_in_elements);
|
||||
virtual std::unique_ptr<GPUSampler> CreateSampler(const GPUSampler::Config& config) = 0;
|
||||
virtual std::unique_ptr<GPUTextureBuffer> CreateTextureBuffer(GPUTextureBuffer::Format format, u32 size_in_elements) = 0;
|
||||
|
||||
virtual bool DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||
u32 out_data_stride) = 0;
|
||||
virtual void CopyTextureRegion(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);
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) = 0;
|
||||
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);
|
||||
u32 height) = 0;
|
||||
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,
|
||||
u32 rt_level = 0, GPUTexture* ds = nullptr,
|
||||
u32 ds_layer = 0, u32 ds_level = 0);
|
||||
virtual std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds = nullptr) = 0;
|
||||
|
||||
/// Shader abstraction.
|
||||
// TODO: entry point? source format?
|
||||
std::unique_ptr<GPUShader> CreateShader(GPUShaderStage stage, const std::string_view& source);
|
||||
virtual std::unique_ptr<GPUPipeline> CreatePipeline(const GPUPipeline::GraphicsConfig& config);
|
||||
virtual std::unique_ptr<GPUPipeline> CreatePipeline(const GPUPipeline::GraphicsConfig& config) = 0;
|
||||
|
||||
/// Debug messaging.
|
||||
virtual void PushDebugGroup(const char* fmt, ...);
|
||||
virtual void PopDebugGroup();
|
||||
virtual void InsertDebugMessage(const char* fmt, ...);
|
||||
virtual void PushDebugGroup(const char* fmt, ...) = 0;
|
||||
virtual void PopDebugGroup() = 0;
|
||||
virtual void InsertDebugMessage(const char* fmt, ...) = 0;
|
||||
|
||||
/// Vertex/index buffer abstraction.
|
||||
virtual void MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_ptr, u32* map_space, u32* map_base_vertex);
|
||||
virtual void UnmapVertexBuffer(u32 vertex_size, u32 vertex_count);
|
||||
virtual void MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index);
|
||||
virtual void UnmapIndexBuffer(u32 used_size);
|
||||
virtual void MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_ptr, u32* map_space, u32* map_base_vertex) = 0;
|
||||
virtual void UnmapVertexBuffer(u32 vertex_size, u32 vertex_count) = 0;
|
||||
virtual void MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index) = 0;
|
||||
virtual void UnmapIndexBuffer(u32 used_size) = 0;
|
||||
|
||||
void UploadVertexBuffer(const void* vertices, u32 vertex_size, u32 vertex_count, u32* base_vertex);
|
||||
void UploadIndexBuffer(const DrawIndex* indices, u32 index_count, u32* base_index);
|
||||
|
||||
/// Uniform buffer abstraction.
|
||||
virtual void PushUniformBuffer(const void* data, u32 data_size);
|
||||
virtual void* MapUniformBuffer(u32 size);
|
||||
virtual void UnmapUniformBuffer(u32 size);
|
||||
virtual void PushUniformBuffer(const void* data, u32 data_size) = 0;
|
||||
virtual void* MapUniformBuffer(u32 size) = 0;
|
||||
virtual void UnmapUniformBuffer(u32 size) = 0;
|
||||
void UploadUniformBuffer(const void* data, u32 data_size);
|
||||
|
||||
/// Drawing setup abstraction.
|
||||
virtual void SetFramebuffer(GPUFramebuffer* fb);
|
||||
virtual void SetPipeline(GPUPipeline* pipeline);
|
||||
virtual void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler);
|
||||
virtual void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer);
|
||||
virtual void SetViewport(s32 x, s32 y, s32 width, s32 height);
|
||||
virtual void SetScissor(s32 x, s32 y, s32 width, s32 height);
|
||||
virtual void SetFramebuffer(GPUFramebuffer* fb) = 0;
|
||||
virtual void SetPipeline(GPUPipeline* pipeline) = 0;
|
||||
virtual void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) = 0;
|
||||
virtual void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) = 0;
|
||||
virtual void SetViewport(s32 x, s32 y, s32 width, s32 height) = 0;
|
||||
virtual void SetScissor(s32 x, s32 y, s32 width, s32 height) = 0;
|
||||
void SetViewportAndScissor(s32 x, s32 y, s32 width, s32 height);
|
||||
|
||||
// Drawing abstraction.
|
||||
virtual void Draw(u32 vertex_count, u32 base_vertex);
|
||||
virtual void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex);
|
||||
virtual void Draw(u32 vertex_count, u32 base_vertex) = 0;
|
||||
virtual void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) = 0;
|
||||
|
||||
/// Returns false if the window was completely occluded.
|
||||
virtual bool BeginPresent(bool skip_present);
|
||||
virtual void EndPresent();
|
||||
virtual bool BeginPresent(bool skip_present) = 0;
|
||||
virtual void EndPresent() = 0;
|
||||
bool Render(bool skip_present);
|
||||
|
||||
/// Renders the display with postprocessing to the specified image.
|
||||
|
@ -633,12 +630,12 @@ public:
|
|||
bool WriteScreenshotToFile(std::string filename, bool internal_resolution = false, bool compress_on_thread = false);
|
||||
|
||||
protected:
|
||||
virtual bool CreateDevice(const std::string_view& adapter);
|
||||
virtual void DestroyDevice();
|
||||
virtual bool CreateDevice(const std::string_view& adapter) = 0;
|
||||
virtual void DestroyDevice() = 0;
|
||||
|
||||
virtual std::unique_ptr<GPUShader> CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data);
|
||||
virtual std::unique_ptr<GPUShader> CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data) = 0;
|
||||
virtual std::unique_ptr<GPUShader> CreateShaderFromSource(GPUShaderStage stage, const std::string_view& source,
|
||||
std::vector<u8>* out_binary = nullptr);
|
||||
std::vector<u8>* out_binary = nullptr) = 0;
|
||||
|
||||
bool AcquireWindow(bool recreate_window);
|
||||
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "gpu_texture.h"
|
||||
#include "gpu_device.h"
|
||||
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
Log_SetChannel(GPUTexture);
|
||||
|
||||
GPUTexture::GPUTexture() = default;
|
||||
|
@ -54,6 +57,49 @@ bool GPUTexture::IsDepthFormat(Format format)
|
|||
return (format == Format::D16);
|
||||
}
|
||||
|
||||
bool GPUTexture::ValidateConfig(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type, Format format)
|
||||
{
|
||||
if (width > MAX_WIDTH || height > MAX_HEIGHT || layers > MAX_LAYERS || levels > MAX_LEVELS || samples > MAX_SAMPLES)
|
||||
{
|
||||
Log_ErrorPrintf("Invalid dimensions: %ux%ux%u %u %u.", width, height, layers, levels, samples);
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 max_texture_size = g_gpu_device->GetMaxTextureSize();
|
||||
if (width > max_texture_size || height > max_texture_size)
|
||||
{
|
||||
Log_ErrorPrintf("Texture width (%u) or height (%u) exceeds max texture size (%u).", width, height, max_texture_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 max_samples = g_gpu_device->GetMaxMultisamples();
|
||||
if (samples > max_samples)
|
||||
{
|
||||
Log_ErrorPrintf("Texture samples (%u) exceeds max samples (%u).", samples, max_samples);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (samples > 1 && levels > 1)
|
||||
{
|
||||
Log_ErrorPrintf("Multisampled textures can't have mip levels.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layers > 1 && type != Type::Texture)
|
||||
{
|
||||
Log_ErrorPrintf("Texture arrays are not supported on targets.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (levels > 1 && type != Type::Texture)
|
||||
{
|
||||
Log_ErrorPrintf("Mipmaps are not supported on targets.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPUTexture::ConvertTextureDataToRGBA8(u32 width, u32 height, std::vector<u32>& texture_data,
|
||||
u32& texture_data_stride, GPUTexture::Format format)
|
||||
{
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
|
||||
static u32 GetPixelSize(GPUTexture::Format format);
|
||||
static bool IsDepthFormat(GPUTexture::Format format);
|
||||
static bool ValidateConfig(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type, Format format);
|
||||
|
||||
static bool ConvertTextureDataToRGBA8(u32 width, u32 height, std::vector<u32>& texture_data, u32& texture_data_stride,
|
||||
GPUTexture::Format format);
|
||||
|
|
|
@ -212,9 +212,7 @@ public:
|
|||
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,
|
||||
u32 ds_level = 0) override;
|
||||
std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds = nullptr) override;
|
||||
|
||||
std::unique_ptr<GPUShader> CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data) override;
|
||||
std::unique_ptr<GPUShader> CreateShaderFromSource(GPUShaderStage stage, const std::string_view& source,
|
||||
|
|
|
@ -970,15 +970,15 @@ std::unique_ptr<GPUTexture> MetalDevice::CreateTexture(u32 width, u32 height, u3
|
|||
GPUTexture::Type type, GPUTexture::Format format,
|
||||
const void* data, u32 data_stride, bool dynamic /* = false */)
|
||||
{
|
||||
if (!GPUTexture::ValidateConfig(width, height, layers, layers, samples, type, format))
|
||||
return {};
|
||||
|
||||
const MTLPixelFormat pixel_format = s_pixel_format_mapping[static_cast<u8>(format)];
|
||||
if (pixel_format == MTLPixelFormatInvalid)
|
||||
return {};
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
if (width > m_max_texture_size || height > m_max_texture_size || samples > m_max_multisamples)
|
||||
return {};
|
||||
|
||||
const MTLPixelFormat pixel_format = s_pixel_format_mapping[static_cast<u8>(format)];
|
||||
if (pixel_format == MTLPixelFormatInvalid)
|
||||
return {};
|
||||
|
||||
MTLTextureDescriptor* desc = [[[MTLTextureDescriptor alloc] init] autorelease];
|
||||
desc.width = width;
|
||||
desc.height = height;
|
||||
|
@ -1115,16 +1115,19 @@ MTLRenderPassDescriptor* MetalFramebuffer::GetDescriptor() const
|
|||
return m_descriptor;
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> MetalDevice::CreateFramebuffer(GPUTexture* rt, u32 rt_layer, u32 rt_level,
|
||||
GPUTexture* ds, u32 ds_layer, u32 ds_level)
|
||||
std::unique_ptr<GPUFramebuffer> MetalDevice::CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds)
|
||||
{
|
||||
DebugAssert((rt_or_ds || ds) && (!rt_or_ds || rt_or_ds->IsRenderTarget() || (rt_or_ds->IsDepthStencil() && !ds)));
|
||||
MetalTexture* RT = static_cast<MetalTexture*>((rt_or_ds && rt_or_ds->IsDepthStencil()) ? nullptr : rt_or_ds);
|
||||
MetalTexture* DS = static_cast<MetalTexture*>((rt_or_ds && rt_or_ds->IsDepthStencil()) ? rt_or_ds : ds);
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
MTLRenderPassDescriptor* desc = [[MTLRenderPassDescriptor renderPassDescriptor] retain];
|
||||
id<MTLTexture> rt_tex = rt ? [static_cast<MetalTexture*>(rt)->GetMTLTexture() retain] : nil;
|
||||
id<MTLTexture> ds_tex = ds ? [static_cast<MetalTexture*>(ds)->GetMTLTexture() retain] : nil;
|
||||
id<MTLTexture> rt_tex = RT ? [RT->GetMTLTexture() retain] : nil;
|
||||
id<MTLTexture> ds_tex = DS ? [DS->GetMTLTexture() retain] : nil;
|
||||
|
||||
if (rt)
|
||||
if (RT)
|
||||
{
|
||||
desc.colorAttachments[0].texture = rt_tex;
|
||||
desc.colorAttachments[0].slice = rt_layer;
|
||||
|
@ -1133,7 +1136,7 @@ std::unique_ptr<GPUFramebuffer> MetalDevice::CreateFramebuffer(GPUTexture* rt, u
|
|||
desc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
}
|
||||
|
||||
if (rt)
|
||||
if (DS)
|
||||
{
|
||||
desc.depthAttachment.texture = ds_tex;
|
||||
desc.depthAttachment.slice = ds_layer;
|
||||
|
@ -1142,12 +1145,12 @@ std::unique_ptr<GPUFramebuffer> MetalDevice::CreateFramebuffer(GPUTexture* rt, u
|
|||
desc.depthAttachment.storeAction = MTLStoreActionStore;
|
||||
}
|
||||
|
||||
const u32 width = rt ? rt->GetMipWidth(rt_level) : ds->GetMipWidth(ds_level);
|
||||
const u32 height = rt ? rt->GetMipHeight(rt_level) : ds->GetMipHeight(ds_level);
|
||||
const u32 width = RT ? RT->GetWidth() : DS->GetWidth();
|
||||
const u32 height = RT ? RT->GetHeight() : DS->GetHeight();
|
||||
desc.renderTargetWidth = width;
|
||||
desc.renderTargetHeight = height;
|
||||
|
||||
return std::unique_ptr<GPUFramebuffer>(new MetalFramebuffer(rt, ds, width, height, rt_tex, ds_tex, desc));
|
||||
return std::unique_ptr<GPUFramebuffer>(new MetalFramebuffer(RT, DS, width, height, rt_tex, ds_tex, desc));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ std::unique_ptr<GPUTexture> OpenGLDevice::CreateTexture(u32 width, u32 height, u
|
|||
const void* data, u32 data_stride, bool dynamic /* = false */)
|
||||
{
|
||||
std::unique_ptr<OpenGLTexture> tex(std::make_unique<OpenGLTexture>());
|
||||
if (!tex->Create(width, height, layers, levels, samples, format, data, data_stride))
|
||||
if (!tex->Create(width, height, layers, levels, samples, type, format, data, data_stride))
|
||||
tex.reset();
|
||||
|
||||
return tex;
|
||||
|
@ -417,9 +417,6 @@ bool OpenGLDevice::CheckFeatures()
|
|||
|
||||
m_features.per_sample_shading = GLAD_GL_VERSION_4_0 || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_ARB_sample_shading;
|
||||
|
||||
// adaptive smoothing would require texture views, which aren't in GLES.
|
||||
m_features.mipmapped_render_targets = false;
|
||||
|
||||
// noperspective is not supported in GLSL ES.
|
||||
m_features.noperspective_interpolation = !is_gles;
|
||||
return true;
|
||||
|
|
|
@ -69,9 +69,7 @@ public:
|
|||
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,
|
||||
u32 ds_level = 0) override;
|
||||
std::unique_ptr<GPUFramebuffer> CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds = nullptr) override;
|
||||
|
||||
std::unique_ptr<GPUShader> CreateShaderFromBinary(GPUShaderStage stage, gsl::span<const u8> data) override;
|
||||
std::unique_ptr<GPUShader> CreateShaderFromSource(GPUShaderStage stage, const std::string_view& source,
|
||||
|
|
|
@ -59,22 +59,11 @@ bool OpenGLTexture::UseTextureStorage() const
|
|||
return UseTextureStorage(IsMultisampled());
|
||||
}
|
||||
|
||||
bool OpenGLTexture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Format format, const void* data,
|
||||
u32 data_pitch)
|
||||
bool OpenGLTexture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type, Format format,
|
||||
const void* data, u32 data_pitch)
|
||||
{
|
||||
glGetError();
|
||||
|
||||
if (width > MAX_WIDTH || height > MAX_HEIGHT || layers > MAX_LAYERS || levels > MAX_LEVELS || samples > MAX_SAMPLES)
|
||||
{
|
||||
Log_ErrorPrintf("Invalid dimensions: %ux%ux%u %u %u", width, height, layers, levels, samples);
|
||||
if (!ValidateConfig(width, height, layers, levels, samples, type, format))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (samples > 1 && levels > 1)
|
||||
{
|
||||
Log_ErrorPrintf("Multisampled textures can't have mip levels");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layers > 1 && data)
|
||||
{
|
||||
|
@ -88,6 +77,8 @@ bool OpenGLTexture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 sa
|
|||
|
||||
OpenGLDevice::BindUpdateTextureUnit();
|
||||
|
||||
glGetError();
|
||||
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(target, id);
|
||||
|
@ -164,67 +155,12 @@ bool OpenGLTexture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 sa
|
|||
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_state = GPUTexture::State::Dirty;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void OpenGLTexture::Replace(u32 width, u32 height, GLenum internal_format, GLenum format, GLenum type, const void* data)
|
||||
{
|
||||
Assert(IsValid() && width < MAX_WIDTH && height < MAX_HEIGHT && m_layers == 1 && m_samples == 1 && m_levels == 1);
|
||||
|
||||
const bool size_changed = (width != m_width || height != m_height);
|
||||
|
||||
m_width = static_cast<u16>(width);
|
||||
m_height = static_cast<u16>(height);
|
||||
m_levels = 1;
|
||||
|
||||
const GLenum target = GetGLTarget();
|
||||
glBindTexture(target, m_id);
|
||||
|
||||
if (UseTextureStorage())
|
||||
{
|
||||
if (size_changed)
|
||||
{
|
||||
if (m_layers > 0)
|
||||
glTexStorage3D(target, m_levels, internal_format, m_width, m_height, m_levels);
|
||||
else
|
||||
glTexStorage2D(target, m_levels, internal_format, m_width, m_height);
|
||||
}
|
||||
|
||||
glTexSubImage2D(target, 0, 0, 0, m_width, m_height, format, type, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage2D(target, 0, internal_format, width, height, 0, format, type, data);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLTexture::ReplaceImage(u32 layer, u32 level, GLenum format, GLenum type, const void* data)
|
||||
{
|
||||
Assert(IsValid() && !IsMultisampled());
|
||||
|
||||
const GLenum target = GetGLTarget();
|
||||
if (IsTextureArray())
|
||||
glTexSubImage3D(target, level, 0, 0, layer, m_width, m_height, 1, format, type, data);
|
||||
else
|
||||
glTexSubImage2D(target, level, 0, 0, m_width, m_height, format, type, data);
|
||||
}
|
||||
|
||||
void OpenGLTexture::ReplaceSubImage(u32 layer, u32 level, u32 x, u32 y, u32 width, u32 height, GLenum format,
|
||||
GLenum type, const void* data)
|
||||
{
|
||||
Assert(IsValid() && !IsMultisampled());
|
||||
|
||||
const GLenum target = GetGLTarget();
|
||||
if (IsTextureArray())
|
||||
glTexSubImage3D(target, level, x, y, layer, width, height, 1, format, type, data);
|
||||
else
|
||||
glTexSubImage2D(target, level, x, y, width, height, format, type, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
void OpenGLTexture::Destroy()
|
||||
{
|
||||
if (m_id != 0)
|
||||
|
@ -458,8 +394,7 @@ void OpenGLFramebuffer::Bind(GLenum target)
|
|||
glBindFramebuffer(target, m_id);
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUFramebuffer> OpenGLDevice::CreateFramebuffer(GPUTexture* rt, u32 rt_layer, u32 rt_level,
|
||||
GPUTexture* ds, u32 ds_layer, u32 ds_level)
|
||||
std::unique_ptr<GPUFramebuffer> OpenGLDevice::CreateFramebuffer(GPUTexture* rt_or_ds, GPUTexture* ds /* = nullptr */)
|
||||
{
|
||||
glGetError();
|
||||
|
||||
|
@ -467,34 +402,25 @@ std::unique_ptr<GPUFramebuffer> OpenGLDevice::CreateFramebuffer(GPUTexture* rt,
|
|||
glGenFramebuffers(1, &fbo_id);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
|
||||
|
||||
OpenGLTexture* RT = static_cast<OpenGLTexture*>(rt);
|
||||
OpenGLTexture* DS = static_cast<OpenGLTexture*>(ds);
|
||||
DebugAssert((rt_or_ds || ds) && (!rt_or_ds || rt_or_ds->IsRenderTarget() || (rt_or_ds->IsDepthStencil() && !ds)));
|
||||
OpenGLTexture* RT = static_cast<OpenGLTexture*>((rt_or_ds && rt_or_ds->IsDepthStencil()) ? nullptr : rt_or_ds);
|
||||
OpenGLTexture* DS = static_cast<OpenGLTexture*>((rt_or_ds && rt_or_ds->IsDepthStencil()) ? rt_or_ds : ds);
|
||||
if (RT)
|
||||
{
|
||||
if (RT->IsTextureArray())
|
||||
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, fbo_id, RT->GetGLId(), rt_level, rt_layer);
|
||||
else
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, RT->GetGLId(), rt_level);
|
||||
}
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, RT->GetGLId(), 0);
|
||||
if (DS)
|
||||
{
|
||||
if (DS->IsTextureArray())
|
||||
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, fbo_id, DS->GetGLId(), rt_level, rt_layer);
|
||||
else
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DS->GetGLId(), rt_level);
|
||||
}
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DS->GetGLId(), 0);
|
||||
|
||||
if (glGetError() != GL_NO_ERROR || glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create GL framebuffer: %u", glGetError());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_current_framebuffer ? m_current_framebuffer->GetGLId() : 0);
|
||||
glDeleteFramebuffers(1, &fbo_id);
|
||||
return {};
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_current_framebuffer ? m_current_framebuffer->GetGLId() : 0);
|
||||
return std::unique_ptr<GPUFramebuffer>(
|
||||
new OpenGLFramebuffer(rt, ds, rt ? rt->GetMipWidth(rt_level) : ds->GetMipWidth(ds_level),
|
||||
rt ? rt->GetMipHeight(rt_level) : ds->GetMipHeight(ds_level), fbo_id));
|
||||
return std::unique_ptr<GPUFramebuffer>(new OpenGLFramebuffer(RT, DS, RT ? RT->GetWidth() : DS->GetWidth(),
|
||||
RT ? RT->GetHeight() : DS->GetHeight(), fbo_id));
|
||||
}
|
||||
|
||||
void OpenGLDevice::CommitClear(OpenGLTexture* tex)
|
||||
|
|
|
@ -30,8 +30,8 @@ public:
|
|||
|
||||
void SetDebugName(const std::string_view& name) override;
|
||||
|
||||
bool Create(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Format format, const void* data = nullptr,
|
||||
u32 data_pitch = 0);
|
||||
bool Create(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type, Format format,
|
||||
const void* data = nullptr, u32 data_pitch = 0);
|
||||
void Destroy();
|
||||
|
||||
bool UseTextureStorage() const;
|
||||
|
|
|
@ -502,13 +502,10 @@ bool GPU_HW::CreateBuffers()
|
|||
}
|
||||
|
||||
// vram framebuffer has both colour and depth
|
||||
if (!(m_vram_framebuffer =
|
||||
g_gpu_device->CreateFramebuffer(m_vram_texture.get(), 0, 0, m_vram_depth_texture.get(), 0, 0)) ||
|
||||
!(m_vram_update_depth_framebuffer =
|
||||
g_gpu_device->CreateFramebuffer(nullptr, 0, 0, m_vram_depth_texture.get(), 0, 0)) ||
|
||||
!(m_vram_readback_framebuffer =
|
||||
g_gpu_device->CreateFramebuffer(m_vram_readback_texture.get(), 0, 0, nullptr, 0, 0)) ||
|
||||
!(m_display_framebuffer = g_gpu_device->CreateFramebuffer(m_display_texture.get(), 0, 0, nullptr, 0, 0)))
|
||||
if (!(m_vram_framebuffer = g_gpu_device->CreateFramebuffer(m_vram_texture.get(), m_vram_depth_texture.get())) ||
|
||||
!(m_vram_update_depth_framebuffer = g_gpu_device->CreateFramebuffer(m_vram_depth_texture.get())) ||
|
||||
!(m_vram_readback_framebuffer = g_gpu_device->CreateFramebuffer(m_vram_readback_texture.get())) ||
|
||||
!(m_display_framebuffer = g_gpu_device->CreateFramebuffer(m_display_texture.get())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue