LukasBanana / LLGL

Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal
BSD 3-Clause "New" or "Revised" License
2.07k stars 140 forks source link

D3D12 Validation error on mipmap generation #125

Open st0rmbtw opened 3 months ago

st0rmbtw commented 3 months ago

I get this validation error after the CreateTexture method call when the texture has the GenerateMips flag.

D3D12 ERROR: GPU-BASED VALIDATION: Dispatch, Incompatible resource state: Resource: 0x0000018B9A5CF520:'Unnamed ID3D12Resource Object', Subresource Index: [0], Descriptor heap index to DescriptorTableStart: [0], Descriptor heap index FromTableStart: [0], Binding Type In Descriptor: SRV, Resource State: D3D12_RESOURCE_STATE_UNORDERED_ACCESS(0x8), Index of Descriptor Range: 0, Shader Stage: COMPUTE, Root Parameter Index: [1], Dispatch Index: [0], Shader Code: <debug info not available>, Asm Instruction Range: [0x190-0x1c3], Asm Operand Index: [3], Command List: 0x0000018B997CF880:'Unnamed ID3D12GraphicsCommandList Object', SRV/UAV/CBV Descriptor Heap: 0x0000018B9A782D90:'Unnamed ID3D12DescriptorHeap Object', Sampler Descriptor Heap: <not set>, Pipeline State: 0x0000018B99F73800:'Unnamed ID3D12PipelineState Object',  [ EXECUTION ERROR #942: GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE]

The error occurs after the Dispatch method call here: https://github.com/LukasBanana/LLGL/blob/2232eb6eb37b08097ef147d68ae2baf9f120668e/sources/Renderer/Direct3D12/Texture/D3D12MipGenerator.cpp#L282-L286

P.S. Here's the texture descriptor:

LLGL::TextureDescriptor texture_desc;
texture_desc.type = LLGL::TextureType::Texture2DArray;
texture_desc.extent = LLGL::Extent3D(width, height, 1);
texture_desc.arrayLayers = layers;
texture_desc.bindFlags = LLGL::BindFlags::Sampled | LLGL::BindFlags::ColorAttachment;
texture_desc.cpuAccessFlags = 0;
texture_desc.miscFlags = LLGL::MiscFlags::GenerateMips;
LukasBanana commented 3 months ago

This is a known issue and needs a larger refactor in the D3D12 backend for resource state transitioning. Unfortunately, this type of resource transitioning for Mip generation is implemented this way even in Microsoft's MiniEngine example: https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/MiniEngine/Core/ColorBuffer.cpp#L172

What we can do in the short term is to silence this validation notification until the resource state transitioning is more precise, i.e. works on a per-subresource level rather than a per-resource level. I assume that would be D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE which we can add here at D3D12Device.cpp:192.