Feeds:
Posts
Comments

download link

Some time ago after wasting another hour on a bug caused by different memory layout in my c++ struct and corresponding const buffer I figured it would be quite easy to write a simple validator using shader reflection and some basic static c++ reflection. I wrote it and it worked quite good so here is the source code in case anyone has a similar problem. The code is stripped from my framework. I’ve also made a quick sample project that shows how to print and compare struct and cbuffer layout. It’s very simple. This is how to get and print const bufffer info:

CShaderReflection reflection;
reflection.Initialize(shaderBlob);  // param type is ID3DBlob*


// print it
reflection.PrintCBuffersInfo();

For const buffer declared like this:

struct Material
{
float4  Ambient;
float4  Specular;
float3  Reflect;
};


cbuffer testCBuffer
{
float4     ambient;
float      intensity;
float      intensity2;
float4     color;
matrix     view;
float2     sth;
matrix     world;
float3     eyePos;
float4     something;
float      somethinggg;
Material   material;
float3     something2;
};

It will print something like this:

cbuffers count: 1

cbuffer name: testCBuffer
size: 304
vars count: 12
            name  size  offset  wasted space     type name   members  elements columns    rows
         ambient    16       0             0        float4         0         0       4       1
       intensity     4      16             0         float         0         0       1       1
      intensity2     4      20             8         float         0         0       1       1
           color    16      32             0        float4         0         0       4       1
            view    64      48             0      float4x4         0         0       4       4
             sth     8     112             8        float2         0         0       2       1
           world    64     128             0      float4x4         0         0       4       4
          eyePos    12     192             4        float3         0         0       3       1
       something    16     208             0        float4         0         0       4       1
     somethinggg     4     224            12         float         0         0       1       1
        material    44     240             4      Material         3         0      11       1
      something2    12     288             4        float3         0         0       3       1

‘wasted space’ is number of bytes that are not used due to padding.

Next, for corresponding c++ struct declared like this:

struct Material
{
XMFLOAT4    Ambient;
XMFLOAT4    Specular;
XMFLOAT3    Reflect;
};


struct testCBuffer
{
XMFLOAT4   ambient;
float      intensity;
float      intensity2;
XMFLOAT2   padding;
XMFLOAT4   color;
XMMATRIX   view;
XMFLOAT2   sth;
XMMATRIX   world;
XMFLOAT3   eyePos;
XMFLOAT4   something;
float      somethinggg;
Material   material;
XMFLOAT3   something2;


RTTI(testCBuffer, MEMBER(ambient) MEMBER(intensity) MEMBER(intensity2) MEMBER(padding) MEMBER(color) MEMBER(view)
MEMBER(sth) MEMBER(world) MEMBER(eyePos) MEMBER(something)
MEMBER(somethinggg) MEMBER(material) MEMBER(something2) )
};

it will print something like this:

size: 288
ars count: 13
           name  size     offset     missing padding                           type name
        ambient    16           0            0            struct DirectX::XMFLOAT4
      intensity     4          16            0                               float
     intensity2     4          20            0                               float
        padding     8          24            0            struct DirectX::XMFLOAT2
          color    16          32            0            struct DirectX::XMFLOAT4
           view    64          48            0            struct DirectX::XMMATRIX
            sth     8         112            8            struct DirectX::XMFLOAT2
          world    64         128            0            struct DirectX::XMMATRIX
         eyePos    12         192            4            struct DirectX::XMFLOAT3
      something    16         204            0            struct DirectX::XMFLOAT4
    somethinggg     4         220           12                               float
       material    44         224            4                     struct Material
     something2    12         268            4            struct DirectX::XMFLOAT3

And finally the sample will print this:

hlsl cbuffer and c++ struct have different members count
hlsl cbuffer and c++ struct have different sizes

member:    sth        should be padded with 8 bytes
member:    eyePos        should be padded with 4 bytes
member:    somethinggg        should be padded with 12 bytes
member:    material        should be padded with 4 bytes
member:    something2        should be padded with 4 bytes

Note that if you use #pragma pack(*) the “missing padding” column can be invalid.
I’ve included sample loop that shows how to iterate through struct and const buffer members and compare them. You can use the code however you like. I hope it will be useful for someone.

The sample is compiled using visual studio 2012. It uses Windows SDK and a little c++ 11.The reflection code is written by John Watte (http://www.enchantedage.com/cpp-reflection).

If anyone is interested these are slides from the talk I gave at polish conference for game developers called Game Day (http://www.gameday.com.pl) in June 2012. It’s about deferred rendering variations:

  1. Forward shading
  2. Deferred shading
  3. Deferred lightning / light pre-pass
  4. Inferred lightning
  5. Light-indexed deferred shading
  6. Decoupled deferred shading
  7. Prelighning
  8. Afterlights
  9. Tile based deferred shading
  10. Tile based forward shading
  11. Forward+
It was my first conference presentation and I consider it as a big fail (mainly because of too much details and lack of pictures/graphs) but a valuable experience. Anyway you can download it here: deferred_presentation_V_2012

Welcome on my blog!

Hi,
I will post here information about progress of my master thesis application as well as my other projects. Also, here, i will put my general thoughts and reflections about games and game development from a developer and gamer perspective. I hope you’ll enjoy them. You can find more information about me in “About” tab. You can also look at “Projects” tab to see my current and old projects.

Thanks for visiting. Bye