Count elements in texture

Viewed 64

I have a 3D texture of 32-bit unsigned integers initialized with zeroes. It is defined as follows:

D3D11_TEXTURE3D_DESC description{};
description.Format = DXGI_FORMAT_R32_UINT;
description.Usage = D3D11_USAGE_DEFAULT;
description.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
description.CpuAccessFlags = 0;
description.MipLevels = 1;
description.Width = ...;
description.Height = ...;
description.Depth = ...;

I am writing to this texture in a compute shader to set a bit on specified position if a certain condition is fulfilled:

RWTexture3D<uint> txOutput : register(u0)

cbuffer InputBuffer : register(b0)
{
    uint position;
    /** other elements **/
}

#define SET_BIT(value, position) value |= (1U << position)

[numthreads(8, 8, 8)]
void main(uint3 threadID : SV_DispatchThreadID)
{
    if(/** some condition **/)
    {
        uint value = txOutput[threadID];
        SET_BIT(value, position);
        txOutput[threadID] = value;
    }
}

I need to know how many elements of this texture is filled at a certain bit position in a code behind in C++. How could this be done?

2 Answers

You will have to read back the texture to the cpu with the ID3D11DeviceContext::Map API https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-map

You will get out a void* you will cast to uint32_t* which will point to the start of your data.

You need to get better a looking up the DirectX documentation, its really quite good documentation. There are a lot harder things you will need to find in the documentation if you keep doing 3D graphics.

Edit: I use DirectML to do these tasks now, only using compute shaders for exotic work.


When I need to readback to the cpu I always accumulate on the cpu, because accumulating on the gpu is difficult and only partially parallel.

Summing a texture on the gpu is call a parallel reduction and this type of programming is called general purpose gpu (gpgpu). The most excellent resource on gpgpu for Direct Compute are these slides from nvidia, which go through optimizing parallel reductions https://on-demand.gputechconf.com/gtc/2010/presentations/S12312-DirectCompute-Pre-Conference-Tutorial.pdf

From the slides:

for (unsigned int s=groupDim_x/2; s>0; s>>=1)
{
    if (tid < s)
    {
        sdata[tid] += sdata[tid + s];
    }
    GroupMemoryBarrierWithGroupSync();
}

enter image description here

Related