🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

RWStructuredBuffer werid behaviour

Started by
2 comments, last by NullptrDzh 4 years, 1 month ago

Hello All,

I am writing a compute shader that calculating Grid frustum for my tiled forwarding rendering demo using Directx12. However, I am having a very strange issue of writing results to my RWStructedBuffer with a Frustum type, where all planes of a frustum share the exactly the same plane information. (I am pretty sure I can correctly calculate the plane information for left, right, top, and bottom planes of a frustum.)

My Frustum structure declaration is the following:

struct Plane
{
    float3 N;   // Plane normal.
    float  d;   // Distance to origin.
};

// Four planes of a view frustum (in view space).
// The planes are:
//  * Left,
//  * Right,
//  * Top,
//  * Bottom.
// The back and/or front planes can be computed from depth values in the 
// light culling compute shader.
struct Frustum
{
    Plane planes[4];   // left, right, top, bottom frustum planes.
};

These two structures are declared in CommonIncl.hlsl file.

In the actual hlsl file that compute the grid frustum, I wrote a few lines of codes that just try to assign four planes of a frustum different values and store the frustum in my RWStructuredBuffer using the following codes:

#include "CommonIncl.hlsl"


// ...skip some extra codes

struct test2
{
    float4 p[4];
};

RWStructuredBuffer<Frustum> out_Frustums : register(u0);
RWStructuredBuffer<test2> debugUAV : register(u1);

// Calculate the view frustum for each tiled in the view space
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
void CS_GridFrustumPass(ComputeShaderInput Input)
{
    const float3 eyePos = float3(0.0f, 0.0f, 0.0f);

    uint tiledBlockSize = BLOCK_SIZE;
    // Compute 4 points on the far clipping plane to use as the frustum vertices
    float4 tiledVerticesInScreenSpace[4];
    tiledVerticesInScreenSpace[0] = float4(Input.dispatchThreadID.xy * tiledBlockSize, -1.0f, 1.0f);
    tiledVerticesInScreenSpace[1] = float4(float2(Input.dispatchThreadID.x + 1, Input.dispatchThreadID.y) * tiledBlockSize, -1.0f, 1.0f);
    tiledVerticesInScreenSpace[2] = float4(float2(Input.dispatchThreadID.x, Input.dispatchThreadID.y + 1) * tiledBlockSize, -1.0f, 1.0f);
    tiledVerticesInScreenSpace[3] = float4(float2(Input.dispatchThreadID.x + 1, Input.dispatchThreadID.y + 1) * tiledBlockSize, -1.0f, 1.0f);


    float3 tiledVerticesInViewSpace[4];
    [unroll]
    for (int i = 0; i < 4; ++i)
    {
        tiledVerticesInViewSpace[i] = ScreenToView(tiledVerticesInScreenSpace[i]).xyz;
    }

    // Build the frustum planes from the view space points
    Frustum frustum;

    frustum.planes[0].N = float3(0.0f, 1.0f, 0.0f);
    frustum.planes[0].d = 0;
    frustum.planes[1].N = float3(0.0f, 2.0f, 0.0f);
    frustum.planes[1].d = 0;
    frustum.planes[2].N = float3(0.0f, 3.0f, 0.0f);
    frustum.planes[2].d = 0;
    frustum.planes[3].N = float3(0.0f, 4.0f, 0.0f);
    frustum.planes[3].d = 0;

    // Store the computed frustum in the output buffer
    if (Input.dispatchThreadID.x < numThreads.x && Input.dispatchThreadID.y < numThreads.y)
    {
        uint idx = Input.dispatchThreadID.x + (Input.dispatchThreadID.y * numThreads.x);

        out_Frustums[idx] = frustum;
        
        // Another case when the type of RWStructuredBuffer is test2
        //test2 tt;
        //tt.p[0] = float4(1, 1, 1, 1);
        //tt.p[1] = float4(2, 2, 2, 2);
        //tt.p[2] = float4(3, 3, 3, 3);
        //tt.p[3] = float4(4, 4, 4, 4);
        //debugUAV[idx] = tt;

    }
}

With the RWStructuredBuffer<Frustum>, the RenderDoc shows that all planes have the same result as plane[0] in a frustum. However, with the RWStructuredBuffer<test2>, the RenderDoc shows that all planes have the desired values, which is p[0] = {1,1,1,1}, p[1]={2,2,2,2},p[2]={3,3,3,3} and p[3]={4,4,4,4}.

I am very confused about what I just observed and I am not sure what cause this issue. Does that means we cannot use a nested structure for the type of my RWStructuredBuffer?

(PS: I think the creation of this RWStructuredBuffer should be correct in my code.)

Best,

Nullptr

Advertisement

NullptrDzh said:
I am very confused about what I just observed and I am not sure what cause this issue. Does that means we cannot use a nested structure for the type of my RWStructuredBuffer?

Hi, I think you have problem with alignments. Try to use:

typedef float4 Plane;

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

@AndreyVK_D3D Hi Andrey,

Thank you so much for answering my question. Yes, your solution works and I also tried this in my code to work around this problem. I think what I don't understand is why my Plane structure declaration not work as well as typedef float4 Plane. Would that be a driver issue? I am running my program on a 1080GTX machine and shader model 5.1. I do see people use nested structure without a problem.

Thanks,

This topic is closed to new replies.

Advertisement