Jump to content
  • Advertisement
Sign in to follow this  
terryeverlast

Compute Shader

This topic is 915 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

 

 

 

 

Share this post


Link to post
Share on other sites
Advertisement

gOutput should be RWBuffer<float>.

Sorry. Accidentally downvoted this sad.png

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

Share this post


Link to post
Share on other sites

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();
}
Edited by terryeverlast

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!