Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


steven166

Member Since 22 Nov 2011
Online Last Active Today, 05:09 AM

Topics I've Started

How to synchronize in pixel shader with DeviceMemoryBarrier() function?

26 July 2015 - 11:04 PM

I do not know how to use DeviceMemoryBarrier() funcution to to synchronize in a pixel shader. In my situation, if a rasterized fragment has the same object ID (objID) with the current object ID and this object is not shaded, then compute its color.

        for (uint count = 0; count < NumOfObj; count++)
	{	
                // DeviceMemoryBarrier(); 
		if (Fragment.ObjID == Objects[count].ObjID && Shaded[count] == 0)
		{	
                        // DeviceMemoryBarrier();		
                        uint old_val = 0;
                        InterlockedAdd(Shaded[count], 1, old_val);

			// Shading
			break;
		}
	}
        // DeviceMemoryBarrier();

My problem is that an object is shaded twice. I have tried to place DeviceMemoryBarrier() function in many places but it does not work.

 

Is there any idea? Please help me.


result is always null when creating a geometry shader with stream output

18 July 2015 - 08:42 AM

I want to create a geometry shader with a stream output but it always return NULL.

 

HLSL

struct GSOutput
{
	float4 pos : SV_POSITION;
	float2 TextureUV	: TEXCOORD1;	
};

[maxvertexcount(3)]
void main(
	triangle float4 input[3] : SV_POSITION, 
	inout TriangleStream< GSOutput > output
)
{
	for (uint i = 0; i < 3; i++)
	{
		GSOutput element;
		element.pos = input[i];		
		element.TextureUV = float2(0, 0);
		output.Append(element);
	}
	output.RestartStrip();
}

C++

D3D11_SO_DECLARATION_ENTRY pDecl[] =
{		
	{ 0, "SV_POSITION", 0, 0, 4, 0 },
        { 0, "TEXCOORD0", 0, 0, 2, 0 },
};

UINT stride[1] = { 6 * sizeof(float) };

pd3dDevice->CreateGeometryShaderWithStreamOutput(pGSBuffer->GetBufferPointer(), pGSBuffer->GetBufferSize(), pDecl, ARRAYSIZE(pDecl), stride, 1, 0, NULL, &m_pMainStreamOut_GS);

It is okay if I only output a position (float4), but the result is always null when I output more values per-vertex.

 

Please, help me.


How to use the compute shader with a per-pixel linked list.

16 July 2015 - 08:52 AM

- I do not know how to use the compute shader to load all fragments belongs to the current pixel, per-pixel linked list.

 

- In the first pass, all fragments are stored in a uav buffer.

        RWStructuredBuffer< FragmentLink >  FLBuffer        : register(u0);
        RWByteAddressBuffer StartOffsetBuffer                : register(u1);
        
        uint x = input.Position.x;        // [0,g_nFrameWidth]
	uint y = input.Position.y;        // [0,g_nFrameHeight]

	// Create fragment data.
	FragmentLink element;

	element.fragmentData.uv = input.TextureUV;
	element.fragmentData.Depth = input.Position.z;

	if (input.NumOfValues == 2)
		element.fragmentData.FrameInfo = ((input.FrameInfo.x - 0.5f) / input.FrameInfo.y) + 0.5f;
	else // input.TwoVales = 1
		element.fragmentData.FrameInfo = input.FrameInfo.x;

	// Increment and get current pixel count.
	uint nPixelCount = FLBuffer.IncrementCounter();

	// Read and update Start Offset Buffer.
	uint nIndex = y * g_nFrameWidth + x;
	uint nStartOffsetAddress = 4 * nIndex;
	uint nOldStartOffset;

	StartOffsetBuffer.InterlockedExchange(
		nStartOffsetAddress, nPixelCount, nOldStartOffset);

	// Store fragment link.
	element.nNext = nOldStartOffset;
	FLBuffer[nPixelCount] = element;
	

In the compute shader (C++)

md3dImmediateContext->Dispatch(mClientWidth, mClientHeight, 1);

And in the compute shader (HLSL)

void OIT_SortAndRender_CS(uint3 nGid: SV_GroupID, uint3 DTid : SV_DispatchThreadID)
{
	uint iIndex = DTid.y * g_nFrameWidth + DTid.x;

	uint nNext = StartOffsetSRV[iIndex];
	if (nNext == 0xFFFFFFFF) {
		frameBuffer[DTid.xy] = YELLOW;
		return;
	}

	FragmentData aData[TEMPORARY_BUFFER_MAX];
	uint nNumFragment = 0;                                // number of fragments in current pixel's linked list.

	// Read and store linked list data to the temporary buffer.	
	while (nNext != 0xFFFFFFFF && nNumFragment < TEMPORARY_BUFFER_MAX)
	{
		FragmentLink element = FragmentLinkSRV[nNext];
		aData[nNumFragment] = element.fragmentData;

		nNumFragment++;
		nNext = element.nNext;
	}

	if (nNumFragment == 1)
	{		
		frameBuffer[DTid.xy] = BACKGROUND_COLOR;
		return;
	}
	
	frameBuffer[DTid.xy] = GREEN;	
}

A background color is returned if there is only one fragment which belongs to the background. Otherwise, a green color is return. But I only see the background color. I have also tested with a pixel shader, and it is working.

 

Anybody has experience about this problem? Please help me.


a problem with an unordered access view buffer.

16 July 2015 - 05:49 AM

I want to render to the motion blur effect by making a prism which is rasterized to fragments.

 

- In the first pass, transfroming vertices with 2 matrices at the previous ( time t0) and the current frame (time t1) in the vertex shader. In the geometry shader, using 2 triangles to make a prism representing a moving triangle, and a side rectangle is subdivied into 2 triangles for rasterization. In the pixel shader, I just store all fragments into a read/write structured buffer.

 

- Fragment has 6 values, a float4 and an uint2.

 

- In the second pass, I just load all fragments which belongs to the current pixel, and return a color (ex: green).

 

- An error occurs when the camera go inside or near an model. But it is okay when the object is far away.

 

normal

image.jpg

 

Error (go inside a teapot)

loi.jpg

 

Is there anybody has experienced this problem? Please help me.

 

 


How to use geometry shader instances to divide the output data?

16 March 2015 - 07:47 PM

In geometry shader, I want to output about 108 vertices from 3 vertices (a triangle), and each output vertex has 12 scalar values. For example

struct VS_OUTPUT
{
     float4 Pos;
     float2 TextureUV;
     float3 Normal;
     float3 Data;
};

The problem is I cannot output all vertices because of the limitation of geometry shader output which does not allow output more than 1024 registers. Is there possible to use 2 instances of a geometry shader to solve this problem such as the first instance outputs the half of data and the second one outputs the other half?. I have searched on the internet, but there is nothing and have tried it but it does not work.

 

For example

[maxvertexcount(108]
[instance(2)]
GS_OUTPUT GS(triangle VS_OUTPUT input[3], inout TriangleStream<GS_OUTPUT> Output,
	      uint InstanceID : SV_GSInstanceID)
{
       GS_OUTPUT vertex;
       if (InstanceID == 0)
       {
             vertex.Pos = ....
             vertex.TextureUV = ........
       }
       else // InstanceID = 1
       {
             vertex.Normal = ....
             vertex.Data = .....
       }

       // Output data
}

PARTNERS