Search code examples
directx-12direct3d12

Direct x 12 image flickering on Intel graphic hard


I have a weird issue only happening on my Intel HD Graphics 530

When rendering an image, some pixels color randomly change. See the following image: Bug

For the problematic pixels, the graphics debugger show that the color outputted from the graphics pipeline is the correct one. But the pixel displayed color is wrong. See: Debugger

From my investigations i have found that these pixels seems using information from the materials of the others. My materials information is handled by a descriptor heap. So the switch between graphics root descriptor table in my rendering loop seems to be my problem (when i only draw one object everything is fine)

Here the code snippet i use:

void ForwardLighningEffect::pushCommands(ForwardLigthningPushArgs data, ID3D12GraphicsCommandList* commandList, int frameIndex) {

// set PSO
commandList->SetPipelineState(m_mainPipelineStateObject);

// set root signature
commandList->SetGraphicsRootSignature(m_rootSignature);

// set constant buffer view
commandList->SetGraphicsRootConstantBufferView(0, m_constantBufferUploadHeaps[frameIndex]->GetGPUVirtualAddress());

const auto& meshes = data.model->getMeshes();
for (auto mesh : meshes)
{
    if (auto materialHandle = mesh->material.lock()) // get material handle from weak ptr.
    {
        ID3D12DescriptorHeap * matDescriptorHeap = materialHandle->material.descriptorHeap;

        // set the material descriptor heap
        ID3D12DescriptorHeap* descriptorHeaps[] = { matDescriptorHeap };
        commandList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);

        // HERE ! set the descriptor table to the descriptor heap (parameter 1, as constant buffer root descriptor is parameter index 0)
        commandList->SetGraphicsRootDescriptorTable(1, matDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
    }

    commandList->IASetVertexBuffers(0, 1, &mesh->vertexBuffer.bufferView);
    commandList->IASetIndexBuffer(&mesh->indexBuffer.bufferView);

    for (auto camera : data.cameras)
    {
        updateConstantBuffer(camera, frameIndex);

        // Draw mesh.
        commandList->DrawIndexedInstanced(mesh->nbIndices, 1, 0, 0, 0);
    }
}

}

Whats wrong ?


Solution

  • Found a solution. Updating textures state when not used fixed it.

    So when binding a texture:

    commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(/*textureResource*/, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
    

    After use then reset state:

    commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(/*textureResource*/, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COMMON));