GithubHelp home page GithubHelp logo

Comments (8)

chaoticbob avatar chaoticbob commented on July 17, 2024 2

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.

chaoticbob avatar chaoticbob commented on July 17, 2024 2

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.

darksylinc avatar darksylinc commented on July 17, 2024 1

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.

noggs avatar noggs commented on July 17, 2024

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.

bernief1 avatar bernief1 commented on July 17, 2024

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.

cbuffer_struct_issue.zip

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.

chaoticbob avatar chaoticbob commented on July 17, 2024

Thanks for the issue. Sorry for the delay. Will investigate.

from spirv-reflect.

darksylinc avatar darksylinc commented on July 17, 2024

I'm looking into this bug because I managed to get a very interesting repro:

  1. MSVC 2019 x64 and Android trigger the bug.
  2. 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.

lyuma avatar lyuma commented on July 17, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.