Disappearing Data in Structured Buffers

Started by
3 comments, last by safiullahhussaini 11 years, 4 months ago
Hi I am new here so I dont know if this is a common n00b problem.
So I am creating my structured buffer like this

[source lang="cpp"]HRESULT CRenderer::CreateStructuredBuffer ( unsigned int arg_dElementCount, unsigned int arg_dElementSize, void * arg_pData )
{
HRESULT status = S_OK;

D3D11_BUFFER_DESC objBufferDesc;
D3D11_SUBRESOURCE_DATA objInitData;
D3D11_SHADER_RESOURCE_VIEW_DESC objResViewDesc;
ZeroMemory(&objBufferDesc, sizeof(objBufferDesc));
ZeroMemory(&objInitData, sizeof(objInitData));
ZeroMemory(&objResViewDesc, sizeof(objResViewDesc));

objBufferDesc.ByteWidth = arg_dElementCount * arg_dElementSize;
objBufferDesc.StructureByteStride = arg_dElementSize;
objBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;

objBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
objBufferDesc.Usage = D3D11_USAGE_DEFAULT;
objBufferDesc.CPUAccessFlags = 0;

objInitData.pSysMem = arg_pData;

this->m_dxStructuredBufferArray.push_back ( NULL );

status = this->m_dxDevice->CreateBuffer (
&objBufferDesc,
&objInitData,
&(this->m_dxStructuredBufferArray[this->m_dNumOfStructuredBuffers++])
);
if (FAILED(status))
{
return status;
}

objResViewDesc.Format = DXGI_FORMAT_UNKNOWN;
objResViewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
objResViewDesc.Buffer.ElementOffset = 0;
objResViewDesc.Buffer.ElementWidth = arg_dElementSize;
objResViewDesc.Buffer.FirstElement = 0;
objResViewDesc.Buffer.NumElements = arg_dElementCount;

this->m_dxResourceViews.push_back ( NULL );

status = this->m_dxDevice->CreateShaderResourceView (
this->m_dxStructuredBufferArray[this->m_dNumOfStructuredBuffers-1],
&objResViewDesc,
&(this->m_dxResourceViews[this->m_dNumOfStructuredBuffers-1])
);
if (FAILED(status))
{
return status;
}

return status;
}[/source]

And I am calling it like this

[source lang="cpp"] status = objRenderer.CreateStructuredBuffer ( objWorldReader.GetInstanceCount ( ), sizeof(SInstance), objWorldReader.GetInstances ( ) );
if ( FAILED(status) )
return 1;
[/source]

But it seems when I view the buffer in PIX in a simple passthrough Shader, I just see zeros. Now I know the structure may need to be 16 byte aligned since I encountered a similar problem before, so I have declared my structure like this.

[source lang="cpp"]struct SInstance
{
__declspec(align(16)) XMMATRIX matLocation;
int dTemplateType;
};
[/source]
But now I really dont know what's going on and I am really out of my depth. Please Help!!!!
Advertisement
This isn't your problem, but you don't need to set the "ElementOffset" or "ElementWidth" members of D3D11_BUFFER_SRV. The structure is defined like this:


typedef struct D3D11_BUFFER_SRV
{
union
{
UINT FirstElement;
UINT ElementOffset;
} ;
union
{
UINT NumElements;
UINT ElementWidth;
} ;
} D3D11_BUFFER_SRV;


Since they're in unions, you can only set one or the other in each union pair. For a structured buffer you want to use "FirstElement" and "NumElements".

Anyway, I suspect your problem is with your C++ struct. If you check sizeof(SInstance), you'll find that it's 80 bytes in size. This is because the alignment requirements of XMMATRIX (XMMATRIX is already 16-byte aligned, you don't need to add the alignment manually) will cause the struct to have 16-byte alignment, which will cause the compiler to insert 12 bytes of padding after dTemplateType. However if you were to declare something like this in HLSL..


struct SInstance
{
float4x4 matLocation;
int dTemplateType;
};


...this struct will be 68 bytes in size. Structs for structured buffers don't have 16-byte alignment requirements, that was an incorrect assumption on your part. HLSL really only works in terms of 4-byte values, so structs used for structured buffers will pretty much always have 4-byte alignment. If you stick to using 4-byte types in your C++ struct, you should be fine. This means you should avoid the DirectXMath SIMD types like XMVECTOR and XMMATRIX, since they have 16-byte alignment. Try changing your struct to this:


struct SInstance
{
XMFLOAT4x4 matLocation;
int dTemplateType;
};


If you do this, the stride of your structured buffer should match the stride expected by your shader. If you have a mismatched stride, the runtime will transparently set your buffer to NULL which will cause you to get 0's when your shader attempts to access it. If you create the device with the DEBUG flag, the runtime will output an error message to tell you that this has occurred.
Just Mad the changes but no luck... Right now, my ElementCount is 1, is that a problem?
This is the PIX report on my vertex shader, seems like the Buffer is binding correctly (At least the strides match).

[source lang="java"]//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
//
// Buffer Definitions:
//
// Resource bind info for VertexBuffer
// {
//
// struct
// {
//
// float4 position; // Offset: 0
// float4 color; // Offset: 16
//
// } $Element; // Offset: 0 Size: 32
//
// }
//
// Resource bind info for InstanceBuffer
// {
//
// struct
// {
//
// float4x4 matLocation; // Offset: 0
// int strTemplateType; // Offset: 64
//
// } $Element; // Offset: 0 Size: 68
//
// }
//
//
// Resource Bindings:
//
// Name Type Format Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// VertexBuffer texture struct r/o 0 1
// InstanceBuffer texture struct r/o 1 1
//
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------ ------
// SV_VERTEXID 0 x 0 VERTID uint x
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------ ------
// SV_POSITION 0 xyzw 0 POS float xyzw
// COLOR 0 xyzw 1 NONE float xyzw
//
vs_4_0
dcl_globalFlags refactoringAllowed | enableRawAndStructuredBuffers
dcl_resource_structured t0, 32
dcl_resource_structured t1, 68
dcl_input_sgv v0.x, vertex_id
dcl_output_siv o0.xyzw, position
dcl_output o1.xyzw

#line 82 "C:\Users\Safiullah\Documents\Visual Studio 2010\Projects\RayTracingAttempt\Debug\RTShaders.fx"
ld_structured o0.xyzw, v0.x, l(0), t0.xyzw // VS<0,1,2,3>
ld_structured o1.x, l(0), l(0), t1.xxxx // VS<4>
ld_structured o1.y, l(0), l(20), t1.xxxx // VS<5>
ld_structured o1.z, l(0), l(40), t1.xxxx // VS<6>
ld_structured o1.w, l(0), l(60), t1.xxxx // VS<7>

#line 105
ret
// Approximately 6 instruction slots used
[/source]
Problem fixed, it was a rokkie mistake I suppose, I was not properly setting the Resources to the Shader... or something like that.

Thanks a bunch MJP... BTW your book is AWESOME!!!

This topic is closed to new replies.

Advertisement