Comments (8)
Thank you everyone for the information on this issue. I dug into this issue and found that the failed parse in all cases has to do with the handling of the OpAccessChain
indices. In @bernief1's example it seems like shader compilers can "shortcut" the type hierarchy. And from @lyuma's example a similar thing happens for arrays. I have a fix that stops the crash in both cases but incorrectly marks the USED state of the variable in arrays. I'm working on a more generic fix to address this. The OpAccessChain
behavior in these cases are new to me and it wasn't obvious from my previous reading of the spec.
from spirv-reflect.
The crash should be fixed by 64b0cc2. There may be some edge cases of GLSL structs that aren't covered.
Please reopen if you encounter any crashes or unexpected SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE.
from spirv-reflect.
It's getting more clear: ParseDescriptorBlockVariableUsage keeps looping:
while ((p_type->op == SpvOpTypeArray) && (index_index < p_access_chain->index_count)) {
{
p_type = ...; //p_type->op == SpvOpTypeArray may become false now
...
index_index += 1;
}
The loop may result with index_index = p_access_chain->index_count; but later on ParseDescriptorBlockVariableUsage is called; producing the out of bounds read.
Update: The divergence between OSes was indeed caused by the out of bounds read.
So far all I can see is that originally proposed solution works. But I don't know how proper it is
from spirv-reflect.
In case anyone comes to this, I have not been able to figure it out but looking through the SPIRV disasm I noticed there is an OpAccessChain with no Indexes specified. Maybe this is a codegen issue?
Anyway, if anyone needs a dirty hack to get past this, where it goes wrong in ParseDescriptorBlockVariableUsage, you can seemingly early out of parsing the struct with no ill effects.
if (index_index >= p_access_chain->index_count) return SPV_REFLECT_RESULT_SUCCESS;
from spirv-reflect.
I'm also running into this issue, using HLSL. It seems that if a struct inside a cbuffer is passed to a function, then spirv_reflect fails. However if a local copy of the struct is used instead, then it works. The distinction is rather subtle as well - the local copy of the struct must be copied member-by-member from the cbuffer struct, not all at once.
I have a simple repro case here. You'll need dxc.exe and dxcompiler.dll in the same directory (I got mine from https://ci.appveyor.com/project/antiagainst/directxshadercompiler/branch/master/artifacts). If you drag shader.hlsl onto shader.bat, it will generate six versions of the .spv file. The first three fail spirv_reflect, and the last 3 don't.
struct MyStruct
{
float4 v;
};
cbuffer cb_foo
{
MyStruct foo;
};
cbuffer cb_foo_v
{
float4 foo_v;
};
float GetX(MyStruct s)
{
return s.v.x;
}
float GetXFromV(float4 v)
{
return v.x;
}
float4 Main0() : SV_TARGET0 { return GetX(foo); } // <-- this crashes spirv_reflect
float4 Main1() : SV_TARGET0 { MyStruct foo2 = foo; return GetX(foo2); } // <-- this crashes spirv_reflect
float4 Main2() : SV_TARGET0 { MyStruct foo2; foo2 = foo; return GetX(foo2); } // <-- this crashes spirv_reflect
float4 Main3() : SV_TARGET0 { MyStruct foo2; foo2.v = foo.v; return GetX(foo2); } // <-- this does NOT crash
float4 Main4() : SV_TARGET0 { return GetXFromV(foo.v); } // <-- this does NOT crash
float4 Main5() : SV_TARGET0 { return GetXFromV(foo_v); } // <-- this does NOT crash
from spirv-reflect.
Thanks for the issue. Sorry for the delay. Will investigate.
from spirv-reflect.
I'm looking into this bug because I managed to get a very interesting repro:
- MSVC 2019 x64 and Android trigger the bug.
- GCC x64 on Linux works fine
I'm still researching, but so far I found that at the same location:
uint32_t index = p_access_chain->indexes[index_index];
Windows: index is 4261281277
Linux: index is 0,
In both:
index_index = 2
p_access_chain->index_count = 2
Thus p_access_chain->indexes[2] is an out of bounds read.
Another odd thing:
p_parser->access_chain_count
Windows is 186
Linux is 176
My bad they're equal.
I'll report more when I get more info
from spirv-reflect.
Ran into the same problem when I declared a local variable which referenced a struct member of a uniform buffer (Godot engine master branch):
layout(set = 0, binding = 7, std140) uniform DirectionalLights {
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
directional_lights;
...
vec4 get_light_color(uint index) {
DirectionalLightData dld = directional_lights.data[index];
return dld.color;
}
I may have also hit this when returning a struct from a function, such as DirectionalLightData get_light(uint idx) { return ......; }
but it might be conflated with the above issue.
from spirv-reflect.
Related Issues (20)
- Compiler warning for missing field initializers HOT 3
- Update the README.md file for extra dependency HOT 1
- Add runtime array info to SpvReflectBindingArrayTraits HOT 1
- Vertex Input structs don't have formats in members HOT 1
- No Vertex Input Location for structs HOT 1
- Getting error 20 code (SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE) when trying to use functions from extension GL_ARB_fragment_shader_interlock HOT 5
- Remove support for bazel builds HOT 2
- Decide how to handle array interfaces
- Handle buffer reference with arrays to themselves HOT 4
- Empty push constant block name after 56d6806 HOT 2
- resource type for COMBINED_IMAGE_SAMPLER HOT 3
- Geometry Array-of-BuiltIns doesn't label builtin correctly
- Reflecting capabilities used by a shader more finely HOT 8
- Add SECURITY.md HOT 1
- Null pointer dereference HOT 2
- Handle OpCopy* instructions
- Structure layout reuse does not enumerate structure member count HOT 2
- buffer_reference through push constant causing Assert/crash in spirv-reflect HOT 1
- Feature request: reflect referenced members of a ByteAddressBuffer HOT 8
- Reflect SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM when decoration_flag contains SPV_REFLECT_DECORATION_WEIGHT_TEXTURE HOT 4
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 spirv-reflect.