Compute Shader

Started by
6 comments, last by terryeverlast 8 years, 3 months ago

I have some typed buffers.

Two float3 input buffers and a float output buffer.

I've tried


Buffer<float3>gInputA;
Buffer<float3>gInputB;
Buffer<float>gOutput;


[numthreads(64, 1, 1)]
void CS(int dtid : SV_DispatchThreadID)
{
	gOutput[dtid.x] = gInputA[dtid.x].x + gInputB[dtid.x].x;
	
}

All I want to do is add the x value of gInputA and gInputB into a single float output buffer;

what would be the correct syntax to work?

Advertisement
gOutput should be RWBuffer<float>.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

// You are reading them only - could be binded as SRV

Buffer<float3> gInputA : register(t0);
Buffer<float3> gInputB : register(t1);

// Both read and write access allowed. Should be binded as UAV
RWBuffer<float> gOutput : register(u0);

gOutput should be RWBuffer<float>.

Sorry. Accidentally downvoted this sad.png

The missing RW in the OP's code is likely the problem.

Ok thank you that makes it compile. but im not getting the right results.

Im adding to buffers in a loop. so they should go in the order 0,2,4,6,8,10.. and so on

im getting

(0,0,0)

(2,2,2)

(4,4,6) <--the six should be four

(6,8,8) <-- the two eights should be 6

I think it is using the DXGI_FORMAT_R32G32B32A32_FLOAT;

but my float is float3 , so it should be DXGI_FORMAT_R32G32B32_FLOAT;

when I use DXGI_FORMAT_R32G32B32_FLOAT , I get all zeros

here is my code


void VecAddApp::BuildBuffersAndViews()
{
	std::vector<Data> dataA(mNumElements);
	std::vector<Data> dataB(mNumElements);
	for(int i = 0; i < mNumElements; ++i)
	{
		dataA[i].v1 = XMFLOAT3(i, i, i);
		

		dataB[i].v1 = XMFLOAT3(i,i, i);
	
	}

	// Create a buffer to be bound as a shader input (D3D11_BIND_SHADER_RESOURCE).
	D3D11_BUFFER_DESC inputDesc;
    inputDesc.Usage = D3D11_USAGE_DEFAULT;
    inputDesc.ByteWidth = sizeof(Data) * mNumElements;
    inputDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    inputDesc.CPUAccessFlags = 0;
	inputDesc.StructureByteStride = sizeof(Data);
    inputDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;

    D3D11_SUBRESOURCE_DATA vinitDataA;
    vinitDataA.pSysMem = &dataA[0];

	ID3D11Buffer* bufferA = 0;
    HR(md3dDevice->CreateBuffer(&inputDesc, &vinitDataA, &bufferA));

	D3D11_SUBRESOURCE_DATA vinitDataB;
    vinitDataB.pSysMem = &dataB[0];

	ID3D11Buffer* bufferB = 0;
    HR(md3dDevice->CreateBuffer(&inputDesc, &vinitDataB, &bufferB));

	// Create a read-write buffer the compute shader can write to (D3D11_BIND_UNORDERED_ACCESS).
	D3D11_BUFFER_DESC outputDesc;
    outputDesc.Usage = D3D11_USAGE_DEFAULT;
    outputDesc.ByteWidth = sizeof(Data) * mNumElements;
    outputDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
    outputDesc.CPUAccessFlags = 0;
	outputDesc.StructureByteStride = sizeof(Data);
    outputDesc.MiscFlags = 0;

    HR(md3dDevice->CreateBuffer(&outputDesc, 0, &mOutputBuffer));

	// Create a system memory version of the buffer to read the results back from.
	outputDesc.Usage = D3D11_USAGE_STAGING;
	outputDesc.BindFlags = 0;
	outputDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	HR(md3dDevice->CreateBuffer(&outputDesc, 0, &mOutputDebugBuffer));


	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
	srvDesc.Format = DXGI_FORMAT_UNKNOWN;
	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
	srvDesc.BufferEx.FirstElement = 0;
	srvDesc.BufferEx.Flags = 0;
	srvDesc.BufferEx.NumElements = mNumElements;

    md3dDevice->CreateShaderResourceView(bufferA, &srvDesc, &mInputASRV);
	md3dDevice->CreateShaderResourceView(bufferB, &srvDesc, &mInputBSRV);


	D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
	uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
	uavDesc.Buffer.FirstElement = 0;
	uavDesc.Buffer.Flags = 0;
	uavDesc.Buffer.NumElements = mNumElements;

	md3dDevice->CreateUnorderedAccessView(mOutputBuffer, &uavDesc, &mOutputUAV);


	// Views hold references to buffers, so we can release these.
	ReleaseCOM(bufferA);
	ReleaseCOM(bufferB);
}

and my shader


struct Data
{
	float3 v1;
	float2 v2;
};

StructuredBuffer<Data> gInputA;
StructuredBuffer<Data> gInputB;
RWBuffer<float3> gOutput;


[numthreads(32, 1, 1)]
void CS(int3 dtid : SV_DispatchThreadID)
{
	gOutput[dtid.x] = gInputA[dtid.x].v1 + gInputB[dtid.x].v1;
	
}

technique11 VecAdd
{
    pass P0
    {
		SetVertexShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, CS() ) );
    }
}



void VecAddApp::DoComputeWork()
{
	D3DX11_TECHNIQUE_DESC techDesc;

	Effects::VecAddFX->SetInputA(mInputASRV);
	Effects::VecAddFX->SetInputB(mInputBSRV);
	Effects::VecAddFX->SetOutput(mOutputUAV);

	Effects::VecAddFX->VecAddTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
	{
		ID3DX11EffectPass* pass = Effects::VecAddFX->VecAddTech->GetPassByIndex(p);
		pass->Apply(0, md3dImmediateContext);

		md3dImmediateContext->Dispatch(1, 1, 1);
	}

	// Unbind the input textures from the CS for good housekeeping.
	ID3D11ShaderResourceView* nullSRV[1] = { 0 };
	md3dImmediateContext->CSSetShaderResources( 0, 1, nullSRV );

	// Unbind output from compute shader (we are going to use this output as an input in the next pass, 
	// and a resource cannot be both an output and input at the same time.
	ID3D11UnorderedAccessView* nullUAV[1] = { 0 };
	md3dImmediateContext->CSSetUnorderedAccessViews( 0, 1, nullUAV, 0 );

	// Disable compute shader.
	md3dImmediateContext->CSSetShader(0, 0, 0);

	std::ofstream fout("results.txt");

	// Copy the output buffer to system memory.
	md3dImmediateContext->CopyResource(mOutputDebugBuffer, mOutputBuffer);

	// Map the data for reading.
	D3D11_MAPPED_SUBRESOURCE mappedData; 
    md3dImmediateContext->Map(mOutputDebugBuffer, 0, D3D11_MAP_READ, 0, &mappedData);

	Data* dataView = reinterpret_cast<Data*>(mappedData.pData);

	for(int i = 0; i < mNumElements; i++)
	{
		fout << "(" << dataView[i].v1.x << ", " << dataView[i].v1.y <<  "," << dataView[i].v1.z << ")" << std::endl;
	}

    md3dImmediateContext->Unmap(mOutputDebugBuffer, 0);

	fout.close();
}

RWBuffer<float3> gOutput;

Try switching from float3 to float4 ?

DXGI_FORMAT_R32G32B32_FLOAT isn't valid for generic UAVs. Use a structured buffer instead.

Ok thx everyone. I got it working with a float4

This topic is closed to new replies.

Advertisement