]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/spirv.cpp
Use forward references for entry point interfaces in SPIR-V
[libs/gl.git] / source / glsl / spirv.cpp
index b2eac3f0fe1925b11cc586e3e3485d19735ca388..404ffaf3735fe3f575ea62e8c93037095f78a781 100644 (file)
@@ -587,7 +587,9 @@ void SpirVGenerator::visit(VariableReference &var)
        if(composite_access)
        {
                r_expression_result_id = 0;
-               if(!assignment_source_id)
+               if(assignment_source_id)
+                       variable_load_ids.erase(var.declaration);
+               else
                {
                        auto i = variable_load_ids.find(var.declaration);
                        if(i!=variable_load_ids.end())
@@ -1441,7 +1443,7 @@ void SpirVGenerator::visit_builtin_texture(FunctionCall &call, const vector<Id>
 
 void SpirVGenerator::visit_builtin_texture_fetch(FunctionCall &call, const vector<Id> &argument_ids)
 {
-       const ImageTypeDeclaration &image = dynamic_cast<const ImageTypeDeclaration &>(*call.arguments[0]->type);
+       ImageTypeDeclaration &image = dynamic_cast<ImageTypeDeclaration &>(*call.arguments[0]->type);
 
        Opcode opcode;
        if(call.name=="texelFetch")
@@ -1457,9 +1459,18 @@ void SpirVGenerator::visit_builtin_texture_fetch(FunctionCall &call, const vecto
        if(argument_ids.size()!=2U+need_sample+need_lod)
                throw internal_error("invalid texture fetch call");
 
+       Id image_id;
+       if(image.sampled)
+       {
+               Id image_type_id = get_item(image_type_ids, get_id(image));
+               image_id = write_expression(OP_IMAGE, image_type_id, argument_ids[0]);
+       }
+       else
+               image_id = argument_ids[0];
+
        r_expression_result_id = begin_expression(opcode, get_id(*call.type), 2+(need_lod|need_sample)+need_lod+need_sample);
-       for(unsigned i=0; i<2; ++i)
-               writer.write(argument_ids[i]);
+       writer.write(image_id);
+       writer.write(argument_ids[1]);
        if(need_lod || need_sample)
        {
                writer.write(need_lod*0x02 | need_sample*0x40);
@@ -1594,6 +1605,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image)
                return;
 
        Id type_id = allocate_id(image, 0);
+       SpirVFormat format = get_format(image.format);
 
        Id image_id = (image.sampled ? next_id++ : type_id);
        writer.begin_op(content.globals, OP_TYPE_IMAGE, 9);
@@ -1604,7 +1616,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image)
        writer.write(image.array);
        writer.write(image.multisample);
        writer.write(image.sampled ? 1 : 2);
-       writer.write(get_format(image.format));
+       writer.write(format);
        writer.end_op(OP_TYPE_IMAGE);
 
        if(image.sampled)
@@ -1621,6 +1633,9 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image)
 
        if(image.multisample && !image.sampled)
                use_capability(CAP_STORAGE_IMAGE_MULTISAMPLE);
+
+       if(format>=FORMAT_RG32F && format<=FORMAT_R8_SNORM)
+               use_capability(CAP_STORAGE_IMAGE_EXTENDED_FORMATS);
 }
 
 void SpirVGenerator::visit(StructDeclaration &strct)
@@ -1817,7 +1832,7 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id)
        for(Node *n: dependencies)
                if(const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(n))
                        if(!var->interface.empty())
-                               writer.write(get_id(*n));
+                               writer.write(allocate_forward_id(*n));
 
        writer.end_op(OP_ENTRY_POINT);