summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D/DXTexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/D3D/DXTexture.cpp')
-rw-r--r--Source/Core/VideoBackends/D3D/DXTexture.cpp185
1 files changed, 163 insertions, 22 deletions
diff --git a/Source/Core/VideoBackends/D3D/DXTexture.cpp b/Source/Core/VideoBackends/D3D/DXTexture.cpp
index 7be3264a74..51a017b741 100644
--- a/Source/Core/VideoBackends/D3D/DXTexture.cpp
+++ b/Source/Core/VideoBackends/D3D/DXTexture.cpp
@@ -43,42 +43,84 @@ DXGI_FORMAT GetDXGIFormatForHostFormat(AbstractTextureFormat format)
return DXGI_FORMAT_R8G8B8A8_UNORM;
case AbstractTextureFormat::BGRA8:
return DXGI_FORMAT_B8G8R8A8_UNORM;
+ case AbstractTextureFormat::R16:
+ return DXGI_FORMAT_R16_UNORM;
+ case AbstractTextureFormat::R32F:
+ return DXGI_FORMAT_R32_FLOAT;
+ case AbstractTextureFormat::D16:
+ return DXGI_FORMAT_R16_TYPELESS;
+ case AbstractTextureFormat::D32F:
+ return DXGI_FORMAT_R32_TYPELESS;
+ case AbstractTextureFormat::D32F_S8:
+ return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
default:
PanicAlert("Unhandled texture format.");
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
}
+DXGI_FORMAT GetSRVFormatForHostFormat(AbstractTextureFormat format)
+{
+ switch (format)
+ {
+ case AbstractTextureFormat::D16:
+ return DXGI_FORMAT_R16_UNORM;
+ case AbstractTextureFormat::D32F:
+ return DXGI_FORMAT_R32_FLOAT;
+ case AbstractTextureFormat::D32F_S8:
+ return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
+ default:
+ return GetDXGIFormatForHostFormat(format);
+ }
+}
+DXGI_FORMAT GetDSVFormatForHostFormat(AbstractTextureFormat format)
+{
+ switch (format)
+ {
+ case AbstractTextureFormat::D16:
+ return DXGI_FORMAT_D16_UNORM;
+ case AbstractTextureFormat::D32F:
+ return DXGI_FORMAT_D32_FLOAT;
+ case AbstractTextureFormat::D32F_S8:
+ return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
+ default:
+ return GetDXGIFormatForHostFormat(format);
+ }
+}
} // Anonymous namespace
DXTexture::DXTexture(const TextureConfig& tex_config) : AbstractTexture(tex_config)
{
- DXGI_FORMAT dxgi_format = GetDXGIFormatForHostFormat(m_config.format);
- if (m_config.rendertarget)
+ DXGI_FORMAT tex_format = GetDXGIFormatForHostFormat(m_config.format);
+ DXGI_FORMAT srv_format = GetSRVFormatForHostFormat(m_config.format);
+ DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN;
+ DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN;
+ UINT bind_flags = D3D11_BIND_SHADER_RESOURCE;
+ if (tex_config.rendertarget)
{
- m_texture = D3DTexture2D::Create(
- m_config.width, m_config.height,
- (D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE),
- D3D11_USAGE_DEFAULT, dxgi_format, 1, m_config.layers);
+ if (IsDepthFormat(tex_config.format))
+ {
+ bind_flags |= D3D11_BIND_DEPTH_STENCIL;
+ dsv_format = GetDSVFormatForHostFormat(m_config.format);
+ }
+ else
+ {
+ bind_flags |= D3D11_BIND_RENDER_TARGET;
+ rtv_format = tex_format;
+ }
}
- else
- {
- const D3D11_TEXTURE2D_DESC texdesc =
- CD3D11_TEXTURE2D_DESC(dxgi_format, m_config.width, m_config.height, 1, m_config.levels,
- D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0);
- ID3D11Texture2D* pTexture;
- const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
- CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");
+ CD3D11_TEXTURE2D_DESC texdesc(tex_format, tex_config.width, tex_config.height, tex_config.layers,
+ tex_config.levels, bind_flags, D3D11_USAGE_DEFAULT, 0,
+ tex_config.samples, 0, 0);
- m_texture = new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE);
+ ID3D11Texture2D* pTexture;
+ HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
+ CHECK(SUCCEEDED(hr), "Create backing DXTexture");
- // TODO: better debug names
- D3D::SetDebugObjectName(m_texture->GetTex(), "a texture of the TextureCache");
- D3D::SetDebugObjectName(m_texture->GetSRV(),
- "shader resource view of a texture of the TextureCache");
+ m_texture = new D3DTexture2D(pTexture, static_cast<D3D11_BIND_FLAG>(bind_flags), srv_format,
+ dsv_format, rtv_format, tex_config.samples > 1);
- SAFE_RELEASE(pTexture);
- }
+ SAFE_RELEASE(pTexture);
}
DXTexture::~DXTexture()
@@ -144,10 +186,25 @@ void DXTexture::ScaleRectangleFromTexture(const AbstractTexture* source,
VertexShaderCache::GetSimpleInputLayout(),
GeometryShaderCache::GetCopyGeometryShader(), 1.0, 0);
- FramebufferManager::BindEFBRenderTarget();
g_renderer->RestoreAPIState();
}
+void DXTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& rect,
+ u32 layer, u32 level)
+{
+ const DXTexture* srcentry = static_cast<const DXTexture*>(src);
+ _dbg_assert_(VIDEO, m_config.samples > 1 && m_config.width == srcentry->m_config.width &&
+ m_config.height == srcentry->m_config.height && m_config.samples == 1);
+ _dbg_assert_(VIDEO,
+ rect.left + rect.GetWidth() <= static_cast<int>(srcentry->m_config.width) &&
+ rect.top + rect.GetHeight() <= static_cast<int>(srcentry->m_config.height));
+
+ D3D::context->ResolveSubresource(
+ m_texture->GetTex(), D3D11CalcSubresource(level, layer, m_config.levels),
+ srcentry->m_texture->GetTex(), D3D11CalcSubresource(level, layer, srcentry->m_config.levels),
+ GetDXGIFormatForHostFormat(m_config.format));
+}
+
void DXTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
size_t buffer_size)
{
@@ -287,4 +344,88 @@ void DXStagingTexture::Flush()
m_needs_flush = false;
}
+DXFramebuffer::DXFramebuffer(AbstractTextureFormat color_format, AbstractTextureFormat depth_format,
+ u32 width, u32 height, u32 layers, u32 samples,
+ ID3D11RenderTargetView* rtv, ID3D11DepthStencilView* dsv)
+ : AbstractFramebuffer(color_format, depth_format, width, height, layers, samples), m_rtv(rtv),
+ m_dsv(dsv)
+{
+}
+
+DXFramebuffer::~DXFramebuffer()
+{
+ if (m_rtv)
+ m_rtv->Release();
+ if (m_dsv)
+ m_dsv->Release();
+}
+
+std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(const DXTexture* color_attachment,
+ const DXTexture* depth_attachment)
+{
+ if (!ValidateConfig(color_attachment, depth_attachment))
+ return nullptr;
+
+ const AbstractTextureFormat color_format =
+ color_attachment ? color_attachment->GetFormat() : AbstractTextureFormat::Undefined;
+ const AbstractTextureFormat depth_format =
+ depth_attachment ? depth_attachment->GetFormat() : AbstractTextureFormat::Undefined;
+ const DXTexture* either_attachment = color_attachment ? color_attachment : depth_attachment;
+ const u32 width = either_attachment->GetWidth();
+ const u32 height = either_attachment->GetHeight();
+ const u32 layers = either_attachment->GetLayers();
+ const u32 samples = either_attachment->GetSamples();
+
+ ID3D11RenderTargetView* rtv = nullptr;
+ if (color_attachment)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC desc;
+ desc.Format = GetDXGIFormatForHostFormat(color_attachment->GetConfig().format);
+ if (color_attachment->GetConfig().IsMultisampled())
+ {
+ desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
+ desc.Texture2DMSArray.ArraySize = color_attachment->GetConfig().layers;
+ desc.Texture2DMSArray.FirstArraySlice = 0;
+ }
+ else
+ {
+ desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ desc.Texture2DArray.ArraySize = color_attachment->GetConfig().layers;
+ desc.Texture2DArray.FirstArraySlice = 0;
+ desc.Texture2DArray.MipSlice = 0;
+ }
+
+ HRESULT hr = D3D::device->CreateRenderTargetView(
+ color_attachment->GetRawTexIdentifier()->GetTex(), &desc, &rtv);
+ CHECK(SUCCEEDED(hr), "Create render target view for framebuffer");
+ }
+
+ ID3D11DepthStencilView* dsv = nullptr;
+ if (depth_attachment)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+ desc.Format = GetDXGIFormatForHostFormat(depth_attachment->GetConfig().format);
+ if (depth_attachment->GetConfig().IsMultisampled())
+ {
+ desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
+ desc.Texture2DMSArray.ArraySize = depth_attachment->GetConfig().layers;
+ desc.Texture2DMSArray.FirstArraySlice = 0;
+ }
+ else
+ {
+ desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ desc.Texture2DArray.ArraySize = depth_attachment->GetConfig().layers;
+ desc.Texture2DArray.FirstArraySlice = 0;
+ desc.Texture2DArray.MipSlice = 0;
+ }
+
+ HRESULT hr = D3D::device->CreateDepthStencilView(
+ depth_attachment->GetRawTexIdentifier()->GetTex(), &desc, &dsv);
+ CHECK(SUCCEEDED(hr), "Create depth stencil view for framebuffer");
+ }
+
+ return std::make_unique<DXFramebuffer>(color_format, depth_format, width, height, layers, samples,
+ rtv, dsv);
+}
+
} // namespace DX11