PDA

View Full Version : NV bug (tested on 314.14) using storage buffer objects..



oscarbg
03-11-2013, 12:58 AM
UPDATE:Sorry for poor code pasting I was testing correct code (with semicolons and defined g_mProjectionInv like mat4x4 so doesn't change any observation)
Hi I seem to have found a bug using storage buffer objects porting deferred+ code to GLSL
I tried to use a storage buffer instead of default uniform buffer to see only how affected perf.. so


#ifdef USE_SBO
layout(binding = 0) buffer cbPerObject
#else
uniform cbPerObject
#endif
{
mat4x4 g_mWorldViewProjection;
mat4x4 g_mWorldView;
mat4x4 g_mWorld;
float4 g_MaterialAmbientColorUp;
float4 g_MaterialAmbientColorDown;
};
has code like accessing



either using
g_mProjectionInv[2].w
or
g_mProjectionInv[2][3]


shader compiles (ie. generates NV assembly but fails with:


-- error message --
line 710, column 30: error: expected ';'
line 711, column 29: error: expected ';'
-- internal assembly text --
!!NVcp5.0

offending lines:
LDB.F32X4 R3.x, sbo_buf1[112].w;
LDB.F32X4 R2.x, sbo_buf1[96].w;

so seems doesn't like .w modifier and seems coming from access to matrices mat4x4

AHeumann
03-11-2013, 03:08 AM
According to the GLSL spec the only way to access members of a matrix is using array subscripting syntax:


5.6 Matrix Components

The components of a matrix can be accessed using array subscripting syntax. Applying a single subscript
to a matrix treats the matrix as an array of column vectors, and selects a single column, whose type is a
vector of the same size as the matrix. The leftmost column is column 0. A second subscript would then
operate on the column vector, as defined earlier for vectors. Hence, two subscripts select a column and
then a row.

mat4 m;
m[1] = vec4(2.0); // sets the second column to all 2.0
m[0][0] = 1.0; // sets the upper left element to 1.0
m[2][3] = 2.0; // sets the 4th element of the third column to 2.0

Behavior is undefined when accessing a component outside the bounds of a matrix with a non-constant
expression. It is an error to access a matrix with a constant expression that is outside the bounds of the
matrix.

It should not work when using a uniform buffer as well. It seems the NVIDIA compiler is taking another path there.

If you change
g_mProjectionInv[2].w to
g_mProjectionInv[2][3] it should work.

Alfonse Reinheart
03-11-2013, 03:19 AM
so seems doesn't like .w modifier and seems coming from access to matrices mat4x4

It's more likely that you didn't use semicolons. Especially considering that, well, there aren't any semicolons anywhere in the code you posted. You should add some and get back to us.



@AHeumann: That doesn't make sense. An array of column vectors would treat `arc[0]` as a vector. And it is legal to do `.w` on a vector. Therefore, if `arc` is an array of column vectors, `arc[0].w` should be legal GLSL code.

AHeumann
03-11-2013, 03:24 AM
You are right, I just read the sentence on array access and did not read the sentence on vector access.

Christoph Kubisch
03-11-2013, 04:10 AM
just quickly threw something together that compiles just fine. As the others mentioned the code you show wouldn't compile at all? g_mProjectionInv doesn't exist in the struct either?

oscarbg
03-11-2013, 06:21 AM
First sorry for poor posting I'm using semicolons of course but not posted here.. also I have another Storage buffer or uniform buffer and it contains g_mProjectionInv see here (I cleaned semicolons for not showing commented HSLS port:


#define matrix mat4x4
#ifdef USE_SBO
/*cbuffer*/layout(binding = 0) buffer cbPerFrame //: register( b1 )
#else
uniform cbPerFrame
#endif
{
matrix g_mProjection ;//: packoffset( c0 );
matrix g_mProjectionInv ;//: packoffset( c4 );
float3 g_vCameraPos ;//: packoffset( c8 );
float g_fAlphaTest ;//: packoffset( c8.w );
uint g_uNumLights ;//: packoffset( c9 );
uint g_uWindowWidth ;//: packoffset( c9.y );
uint g_uWindowHeight ;//: packoffset( c9.z );
uint g_uMaxNumLightsPerTile ;//: packoffset( c9.w );
};

anyway tested that offensive line is:


z = 1.f / (z*g_mProjectionInv[2].w + g_mProjectionInv[3].w);

changing to


z = 1.f / (z*g_mProjectionInv[2][3]+ g_mProjectionInv[3][3]);

doesn't fix nothing as still generates same nv assembly code with .w
as said using uniform objects fixes issue so it's a bug in NV compiler..
I can post full code if needed but issue is good isolated now..

oscarbg
03-12-2013, 03:23 AM
Ok I post a minimal repro case:


#version 430 core

#define TILE_RES 16

layout(binding = 0) buffer cbPerFrame
{
mat4x4 g_mProjectionInv;
};

layout(binding = 3, r32f) uniform imageBuffer g_PerTileLightIndexBufferOut;

layout (local_size_x = TILE_RES, local_size_y = TILE_RES) in;
void main( )
{
float z;
mat4x4 matr=g_mProjectionInv;
z=1.f / (z*matr[2][1] + matr[3][1]);
imageStore(g_PerTileLightIndexBufferOut,int(1),vec 4(z));
}


and compiler error:


Compute info
------------
0(16) : warning C7050: "z" might be used before being initialized
Internal error: assembly compile error for compute shader at offset 619:
-- error message --
line 19, column 29: error: expected ';'
line 20, column 29: error: expected ';'
-- internal assembly text --
!!NVcp5.0
OPTION NV_shader_storage_buffer;
OPTION NV_shader_atomic_float;
GROUP_SIZE 16 16;
# cgc version 3.1.0001, build date Feb 28 2013
# command line args:
#vendor NVIDIA Corporation
#version 3.1.0.1
#profile gp5cp
#program main
#semantic g_PerTileLightIndexBufferOut : IMAGE[3]
#semantic cbPerFrame : SBO_BUFFER[0]
#var int g_PerTileLightIndexBufferOut.__remap : : c[0] : -1 : 1
#var float4x4 g_mProjectionInv : SBO_BUFFER[0] : sbo_buffer[0][0], 4 : -1 : 1
PARAM c[1] = { program.local[0] };
STORAGE sbo_buf0[] = { program.storage[0] };
TEMP R0, R1;
IMAGE images[] = { image[0..7] };
LDB.F32X2 R1.x, sbo_buf0[48].y;
LDB.F32X2 R0.x, sbo_buf0[32].y;
MAD.F R0.x, R0.y, R0, R1;
RCP.F R0.x, R0.x;
MOV.S R0.y, c[0].x;
STOREIM.F images[R0.y], R0.x, {1, 0, 0, 0}, BUFFER;
MOV.F R1, R0;
MOV.U R0.x, R0;
END
# 8 instructions, 2 R-regs

Alfonse Reinheart
03-12-2013, 03:40 AM
Internal error: assembly compile error for compute shader at offset 619:

Generally speaking "internal error"s are bugs from within the compiler itself.

Christoph Kubisch
03-12-2013, 04:50 AM
compiles fine for me, looks like it has been fixed with newer drivers (though can't say exactly from which version on)

oscarbg
08-04-2013, 01:27 PM
compiles fine for me, looks like it has been fixed with newer drivers (though can't say exactly from which version on)
Seems bug is still present on OGL 4.4 beta drivers!

tonyo_au
08-04-2013, 07:14 PM
driver 326.41 beta gives me an error


Includes0(12) : error C3008: unknown layout specifier 'local_size_y'
0(12) : error C3008: unknown layout specifier 'local_size_x'


If I remove the layout line I get oscarbg's error

Piers Daniell
08-13-2013, 04:25 PM
Could you see if the bug is gone with the new OpenGL 4.4 beta 326.58 driver for Windows available here:
https://developer.nvidia.com/opengl-driver