Jump to content
  • Advertisement
GreenGodDiary

DX11 Rendering CS output to backbuffer [SOLVED]

Recommended Posts

SOLVED: I had written 

Dispatch(32, 24, 0)

instead of

Dispatch(32, 24, 1)

 

 

I'm attempting to implement some basic post-processing in my "engine" and the HLSL part of the Compute Shader and such I think I've understood, however I'm at a loss at how to actually get/use it's output for rendering to the screen.

Assume I'm doing something to a UAV in my CS:

RWTexture2D<float4> InputOutputMap : register(u0);

I want that texture to essentially "be" the backbuffer.

 

I'm pretty certain I'm doing something wrong when I create the views (what I think I'm doing is having the backbuffer be bound as render target aswell as UAV and then using it in my CS):
 

	DXGI_SWAP_CHAIN_DESC scd;
	ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

	scd.BufferCount = 1;                                   
	scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;     
	scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_UNORDERED_ACCESS;
	scd.OutputWindow = wndHandle;  
	scd.SampleDesc.Count = 1;  
	scd.Windowed = TRUE; 
						
	HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL,
		D3D_DRIVER_TYPE_HARDWARE,
		NULL,
		NULL,
		NULL,
		NULL,
		D3D11_SDK_VERSION,
		&scd,
		&gSwapChain,
		&gDevice,
		NULL,
		&gDeviceContext);

	// get the address of the back buffer
	ID3D11Texture2D* pBackBuffer = nullptr;
	gSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

	// use the back buffer address to create the render target
	gDevice->CreateRenderTargetView(pBackBuffer, NULL, &gBackbufferRTV);

	// set the render target as the back buffer
	CreateDepthStencilBuffer();

	gDeviceContext->OMSetRenderTargets(1, &gBackbufferRTV, depthStencilView);

	//UAV for compute shader
	D3D11_UNORDERED_ACCESS_VIEW_DESC uavd;
	ZeroMemory(&uavd, sizeof(uavd));

	uavd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	uavd.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
	uavd.Texture2D.MipSlice = 1;
		
	gDevice->CreateUnorderedAccessView(pBackBuffer, &uavd, &gUAV);

	pBackBuffer->Release();

 

After I render the scene, I dispatch like this:


	gDeviceContext->OMSetRenderTargets(0, NULL, NULL);
	m_vShaders["cs1"]->Bind();
	gDeviceContext->CSSetUnorderedAccessViews(0, 1, &gUAV, 0);
	gDeviceContext->Dispatch(32, 24, 0); //hard coded

	ID3D11UnorderedAccessView* nullview = { nullptr };
	gDeviceContext->CSSetUnorderedAccessViews(0, 1, &nullview, 0);
	gDeviceContext->OMSetRenderTargets(1, &gBackbufferRTV, depthStencilView);

	gSwapChain->Present(0, 0);

Worth noting is the scene is rendered as usual, but I dont get any results from the CS (simple gaussian blur)

I'm sure it's something fairly basic I'm doing wrong, perhaps my understanding of render targets / views / what have you is just completely wrong and my approach just makes no sense.

If someone with more experience could point me in the right direction I would really appreciate it!

On a side note, I'd really like to learn more about this kind of stuff. I can really see the potential of the CS aswell as rendering to textures and using them for whatever in the engine so I would love it if you know some good resources I can read about this!

Thank you <3

 

P.S I excluded the .hlsl since I cant imagine that being the issue, but if you think you need it to help me just ask


P:P:S. As you can see this is my first post however I do have another account, but I can't log in with it because gamedev.net just keeps asking me to accept terms and then logs me out when I do over and over

Edited by GreenGodDiary
solved

Share this post


Link to post
Share on other sites
Advertisement

Update:

Been trying to figure it out on my own, using Graphics Debugging in VStudio shows that the UAV and resource are correct in the CS, but the history for the resource shows that the Dispatch-call writes to it but doesnt change it (i think?)

91096550af06934ec00d0b4548a1a67b.png

 

So, maybe it is my shader code after all?

It is taken from Practical Rendering and Computation with Direct3D 11 with minimal change, since their version used a separate input resource (SRV), while I use the UAV for both input and output.
Anyway here's the shader:

// Declare the input and output resources
//Texture2D<float4> InputMap : register(t0);
RWTexture2D<float4> InputOutputMap : register(u0);

// Group size
#define size_x 32
#define size_y 32
  
// Declare the filter kernel coefficients
static const float filter[7][7] = {
	0.000904706, 0.003157733, 0.00668492, 0.008583607, 0.00668492,
	0.003157733, 0.000904706,
	0.003157733, 0.01102157, 0.023332663, 0.029959733, 0.023332663,
	0.01102157, 0.003157733,
	0.00668492, 0.023332663, 0.049395249, 0.063424755, 0.049395249,
	0.023332663, 0.00668492,
	0.008583607, 0.029959733, 0.063424755, 0.081438997, 0.063424755,
	0.029959733, 0.008583607,
	0.00668492, 0.023332663, 0.049395249, 0.063424755, 0.049395249,
	0.023332663, 0.00668492,
	0.003157733, 0.01102157, 0.023332663, 0.029959733, 0.023332663,
	0.01102157, 0.003157733,
	0.000904706, 0.003157733, 0.00668492, 0.008583607, 0.00668492,
	0.003157733, 0.000904706
};
// Declare one thread for each texel of the current block size.
[numthreads(size_x, size_y, 1)]
void CS_main(uint3 DispatchThreadID : SV_DispatchThreadID)
{
		//Offset the texture location to the first sample location
		int3 texturelocation = DispatchThreadID - int3(3, 3, 0);
  
		//Initialize the output value to zero, then loop through the
		// filter samples, apply them to the image samples, and sum
		// the results.
		float4 Color = float4(0.0, 0.0, 0.0, 0.0);
		for (int x = 0; x < 7; x++)
		{
			for (int y = 0; y < 7; y++)
			{
				Color += InputOutputMap.Load(texturelocation + int3(x, y, 0)) * filter[x][y];
			}
		}
		// Write the output to the output resource
		InputOutputMap[DispatchThreadID.xy] = Color;
}


It looks good to me and it compiles fine, and it might be, but something I'm obviously doing wrong.

Another thing the Graphics Debugger tells me is this:

da99e38065b911d70fdc7f6b9eefc25f.png

 

No effect: makes little sense to me, looking at my shader code.
Occluded: how? I do not touch the resource after the Dispatch, and since im explicitly overwriting every pixel I dont see how it could become occluded from any previous operations.

Any pointers appreciated!

Share this post


Link to post
Share on other sites

Small note: ZeroMemory was introduced for C# programmers wanting to write C++, you can just do = {}; (braced initializer) as well.

Edited by matt77hias

Share this post


Link to post
Share on other sites
4 hours ago, matt77hias said:

Small note: ZeroMemory was introduced for C# programmers wanting to write C++, you can just do = {}; (braced initializer) as well.

Good to know! Thanks :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • 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!