Formalize cubemap skybox pipeline across backends

This commit is contained in:
2026-04-06 01:37:04 +08:00
parent 66a6818b89
commit f014ae6e6f
24 changed files with 549 additions and 196 deletions

View File

@@ -196,6 +196,46 @@ D3D12_RTV_DIMENSION ResolveRTVDimension(const ResourceViewDesc& desc, TextureTyp
}
}
D3D12_SRV_DIMENSION ResolveSRVDimension(const ResourceViewDesc& desc, TextureType textureType) {
switch (desc.dimension) {
case ResourceViewDimension::Texture1D:
return D3D12_SRV_DIMENSION_TEXTURE1D;
case ResourceViewDimension::Texture1DArray:
return D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
case ResourceViewDimension::Texture2DArray:
return D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
case ResourceViewDimension::Texture3D:
return D3D12_SRV_DIMENSION_TEXTURE3D;
case ResourceViewDimension::TextureCube:
return D3D12_SRV_DIMENSION_TEXTURECUBE;
case ResourceViewDimension::TextureCubeArray:
return D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
case ResourceViewDimension::Texture2DMS:
return D3D12_SRV_DIMENSION_TEXTURE2DMS;
case ResourceViewDimension::Texture2DMSArray:
return D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY;
case ResourceViewDimension::Unknown:
break;
default:
return D3D12_SRV_DIMENSION_TEXTURE2D;
}
switch (textureType) {
case TextureType::Texture1D:
return D3D12_SRV_DIMENSION_TEXTURE1D;
case TextureType::Texture2DArray:
return D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
case TextureType::Texture3D:
return D3D12_SRV_DIMENSION_TEXTURE3D;
case TextureType::TextureCube:
return D3D12_SRV_DIMENSION_TEXTURECUBE;
case TextureType::TextureCubeArray:
return D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
default:
return D3D12_SRV_DIMENSION_TEXTURE2D;
}
}
bool IsDepthFormat(Format format) {
return format == Format::D16_UNorm ||
format == Format::D24_UNorm_S8_UInt ||
@@ -680,10 +720,6 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc, const void* init
return CreateTexture(desc);
}
if (desc.textureType != static_cast<uint32_t>(TextureType::Texture2D)) {
return nullptr;
}
const Format format = static_cast<Format>(desc.format);
uint32_t resolvedRowPitch = rowPitch;
if (resolvedRowPitch == 0) {
@@ -716,14 +752,27 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc, const void* init
uploadCommandList.Reset();
auto* texture = new D3D12Texture();
D3D12_RESOURCE_DESC textureDesc = {};
const TextureType textureType = ResolveTextureType(desc.textureType);
textureDesc.Dimension = ToD3D12(textureType);
textureDesc.Alignment = 0;
textureDesc.Width = desc.width;
textureDesc.Height = desc.height;
textureDesc.DepthOrArraySize = ResolveDepthOrArraySize(desc, textureType);
textureDesc.MipLevels = desc.mipLevels > 0 ? static_cast<uint16_t>(desc.mipLevels) : 1;
textureDesc.Format = ResolveD3D12ResourceFormat(format);
textureDesc.SampleDesc.Count = desc.sampleCount > 0 ? desc.sampleCount : 1;
textureDesc.SampleDesc.Quality = desc.sampleQuality;
textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
textureDesc.Flags = static_cast<D3D12_RESOURCE_FLAGS>(desc.flags);
ComPtr<ID3D12Resource> uploadBuffer;
if (!texture->InitializeFromData(
m_device.Get(),
uploadCommandList.GetCommandList(),
textureDesc,
textureType,
initialData,
desc.width,
desc.height,
ToD3D12(format),
initialDataSize,
resolvedRowPitch,
&uploadBuffer)) {
delete texture;
@@ -734,6 +783,8 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc, const void* init
}
texture->SetState(ResourceStates::PixelShaderResource);
texture->SetFormat(format);
texture->SetTextureType(textureType);
uploadCommandList.Close();
ID3D12CommandList* commandLists[] = { uploadCommandList.GetCommandList() };
@@ -1074,11 +1125,52 @@ RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, cons
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
const Format format = desc.format != 0 ? static_cast<Format>(desc.format) : texture->GetFormat();
const TextureType textureType = texture->GetTextureType();
srvDesc.Format = ResolveD3D12ShaderResourceViewFormat(format);
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = desc.mipLevel;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.ViewDimension = ResolveSRVDimension(desc, textureType);
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
switch (srvDesc.ViewDimension) {
case D3D12_SRV_DIMENSION_TEXTURE1D:
srvDesc.Texture1D.MostDetailedMip = desc.mipLevel;
srvDesc.Texture1D.MipLevels = 1;
break;
case D3D12_SRV_DIMENSION_TEXTURE1DARRAY:
srvDesc.Texture1DArray.MostDetailedMip = desc.mipLevel;
srvDesc.Texture1DArray.MipLevels = 1;
srvDesc.Texture1DArray.FirstArraySlice = desc.firstArraySlice;
srvDesc.Texture1DArray.ArraySize = desc.arraySize > 0 ? desc.arraySize : 1;
break;
case D3D12_SRV_DIMENSION_TEXTURE2DARRAY:
srvDesc.Texture2DArray.MostDetailedMip = desc.mipLevel;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = desc.firstArraySlice;
srvDesc.Texture2DArray.ArraySize = desc.arraySize > 0 ? desc.arraySize : 1;
srvDesc.Texture2DArray.PlaneSlice = desc.planeSlice;
break;
case D3D12_SRV_DIMENSION_TEXTURE3D:
srvDesc.Texture3D.MostDetailedMip = desc.mipLevel;
srvDesc.Texture3D.MipLevels = 1;
break;
case D3D12_SRV_DIMENSION_TEXTURECUBE:
srvDesc.TextureCube.MostDetailedMip = desc.mipLevel;
srvDesc.TextureCube.MipLevels = 1;
break;
case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY:
srvDesc.TextureCubeArray.MostDetailedMip = desc.mipLevel;
srvDesc.TextureCubeArray.MipLevels = 1;
srvDesc.TextureCubeArray.First2DArrayFace = desc.firstArraySlice;
srvDesc.TextureCubeArray.NumCubes = desc.arraySize > 0 ? std::max<uint32_t>(desc.arraySize / 6u, 1u) : 1u;
break;
case D3D12_SRV_DIMENSION_TEXTURE2DMS:
case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY:
break;
case D3D12_SRV_DIMENSION_TEXTURE2D:
default:
srvDesc.Texture2D.MostDetailedMip = desc.mipLevel;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.PlaneSlice = desc.planeSlice;
break;
}
auto heap = std::make_unique<D3D12DescriptorHeap>();
if (!heap->Initialize(m_device.Get(), DescriptorHeapType::CBV_SRV_UAV, 1, false)) {
@@ -1087,6 +1179,9 @@ RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, cons
}
view->InitializeAsShaderResource(m_device.Get(), resource, &srvDesc, heap.get(), 0);
if (IsDepthFormat(format)) {
view->SetFormat(format);
}
view->SetOwnedHeap(std::move(heap));
return view;