diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 97c605fb8..25f45c7c9 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -2338,10 +2338,12 @@ bool WrappedID3D12Device::Serialise_WriteToSubresource(SerialiserType &ser, ID3D } else { - UINT width = UINT(desc.Width); - UINT height = desc.Height; + UINT width = RDCMAX(1U, UINT(desc.Width) >> Subresource); + UINT height = RDCMAX(1U, desc.Height >> Subresource); // only 3D textures have a depth, array slices are separate subresources. - UINT depth = (desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? desc.DepthOrArraySize : 1); + UINT depth = (desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D + ? RDCMAX(1U, UINT(desc.DepthOrArraySize) >> Subresource) + : 1); // if we have a box, use its dimensions if(pDstBox) diff --git a/util/test/demos/d3d12/d3d12_write_subresource.cpp b/util/test/demos/d3d12/d3d12_write_subresource.cpp index 3469de91a..51e48b1c6 100644 --- a/util/test/demos/d3d12/d3d12_write_subresource.cpp +++ b/util/test/demos/d3d12/d3d12_write_subresource.cpp @@ -69,6 +69,9 @@ float4 main(v2f IN) : SV_Target0 D3D12_STATIC_SAMPLER_DESC staticSamp = {}; staticSamp.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; staticSamp.AddressU = staticSamp.AddressV = staticSamp.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + // LOD is clamped to 0 since input SRV has multiple mips for subresource-modification + // validation, but only the first one is considered as output result. + staticSamp.MinLOD = staticSamp.MaxLOD = 0; staticSamp.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; ID3D12RootSignaturePtr sig = MakeSig( @@ -86,11 +89,15 @@ float4 main(v2f IN) : SV_Target0 heap.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; heap.Type = D3D12_HEAP_TYPE_CUSTOM; - uint32_t *texData = new uint32_t[2048 * 2084]; + const size_t width = 2048, height = 2048; + const UINT subresourceIdx = 8; - ID3D12ResourcePtr tex = MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM, 2048, 2048) + uint32_t *baseData = new uint32_t[width * height]; + uint32_t *subresourceData = new uint32_t[(width * height) >> (2 * subresourceIdx)]; + + ID3D12ResourcePtr tex = MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM, width, height) .CustomHeap(heap) - .Mips(1) + .Mips(12) .InitialState(D3D12_RESOURCE_STATE_COMMON); D3D12_GPU_DESCRIPTOR_HANDLE view = @@ -102,15 +109,36 @@ float4 main(v2f IN) : SV_Target0 GPUSync(); - tex->Map(0, NULL, NULL); + { + const size_t rowPitch = width * sizeof(uint32_t), depthPitch = rowPitch * height; - memset(texData, 0, 2048 * 2048 * sizeof(uint32_t)); - tex->WriteToSubresource(0, NULL, texData, 1024 * 4, 1024 * 1024); - D3D12_BOX box = {400, 400, 0, 1600, 1600, 1}; - memset(texData, 0xff, 2048 * 2048 * sizeof(uint32_t)); - tex->WriteToSubresource(0, &box, texData, 1024 * 4, 1024 * 1024); + tex->Map(0, NULL, NULL); - tex->Unmap(0, NULL); + memset(baseData, 0x00, depthPitch); + tex->WriteToSubresource(0, NULL, baseData, rowPitch, depthPitch); + + D3D12_BOX box = {400, 400, 0, 1600, 1600, 1}; + memset(baseData, 0xff, depthPitch); + tex->WriteToSubresource(0, &box, baseData, rowPitch, depthPitch); + + tex->Unmap(0, NULL); + } + + { + const size_t rowPitch = (width >> subresourceIdx) * sizeof(uint32_t), + depthPitch = rowPitch * (height >> subresourceIdx); + + tex->Map(subresourceIdx, NULL, NULL); + + memset(subresourceData, 0x00, depthPitch); + tex->WriteToSubresource(subresourceIdx, NULL, subresourceData, rowPitch, depthPitch); + + D3D12_BOX box = {1, 1, 0, 7, 7, 1}; + memset(subresourceData, 0xff, depthPitch); + tex->WriteToSubresource(subresourceIdx, &box, subresourceData, rowPitch, depthPitch); + + tex->Unmap(subresourceIdx, NULL); + } GPUSync();