KhronosGroup / glslang

Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
Other
2.98k stars 822 forks source link

Modifying compute buffer memory causes "unknown glslang binary operation" #1464

Open 0xen opened 6 years ago

0xen commented 6 years ago

I have created a simple GLSL shader to be compiled with glslang, but I get the message "Missing functionality: unknown glslang binary operation" from the logger. Are buffers not implemented?

GLSL Code

#version 450

#extension GL_ARB_separate_shader_objects : enable

layout(binding = 0) buffer Buffer1 {
    float[] fpn;
};

void main() {
    uint GIX = gl_GlobalInvocationID.x;
    fpn[GIX] *= 4.0f;
}
johnkslang commented 6 years ago

It compiles clean for me, as a compute shader, using glslang both as a validator and for generating SPIR-V.

How are you executing it? What version are you using (-v)?

johnkslang commented 6 years ago

BTW, buffers are fully implemented, and I don't see an immediate problem.

0xen commented 6 years ago

I am note using the glslangValidator, I'm aware that works. The issue I am having is when implementing glslang into my project and compiling it in there. I'm not sure if I have missed a important step when building it but I will attach the function I have created. ` if (!m_glslangInitialized) { glslang::InitializeProcess(); m_glslangInitialized = true; } std::ifstream file(path);

if (!file.is_open())
{
    throw std::runtime_error("failed to open shader file");
}

std::string glsl((std::istreambuf_iterator<char>(file)),
    std::istreambuf_iterator<char>());

const char* InputCString = glsl.c_str();

glslang::TShader Shader(stage);

Shader.setStrings(&InputCString, 1);

int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
int VulkanClientVersion = 100;
unsigned int TargetVersion = 0x00010000;

Shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
Shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
Shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);

TBuiltInResource Resources;
Resources = glslang::DefaultTBuiltInResource;
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);

const int DefaultVersion = 450;

DirStackFileIncluder Includer;

std::string Path = getFilePath(path);
Includer.pushExternalLocalDirectory(Path);

std::string PreprocessedGLSL;

if (!Shader.preprocess(&Resources, DefaultVersion, ENoProfile, false, false, messages, &PreprocessedGLSL, Includer))
{
    throw std::runtime_error("GLSL Preprocessing Failed");
}

const char* PreprocessedCStr = PreprocessedGLSL.c_str();
Shader.setStrings(&PreprocessedCStr, 1);

if (!Shader.parse(&Resources, 100, false, messages))
{
    throw std::runtime_error("GLSL Parsing Failed");
}

glslang::TProgram Program;
Program.addShader(&Shader);

if (!Program.link(messages))
{
    throw std::runtime_error("GLSL Linking Failed");
}
if (!Program.mapIO())
{
    throw std::runtime_error("GLSL Linking Failed");
}

// Temp storage of SpireV after conversion 
std::vector<unsigned int> SpirV_temp;
spv::SpvBuildLogger logger;
glslang::SpvOptions spvOptions;
glslang::GlslangToSpv(*Program.getIntermediate(stage), SpirV_temp, &logger, &spvOptions);

`

johnkslang commented 6 years ago

I don't know root cause yet, but I don't think you want to

typedef enum {
    EShTargetVulkan_1_0 = (1 << 22),
    EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),
    EShTargetOpenGL_450 = 450,
} EShTargetClientVersion;