Search code examples
directxshadertexturesdirectx-11

2d texture always black in compute shader - Directx 11


I am learning directx11 programming and setting up a basic compute shader. My first objective is to just check if compute shader is able to write anything to a 2D texture resource. Relevant code snippets are below:

  1. Buffer creation

    ID3D11Texture2D* ColoredTriangleDemo::create_render_target(ID3D11Device1* Direct3DDevice, int width, int height){
    ID3D11Texture2D* renderTarget;
    D3D11_TEXTURE2D_DESC renderTargetDesc;
    ZeroMemory(&renderTargetDesc, sizeof(renderTargetDesc));
    renderTargetDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
    renderTargetDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    renderTargetDesc.Height = height;
    renderTargetDesc.Width = width;
    renderTargetDesc.ArraySize = 1;
    renderTargetDesc.MipLevels = 1;
    renderTargetDesc.SampleDesc.Count = 1;
    renderTargetDesc.SampleDesc.Quality = 0;
    renderTargetDesc.Usage = D3D11_USAGE_DEFAULT;
    
    HRESULT rt = Direct3DDevice->CreateTexture2D(&renderTargetDesc, NULL, &renderTarget);
    if (FAILED(rt)){
        std::cout << "Error! Render target creation failed for compute shader " << rt << std::endl;
        exit;
    }
    
    //Create UAV for Compute shader
    D3D11_UNORDERED_ACCESS_VIEW_DESC uavCS;
    ZeroMemory(&uavCS, sizeof(uavCS));
    uavCS.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    uavCS.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
    uavCS.Texture2D.MipSlice = 0;
    HRESULT uav = Direct3DDevice->CreateUnorderedAccessView(renderTarget, &uavCS, &mUAVCS);
    if (FAILED(uav)){
        std::cout << "Error! UAV Creation failed for CS " << uav << std::endl;
        exit;
    }
    return renderTarget;
    }
    
  2. Compute shader HLSL code- For now it just writes something to check if the entire setup is working or not

    struct vertexData{
    float4 position;
    float2 texcoord;
    float3 normal;
    int    materialID;
    };
    
    StructuredBuffer<vertexData> vData : register(t0);
    RWTexture2D<float4>          color : register(t1);
    
    cbuffer bufferSize : register(b0){
        int n_input_elements;
        int n_output_x;
        int n_output_y;
        int dummy;
    }
    
    [numthreads (1, 1, 1)]
    void main(uint3 dispatchThreadID : SV_DispatchThreadID){
        for (int i = 0; i < 1000; ++i){
            for (int j = 0; j < 1000; ++j){
                float2 loc = float2(float(i)/1000.f, float(j)/1000.f);
                color[loc.xy] = (i*j) % 2 ? float4(0.5f, 0.6f, 0.7f, 1.f) : float4(0.7f, 0.6f, 0.5f, 1.f);
            }
        }
    }
    
  3. Rendering code in draw method

    ID3D11DeviceContext* direct3DDeviceContext = mGame->Direct3DDeviceContext();
    direct3DDeviceContext->CSSetShader(mComputeShader, nullptr, 0);
    direct3DDeviceContext->CSSetShaderResources(0, 1, &mSRVCS_I);
    direct3DDeviceContext->CSSetUnorderedAccessViews(0, 1, &mUAVCS, NULL);
    
    //Dispatch
    direct3DDeviceContext->Dispatch(1, 1, 1);
    
    Sleep(20);      //Sleep for 100 ms
    

But when I see the 2D texture color in visual studio graphics debugger, I get the default green screen. Is there something I have missed here?

Thanks


Solution

  • I found the error. In ComputeShader code, I was indexing the RWTexture2d (color) using float, while it should have been accessed with uint2.

    So indexing color[loc.xy], loc should be int not float which fixed the problem.