3

I have a compute shader:

#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_gpu_shader_int64 : enable

layout(local_size_x_id = 0) in;

layout(set = 0, binding = 0) buffer Foo {
    u64vec2[256] scratchpad;
} foo;

layout(set = 0, binding = 1) uniform Bar {
    u64vec2 a;
    u64vec2 b;
} bar;

void main() {
    int foobar = 0;
    int baz = 0;
}

I compiled this with glslangValidator from LunarG SDK 1.0.65.0 and checked it using spirv-val, which returned nothing. I enabled shaderInt64when creating the VkDevice. When loading this shader using vkCreateShaderModule I get this validation error:

SPIR-V module not valid: Invalid instruction word count: 0

The validation error goes away when I do any of the following:

  • Remove the 64-bit extension and change all types to int
  • Remove either Foo or Bar buffers
  • Remove either variables in main
  • Remove layout(local_size_x_id = 0) in

My question is, is this a bug in the compiler or validation layers, or am I using one of these features incorrectly?

vazgriz
  • 33
  • 6
  • Yes. With `layout`, specialization constants are included (`OpSpecConstant`). Otherwise they are the same – vazgriz Nov 18 '17 at 01:57
  • glslangValidator -V myshader.comp -o myshader.comp.spv – vazgriz Nov 18 '17 at 03:04
  • Also, I'm disassembling them with `spirv-dis`. With the `layout(local_size_x_id = 0) in;`, the binary contains, `OpSpecConstant`, and `OpSpecConstantComposite` instructions, which are not present when the `layout` is removed. – vazgriz Nov 18 '17 at 03:15
  • That error msg is tied to a [Op being malformed](https://github.com/KhronosGroup/SPIRV-Tools/blob/d2938e48427cb6e8d5996712c23496d62e3c08d1/source/binary.cpp#L291). Should be the same codebase as `spirv-val` though... – krOoze Nov 18 '17 at 03:30
  • I still don't get validation error though. Maybe it is your file loader? Do you open the file in binary mode? – krOoze Nov 18 '17 at 03:37
  • 1
    It was the loader. Changing it to binary mode fixed it. I guess the opcodes tripped a difference in how files are read in binary mode vs text mode. – vazgriz Nov 18 '17 at 03:54
  • Great! let me do a formal Answer... – krOoze Nov 18 '17 at 11:23

2 Answers2

1

If you are loading SPIR-V at runtime from file, you have to open the file in a binary mode (e.g. std::ifstream::binary in C++). Otherwise your binary may get changed when loading (i.e. usually the runtime tries to switch newline character(s) based on the platform it runs on).

Alternativelly you can load shaders statically (via #include) as a C++ inline file. You can create such file by glslc -mfmt=c or glslangValidator -V -x --vn variable_name.

krOoze
  • 12,301
  • 1
  • 20
  • 34
0

Assuming your GLSL->Spir-V compiler threw no errors, make sure this checklist is met:

  1. You are opening your file in binary mode
  2. You are reading the correct number of bytes from the file

SPIR-V is an intermediate language, and incorrect instruction count may be getting thrown because the validation layer is expecting a number of assembly-like instructions specified by the SPIR-V spec (which you have not fully loaded from the file).

Aaron Hull
  • 422
  • 4
  • 16