D3D11: Support mipmaps in wrapper textures

This commit is contained in:
Connor McLaughlin 2020-12-30 14:56:43 +10:00
parent 68ce959d70
commit 59e8363075
4 changed files with 27 additions and 21 deletions

View file

@ -28,10 +28,11 @@ D3D11_TEXTURE2D_DESC Texture::GetDesc() const
return desc; return desc;
} }
bool Texture::Create(ID3D11Device* device, u32 width, u32 height, u32 samples, DXGI_FORMAT format, u32 bind_flags, bool Texture::Create(ID3D11Device* device, u32 width, u32 height, u16 levels, u16 samples, DXGI_FORMAT format,
const void* initial_data /* = nullptr */, u32 initial_data_stride /* = 0 */, bool dynamic) u32 bind_flags, const void* initial_data /* = nullptr */, u32 initial_data_stride /* = 0 */,
bool dynamic)
{ {
CD3D11_TEXTURE2D_DESC desc(format, width, height, 1, 1, bind_flags, CD3D11_TEXTURE2D_DESC desc(format, width, height, 1, levels, bind_flags,
dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT, dynamic ? D3D11_CPU_ACCESS_WRITE : 0, dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT, dynamic ? D3D11_CPU_ACCESS_WRITE : 0,
samples, 0, 0); samples, 0, 0);
@ -79,9 +80,10 @@ bool Texture::Create(ID3D11Device* device, u32 width, u32 height, u32 samples, D
m_texture = std::move(texture); m_texture = std::move(texture);
m_srv = std::move(srv); m_srv = std::move(srv);
m_rtv = std::move(rtv); m_rtv = std::move(rtv);
m_width = desc.Width; m_width = width;
m_height = desc.Height; m_height = height;
m_samples = desc.SampleDesc.Count; m_levels = levels;
m_samples = samples;
return true; return true;
} }
@ -123,7 +125,8 @@ bool Texture::Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture)
m_rtv = std::move(rtv); m_rtv = std::move(rtv);
m_width = desc.Width; m_width = desc.Width;
m_height = desc.Height; m_height = desc.Height;
m_samples = desc.SampleDesc.Count; m_levels = static_cast<u16>(desc.MipLevels);
m_samples = static_cast<u16>(desc.SampleDesc.Count);
return true; return true;
} }
@ -134,6 +137,7 @@ void Texture::Destroy()
m_texture.Reset(); m_texture.Reset();
m_width = 0; m_width = 0;
m_height = 0; m_height = 0;
m_levels = 0;
m_samples = 0; m_samples = 0;
} }

View file

@ -23,7 +23,8 @@ public:
ALWAYS_INLINE u32 GetWidth() const { return m_width; } ALWAYS_INLINE u32 GetWidth() const { return m_width; }
ALWAYS_INLINE u32 GetHeight() const { return m_height; } ALWAYS_INLINE u32 GetHeight() const { return m_height; }
ALWAYS_INLINE u32 GetSamples() const { return m_samples; } ALWAYS_INLINE u16 GetLevels() const { return m_levels; }
ALWAYS_INLINE u16 GetSamples() const { return m_samples; }
ALWAYS_INLINE bool IsMultisampled() const { return m_samples > 1; } ALWAYS_INLINE bool IsMultisampled() const { return m_samples > 1; }
ALWAYS_INLINE DXGI_FORMAT GetFormat() const { return GetDesc().Format; } ALWAYS_INLINE DXGI_FORMAT GetFormat() const { return GetDesc().Format; }
D3D11_TEXTURE2D_DESC GetDesc() const; D3D11_TEXTURE2D_DESC GetDesc() const;
@ -33,7 +34,7 @@ public:
ALWAYS_INLINE operator ID3D11RenderTargetView*() const { return m_rtv.Get(); } ALWAYS_INLINE operator ID3D11RenderTargetView*() const { return m_rtv.Get(); }
ALWAYS_INLINE operator bool() const { return static_cast<bool>(m_texture); } ALWAYS_INLINE operator bool() const { return static_cast<bool>(m_texture); }
bool Create(ID3D11Device* device, u32 width, u32 height, u32 samples, DXGI_FORMAT format, u32 bind_flags, bool Create(ID3D11Device* device, u32 width, u32 height, u16 levels, u16 samples, DXGI_FORMAT format, u32 bind_flags,
const void* initial_data = nullptr, u32 initial_data_stride = 0, bool dynamic = false); const void* initial_data = nullptr, u32 initial_data_stride = 0, bool dynamic = false);
bool Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture); bool Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture);
@ -45,6 +46,7 @@ private:
ComPtr<ID3D11RenderTargetView> m_rtv; ComPtr<ID3D11RenderTargetView> m_rtv;
u32 m_width; u32 m_width;
u32 m_height; u32 m_height;
u32 m_samples; u16 m_levels;
u16 m_samples;
}; };
} // namespace D3D11 } // namespace D3D11

View file

