Rendering CS output to backbuffer [SOLVED]

Started by
3 comments, last by GreenGodDiary 6 years, 5 months ago

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

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!

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

🧙

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 :)

This topic is closed to new replies.

Advertisement