D3D12Device: Create texture arrays with all layers

Use the requested array size and create array-aware UAV and mipmap
views for layered textures.
pull/3782/head
Stenzek 2 months ago
parent 6e2f06a55a
commit 2273890101
No known key found for this signature in database

@ -2228,7 +2228,7 @@ void D3D12Device::UnbindTextureBuffer(D3D12TextureBuffer* buf)
m_dirty_flags |= DIRTY_FLAG_TEXTURES;
}
void D3D12Device::RenderTextureMipmap(D3D12Texture* texture, u32 dst_level, u32 dst_width, u32 dst_height,
void D3D12Device::RenderTextureMipmap(D3D12Texture* texture, u32 layer, u32 dst_level, u32 dst_width, u32 dst_height,
u32 src_level, u32 src_width, u32 src_height)
{
ComPtr<ID3D12PipelineState>& pipeline = m_mipmap_render_pipelines[static_cast<size_t>(texture->GetFormat())];
@ -2304,29 +2304,46 @@ void D3D12Device::RenderTextureMipmap(D3D12Texture* texture, u32 dst_level, u32
}
// Setup views. This will be a partial view for the SRV.
const D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = {.Format = texture->GetDXGIFormat(),
.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D,
.Texture2D = {.MipSlice = dst_level, .PlaneSlice = 0}};
const D3D12_RENDER_TARGET_VIEW_DESC rtv_desc =
(texture->GetLayers() > 1) ?
D3D12_RENDER_TARGET_VIEW_DESC{
.Format = texture->GetDXGIFormat(),
.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY,
.Texture2DArray = {.MipSlice = dst_level, .FirstArraySlice = layer, .ArraySize = 1, .PlaneSlice = 0}} :
D3D12_RENDER_TARGET_VIEW_DESC{.Format = texture->GetDXGIFormat(),
.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D,
.Texture2D = {.MipSlice = dst_level, .PlaneSlice = 0}};
m_device->CreateRenderTargetView(texture->GetResource(), &rtv_desc, rtv_handle);
const D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {
.Format = texture->GetDXGIFormat(),
.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D,
.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
.Texture2D = {.MostDetailedMip = src_level, .MipLevels = 1, .PlaneSlice = 0, .ResourceMinLODClamp = 0.0f}};
const D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc =
(texture->GetLayers() > 1) ?
D3D12_SHADER_RESOURCE_VIEW_DESC{.Format = texture->GetDXGIFormat(),
.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY,
.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
.Texture2DArray = {.MostDetailedMip = src_level,
.MipLevels = 1,
.FirstArraySlice = layer,
.ArraySize = 1,
.PlaneSlice = 0,
.ResourceMinLODClamp = 0.0f}} :
D3D12_SHADER_RESOURCE_VIEW_DESC{
.Format = texture->GetDXGIFormat(),
.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D,
.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
.Texture2D = {.MostDetailedMip = src_level, .MipLevels = 1, .PlaneSlice = 0, .ResourceMinLODClamp = 0.0f}};
m_device->CreateShaderResourceView(texture->GetResource(), &srv_desc, srv_handle);
// *now* we don't have to worry about running out of anything.
ID3D12GraphicsCommandList4* cmdlist = GetCommandList();
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
{
texture->TransitionSubresourceToState(cmdlist, src_level, texture->GetResourceState(),
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
texture->TransitionSubresourceToState(cmdlist, texture->CalculateSubresource(layer, src_level),
texture->GetResourceState(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
}
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
{
texture->TransitionSubresourceToState(cmdlist, dst_level, texture->GetResourceState(),
D3D12_RESOURCE_STATE_RENDER_TARGET);
texture->TransitionSubresourceToState(cmdlist, texture->CalculateSubresource(layer, dst_level),
texture->GetResourceState(), D3D12_RESOURCE_STATE_RENDER_TARGET);
}
const D3D12_RENDER_PASS_RENDER_TARGET_DESC rt_desc = {
@ -2351,13 +2368,13 @@ void D3D12Device::RenderTextureMipmap(D3D12Texture* texture, u32 dst_level, u32
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
{
texture->TransitionSubresourceToState(cmdlist, src_level, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
texture->GetResourceState());
texture->TransitionSubresourceToState(cmdlist, texture->CalculateSubresource(layer, src_level),
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, texture->GetResourceState());
}
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
{
texture->TransitionSubresourceToState(cmdlist, dst_level, D3D12_RESOURCE_STATE_RENDER_TARGET,
texture->GetResourceState());
texture->TransitionSubresourceToState(cmdlist, texture->CalculateSubresource(layer, dst_level),
D3D12_RESOURCE_STATE_RENDER_TARGET, texture->GetResourceState());
}
// Must destroy after current cmdlist.

@ -198,8 +198,8 @@ public:
void UnbindTexture(D3D12Texture* tex);
void UnbindTextureBuffer(D3D12TextureBuffer* buf);
void RenderTextureMipmap(D3D12Texture* texture, u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level,
u32 src_width, u32 src_height);
void RenderTextureMipmap(D3D12Texture* texture, u32 layer, u32 dst_level, u32 dst_width, u32 dst_height,
u32 src_level, u32 src_width, u32 src_height);
protected:
bool CreateDeviceAndMainSwapChain(std::string_view adapter, CreateFlags create_flags, const WindowInfo& wi,
@ -271,8 +271,8 @@ private:
Error* error);
bool CreateDSVDescriptor(ID3D12Resource* resource, u32 samples, DXGI_FORMAT format, D3D12DescriptorHandle* dh,
Error* error);
bool CreateUAVDescriptor(ID3D12Resource* resource, u32 samples, DXGI_FORMAT format, D3D12DescriptorHandle* dh,
Error* error);
bool CreateUAVDescriptor(ID3D12Resource* resource, u32 layers, u32 samples, DXGI_FORMAT format,
D3D12DescriptorHandle* dh, Error* error);
bool IsRenderTargetBound(const GPUTexture* tex) const;

@ -50,7 +50,7 @@ std::unique_ptr<GPUTexture> D3D12Device::CreateTexture(u32 width, u32 height, u3
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Width = width;
desc.Height = height;
desc.DepthOrArraySize = 1;
desc.DepthOrArraySize = static_cast<u16>(layers);
desc.MipLevels = static_cast<u8>(levels);
desc.Format = fm.resource_format;
desc.SampleDesc.Count = samples;
@ -161,7 +161,7 @@ std::unique_ptr<GPUTexture> D3D12Device::CreateTexture(u32 width, u32 height, u3
if ((flags & GPUTexture::Flags::AllowBindAsImage) != GPUTexture::Flags::None)
{
if (!CreateUAVDescriptor(resource.Get(), samples, fm.srv_format, &uav_descriptor, error))
if (!CreateUAVDescriptor(resource.Get(), layers, samples, fm.srv_format, &uav_descriptor, error))
{
if (write_descriptor_type != D3D12Texture::WriteDescriptorType::None)
m_descriptor_heap_manager.Free(&write_descriptor);
@ -264,7 +264,7 @@ bool D3D12Device::CreateDSVDescriptor(ID3D12Resource* resource, u32 samples, DXG
return true;
}
bool D3D12Device::CreateUAVDescriptor(ID3D12Resource* resource, u32 samples, DXGI_FORMAT format,
bool D3D12Device::CreateUAVDescriptor(ID3D12Resource* resource, u32 layers, u32 samples, DXGI_FORMAT format,
D3D12DescriptorHandle* dh, Error* error)
{
if (!m_descriptor_heap_manager.Allocate(dh))
@ -274,7 +274,12 @@ bool D3D12Device::CreateUAVDescriptor(ID3D12Resource* resource, u32 samples, DXG
}
DebugAssert(samples == 1);
const D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {format, D3D12_UAV_DIMENSION_TEXTURE2D, {}};
const D3D12_UNORDERED_ACCESS_VIEW_DESC desc =
(layers > 1) ? D3D12_UNORDERED_ACCESS_VIEW_DESC{.Format = format,
.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY,
.Texture2DArray = {0u, 0u, layers, 0u}} :
D3D12_UNORDERED_ACCESS_VIEW_DESC{
.Format = format, .ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D, .Texture2D = {}};
m_device->CreateUnorderedAccessView(resource, nullptr, &desc, dh->cpu_handle);
return true;
}
@ -576,8 +581,8 @@ void D3D12Texture::GenerateMipmaps()
const u32 dst_width = std::max<u32>(m_width >> dst_level, 1u);
const u32 dst_height = std::max<u32>(m_height >> dst_level, 1u);
D3D12Device::GetInstance().RenderTextureMipmap(this, dst_level, dst_width, dst_height, src_level, src_width,
src_height);
D3D12Device::GetInstance().RenderTextureMipmap(this, layer, dst_level, dst_width, dst_height, src_level,
src_width, src_height);
}
}

Loading…
Cancel
Save