Comments (9)
It appears to be a data stride / layout issue. I recommend double check the address computation in the generated glsl code and look for how strides are calculated. I suspect something like indexAddress
is having a 16 bytes stride instead of 12, or somewhere inside Vertex
we are following a different layout than what the data is assumed.
from slang.
In this particular case, it is worth checking the stride for InstanceInfo
and Material
.
Make sure instInfo.materialID
is at least correct.
from slang.
I'm using emit-spirv-directly
, do you suggest using `SpirV-cross' to generate the GLSL code? In case the stride is different, isn't there a flag in SpirV to do things the same way as GLSL?
Tomorrow I will check if instInfo.materialID
contains the right values.
from slang.
Yes, the easiest way is to use spirv-cross to generate glsl and examine the pointer offset.
from slang.
I tested spriv-cross on the output, but it generated an error.
SPIRV-Cross threw an exception: VariablePointers capability is not supported in GLSL.
I decided to use -target glsl
and not using -emit-spirv-directly
. This is generating the same visual error, but I could extract the GLSL code for it.
Here is the GLSL layouts from the Slang output
layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer BufferPointer_Material_0_3
{ _735 _data; };
layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer BufferPointer_InstanceInfo_0_4
{ layout(row_major) _753 _data; };
layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer BufferPointer_PrimMeshInfoSlang_0_8
{ _771 _data; };
layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer BufferPointer_Vertex_0_5
{ _779 _data; };
layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer BufferPointer_S6_7
{ uvec3 _data; };
and some structs
layout(buffer_reference, std430) buffer _779
{
vec3 position_1;
vec3 normal_0;
vec2 t_0;
};
layout(buffer_reference, std430) buffer _735
{
vec3 albedo_0;
float roughness_0;
float metallic_0;
};
In the original GLSL code, no buffer_reference_align
were defined, so I compiled the GLSL shader to SpirV and spriv-cross back to see how it looks.
Here are the layouts from the working GLSL
layout(buffer_reference, buffer_reference_align = 16, scalar) readonly buffer Vertices
{
_807 v[];
};
layout(buffer_reference, buffer_reference_align = 4, scalar) readonly buffer Indices
{
uvec3 i[];
};
layout(buffer_reference, scalar) buffer _807
{
vec3 position;
vec3 normal;
vec2 t;
};
layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PrimMeshInfos
{
_1025 i[];
};
layout(buffer_reference, std430) buffer _1025
{
uint64_t vertexAddress;
uint64_t indexAddress;
};
layout(buffer_reference, buffer_reference_align = 4, scalar) readonly buffer Materials
{
_1129 m[];
};
layout(buffer_reference, buffer_reference_align = 4, scalar) readonly buffer InstanceInfos
{
_1177 i[];
};
layout(buffer_reference, std430) buffer _1177
{
mat4 transform;
int materialID;
};
layout(buffer_reference, std430) buffer _1129
{
vec3 albedo;
float roughness;
float metallic;
};
I can see two things
- buffer_reference_align = 4 : sometimes it is 4 instead of 16
- scalar : uses
scalar
instead ofstd430
, but the-force-glsl-scalar-layout
was set when compiling
But the biggest difference is how the data get retrieve
This is the GLSL (spirv-cross from original GLSL)
Vertices vertices = Vertices(pinfo.vertexAddress);
Indices indices = Indices(pinfo.indexAddress);
vec3 barycentrics = vec3((1.0 - barycentricCoords.x) - barycentricCoords.y, barycentricCoords.x, barycentricCoords.y);
uvec3 triangleIndex = indices.i[primitiveID];
_807 _851;
_851.position = vertices.v[triangleIndex.x].position;
_851.normal = vertices.v[triangleIndex.x].normal;
_851.t = vertices.v[triangleIndex.x].t;
_807 v0 = _851;
_807 _858;
_858.position = vertices.v[triangleIndex.y].position;
_858.normal = vertices.v[triangleIndex.y].normal;
_858.t = vertices.v[triangleIndex.y].t;
_807 v1 = _858;
_807 _865;
_865.position = vertices.v[triangleIndex.z].position;
_865.normal = vertices.v[triangleIndex.z].normal;
_865.t = vertices.v[triangleIndex.z].t;
_807 v2 = _865;
vec3 pos0 = v0.position;
vec3 pos1 = v1.position;
vec3 pos2 = v2.position;
And this is how Slang does it. Note the arithmetic instead of data access.
float _S9 = barycentricCoords_0.x;
float _S10 = barycentricCoords_0.y;
float _S11 = (1.0 - _S9) - _S10;
uint64_t _S12 = uint64_t(sceneDesc_0._data[0].primInfoAddress_0);
BufferPointer_PrimMeshInfoSlang_0_8 _S13 = BufferPointer_PrimMeshInfoSlang_0_8(_S12 + uint64_t(int64_t(16 * meshID_0)));
_771 _848;
_848.vertexAddress_0._data.position_1 = _S13._data.vertexAddress_0._data.position_1;
_848.vertexAddress_0._data.normal_0 = _S13._data.vertexAddress_0._data.normal_0;
_848.vertexAddress_0._data.t_0 = _S13._data.vertexAddress_0._data.t_0;
_848.indexAddress_0._data = _S13._data.indexAddress_0._data;
_771 _S14 = _848;
uint64_t _S15 = uint64_t(_S14.indexAddress_0);
BufferPointer_S6_7 _S16 = BufferPointer_S6_7(_S15 + uint64_t(int64_t(12 * primitiveID_0)));
uvec3 _S17 = _S16._data;
int _S18 = int(_S17.x);
uint64_t _S19 = uint64_t(_S14.vertexAddress_0);
BufferPointer_Vertex_0_5 _S20 = BufferPointer_Vertex_0_5(_S19 + uint64_t(int64_t(32 * _S18)));
_779 _923;
_923.position_1 = _S20._data.position_1;
_923.normal_0 = _S20._data.normal_0;
_923.t_0 = _S20._data.t_0;
_779 _S21 = _923;
int _S22 = int(_S17.y);
uint64_t _S23 = uint64_t(_S14.vertexAddress_0);
BufferPointer_Vertex_0_5 _S24 = BufferPointer_Vertex_0_5(_S23 + uint64_t(int64_t(32 * _S22)));
_779 _958;
_958.position_1 = _S24._data.position_1;
_958.normal_0 = _S24._data.normal_0;
_958.t_0 = _S24._data.t_0;
_779 _S25 = _958;
int _S26 = int(_S17.z);
uint64_t _S27 = uint64_t(_S14.vertexAddress_0);
BufferPointer_Vertex_0_5 _S28 = BufferPointer_Vertex_0_5(_S27 + uint64_t(int64_t(32 * _S26)));
_779 _993;
_993.position_1 = _S28._data.position_1;
_993.normal_0 = _S28._data.normal_0;
_993.t_0 = _S28._data.t_0;
_779 _S29 = _993;
vec3 pos0_0 = _S21.position_1;
vec3 pos1_0 = _S25.position_1;
vec3 pos2_0 = _S29.position_1;
It is unclear whether the scalar
would solve the issue, as there is a disagreement between stride and alignment. While modifying all structs to be aligned to 16 is possible, it is not always feasible or recommended due to padding constraints. For instance, the indices are packed as uvec3
, and changing this would require modifying the data access method.
from slang.
Alignments can be explicitly specified in ConstBufferPointer type as ConstBufferPointer<T, alignment>
.
Perhaps try explicitly specify the alignments to 4 in the shader code?
from slang.
I tried, by doing the following
ConstBufferPointer<Material, 4> materialAddress;
But I can see two layouts spitting out for the material, one with an alignment of 4 and one with 16
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer BufferPointer_Material_0_3
{
Material_0 _data;
};
layout(buffer_reference, std430, buffer_reference_align = 16) readonly buffer BufferPointer_Material_0_9
{
Material_0 _data;
};
and unfortunately, it is using the wrong one
BufferPointer_Material_0_9 _S66 = (BufferPointer_Material_0_9((_S65 + uint64_t(20 * _S60.materialID_0))));
from slang.
I am adding true/complete pointer support to SPIRV, and will take care of this issue along the way.
from slang.
General pointer type (T*) is now supported.
Currently this is only support on the direct-to-spirv backend. GLSL backend to come.
from slang.
Related Issues (20)
- Capabilities System: Inclusive join logic bug
- Trailing OpTypeRuntimeArray in Uniform Struct
- Add compile flag to allow for relaxed enum rules HOT 2
- GLSLForceScalarLayout doesn't seem to work as CompileOptionEntry HOT 4
- Metal: support for structures in compute kernel arguments HOT 2
- Reinvestigate support for OpDebugTypePointer
- "DerivativeGroupLinear" not working when compiled with glslang HOT 1
- Preprocessor macro for targets HOT 9
- error 49999: unknown system-value semantic 'SV_InsideTessFactor' HOT 5
- Running examples like "triangle" fails to find corresponding "shader.slang" HOT 3
- SPIR-V Validation error - Fragment stage integer Input decorated Flat multiple times HOT 1
- [SPIRV] Resulting matrix vector product code looks unoptimized HOT 2
- Vertex entrypoints missing from capability system? HOT 3
- `GetAttributeAtVertex` is not correctly implemented for SPIRV. HOT 1
- Add compile flag to allow register() for Vulkan HOT 2
- slang-test failures with the latest Vulkan SDK 1.3.283.0
- Sanity check for compiling multiple shaders in a single file to SPIR-V library with Slang API HOT 1
- Disable all failing metal tests and enable full testing on CI.
- Passthrough linking of shader-modules with embedded DXIL
- Implement `InputPatch` and `OutputPatch` for spirv.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from slang.