@ -200,19 +200,19 @@ bool GPU_HW_D3D11::CreateFramebuffer()
// scale vram size to internal resolution // scale vram size to internal resolution
const u32 texture_width = VRAM_WIDTH * m_resolution_scale; const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale; const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
const u32 multisamples = m_multisamples; const u16 samples = static_cast<u16>(m_multisamples);
const DXGI_FORMAT texture_format = DXGI_FORMAT_R8G8B8A8_UNORM; const DXGI_FORMAT texture_format = DXGI_FORMAT_R8G8B8A8_UNORM;
const DXGI_FORMAT depth_format = DXGI_FORMAT_D16_UNORM; const DXGI_FORMAT depth_format = DXGI_FORMAT_D16_UNORM;
if (!m_vram_texture.Create(m_device.Get(), texture_width, texture_height, multisamples, texture_format, if (!m_vram_texture.Create(m_device.Get(), texture_width, texture_height, 1, samples, texture_format,
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) || D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) ||
!m_vram_depth_texture.Create(m_device.Get(), texture_width, texture_height, multisamples, depth_format, !m_vram_depth_texture.Create(m_device.Get(), texture_width, texture_height, 1, samples, depth_format,
D3D11_BIND_DEPTH_STENCIL) || D3D11_BIND_DEPTH_STENCIL) ||
!m_vram_read_texture.Create(m_device.Get(), texture_width, texture_height, 1, texture_format, !m_vram_read_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, texture_format,
D3D11_BIND_SHADER_RESOURCE) || D3D11_BIND_SHADER_RESOURCE) ||
!m_display_texture.Create(m_device.Get(), texture_width, texture_height, 1, texture_format, !m_display_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, texture_format,
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) || D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) ||
!m_vram_encoding_texture.Create(m_device.Get(), VRAM_WIDTH, VRAM_HEIGHT, 1, texture_format, !m_vram_encoding_texture.Create(m_device.Get(), VRAM_WIDTH, VRAM_HEIGHT, 1, 1, texture_format,
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) || D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) ||
!m_vram_readback_texture.Create(m_device.Get(), VRAM_WIDTH, VRAM_HEIGHT, texture_format, false)) !m_vram_readback_texture.Create(m_device.Get(), VRAM_WIDTH, VRAM_HEIGHT, texture_format, false))
{ {
@ -220,7 +220,7 @@ bool GPU_HW_D3D11::CreateFramebuffer()
} }
const CD3D11_DEPTH_STENCIL_VIEW_DESC depth_view_desc( const CD3D11_DEPTH_STENCIL_VIEW_DESC depth_view_desc(
multisamples > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D, depth_format); samples > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D, depth_format);
HRESULT hr = HRESULT hr =
m_device->CreateDepthStencilView(m_vram_depth_texture, &depth_view_desc, m_vram_depth_view.GetAddressOf()); m_device->CreateDepthStencilView(m_vram_depth_texture, &depth_view_desc, m_vram_depth_view.GetAddressOf());
if (FAILED(hr)) if (FAILED(hr))
@ -622,7 +622,7 @@ bool GPU_HW_D3D11::BlitVRAMReplacementTexture(const TextureReplacementTexture* t
if (m_vram_replacement_texture.GetWidth() < tex->GetWidth() || if (m_vram_replacement_texture.GetWidth() < tex->GetWidth() ||
m_vram_replacement_texture.GetHeight() < tex->GetHeight()) m_vram_replacement_texture.GetHeight() < tex->GetHeight())
{ {
if (!m_vram_replacement_texture.Create(m_device.Get(), tex->GetWidth(), tex->GetHeight(), 1, if (!m_vram_replacement_texture.Create(m_device.Get(), tex->GetWidth(), tex->GetHeight(), 1, 1,
DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_BIND_SHADER_RESOURCE, tex->GetPixels(), DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_BIND_SHADER_RESOURCE, tex->GetPixels(),
tex->GetByteStride(), true)) tex->GetByteStride(), true))
{ {

View file

@ -198,7 +198,7 @@ bool D3D11HostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32
if (m_display_pixels_texture.GetWidth() < width || m_display_pixels_texture.GetHeight() < height || if (m_display_pixels_texture.GetWidth() < width || m_display_pixels_texture.GetHeight() < height ||
m_display_pixels_texture.GetFormat() != dxgi_format) m_display_pixels_texture.GetFormat() != dxgi_format)
{ {
if (!m_display_pixels_texture.Create(m_device.Get(), width, height, 1, dxgi_format, D3D11_BIND_SHADER_RESOURCE, if (!m_display_pixels_texture.Create(m_device.Get(), width, height, 1, 1, dxgi_format, D3D11_BIND_SHADER_RESOURCE,
nullptr, 0, true)) nullptr, 0, true))
{ {
return false; return false;
@ -961,7 +961,7 @@ bool D3D11HostDisplay::CheckPostProcessingRenderTargets(u32 target_width, u32 ta
if (m_post_processing_input_texture.GetWidth() != target_width || if (m_post_processing_input_texture.GetWidth() != target_width ||
m_post_processing_input_texture.GetHeight() != target_height) m_post_processing_input_texture.GetHeight() != target_height)
{ {
if (!m_post_processing_input_texture.Create(m_device.Get(), target_width, target_height, 1, format, bind_flags)) if (!m_post_processing_input_texture.Create(m_device.Get(), target_width, target_height, 1, 1, format, bind_flags))
return false; return false;
} }
@ -971,7 +971,7 @@ bool D3D11HostDisplay::CheckPostProcessingRenderTargets(u32 target_width, u32 ta
PostProcessingStage& pps = m_post_processing_stages[i]; PostProcessingStage& pps = m_post_processing_stages[i];
if (pps.output_texture.GetWidth() != target_width || pps.output_texture.GetHeight() != target_height) if (pps.output_texture.GetWidth() != target_width || pps.output_texture.GetHeight() != target_height)
{ {
if (!pps.output_texture.Create(m_device.Get(), target_width, target_height, 1, format, bind_flags)) if (!pps.output_texture.Create(m_device.Get(), target_width, target_height, 1, 1, format, bind_flags))
return false; return false;
} }
} }