]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/spirv.cpp
Add multisampled texture types to the shader compiler
[libs/gl.git] / source / glsl / spirv.cpp
index 1f7d6a1b722c98289446f95a40aacd0c8101a09b..61e2d594e6c641105379dfd6c671a82b1991f5fa 100644 (file)
@@ -111,6 +111,7 @@ const SpirVGenerator::BuiltinFunctionInfo SpirVGenerator::builtin_functions[] =
        { "textureSize", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
        { "textureQueryLod", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
        { "textureQueryLevels", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
+       { "textureSamples", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query },
        { "texture", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture },
        { "textureLod", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture },
        { "texelFetch", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texel_fetch },
@@ -1021,18 +1022,22 @@ void SpirVGenerator::visit(TernaryExpression &ternary)
        writer.write_op(content.function_body, OP_SELECTION_MERGE, merge_block_id, 0);  // Selection control (none)
        writer.write_op(content.function_body, OP_BRANCH_CONDITIONAL, condition_id, true_label_id, false_label_id);
 
+       std::map<const VariableDeclaration *, Id> saved_load_ids = variable_load_ids;
+
        writer.write_op_label(true_label_id);
        ternary.true_expr->visit(*this);
        Id true_result_id = r_expression_result_id;
        true_label_id = writer.get_current_block();
        writer.write_op(content.function_body, OP_BRANCH, merge_block_id);
 
+       swap(saved_load_ids, variable_load_ids);
        writer.write_op_label(false_label_id);
        ternary.false_expr->visit(*this);
        Id false_result_id = r_expression_result_id;
        false_label_id = writer.get_current_block();
 
        writer.write_op_label(merge_block_id);
+       prune_loads(true_label_id);
        r_expression_result_id = begin_expression(OP_PHI, get_id(*ternary.type), 4);
        writer.write(true_result_id);
        writer.write(true_label_id);
@@ -1291,6 +1296,8 @@ void SpirVGenerator::visit_builtin_texture_query(FunctionCall &call, const vecto
                opcode = OP_IMAGE_QUERY_LOD;
        else if(call.name=="textureQueryLevels")
                opcode = OP_IMAGE_QUERY_LEVELS;
+       else if(call.name=="textureSamples")
+               opcode = OP_IMAGE_QUERY_SAMPLES;
        else
                throw internal_error("invalid texture query call");
 
@@ -1367,10 +1374,12 @@ void SpirVGenerator::visit_builtin_texel_fetch(FunctionCall &call, const vector<
        if(argument_ids.size()!=3)
                throw internal_error("invalid texelFetch call");
 
+       const ImageTypeDeclaration &image = dynamic_cast<const ImageTypeDeclaration &>(*call.arguments[0]->type);
+
        r_expression_result_id = begin_expression(OP_IMAGE_FETCH, get_id(*call.type), 4);
        for(unsigned i=0; i<2; ++i)
                writer.write(argument_ids[i]);
-       writer.write(2);  // Lod
+       writer.write(image.multisample ? 0x40 : 0x02);  // Sample or Lod
        writer.write(argument_ids.back());
        end_expression(OP_IMAGE_FETCH);
 }
@@ -1488,7 +1497,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image)
        writer.write(image.dimensions-1);
        writer.write(image.shadow);
        writer.write(image.array);
-       writer.write(false);  // Multisample
+       writer.write(image.multisample);
        writer.write(image.sampled ? 1 : 2);
        writer.write(0);  // Format (unknown)
        writer.end_op(OP_TYPE_IMAGE);
@@ -1512,7 +1521,7 @@ void SpirVGenerator::visit(StructDeclaration &strct)
                return;
 
        Id type_id = allocate_id(strct, 0);
-       writer.write_op_name(type_id, strct.name);
+       writer.write_op_name(type_id, (strct.block_name.empty() ? strct.name : strct.block_name));
 
        if(!strct.block_name.empty())
                writer.write_op_decorate(type_id, DECO_BLOCK);
@@ -1670,7 +1679,8 @@ void SpirVGenerator::visit(VariableDeclaration &var)
                }
        }
 
-       writer.write_op_name(var_id, var.name);
+       if(var.name.find(' ')==string::npos)
+               writer.write_op_name(var_id, var.name);
 }
 
 void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id)
@@ -1700,7 +1710,10 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id)
                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, origin);
        }
        else if(stage->type==Stage::GEOMETRY)
+       {
                use_capability(CAP_GEOMETRY);
+               writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_INVOCATIONS, 1);
+       }
 
        for(const InterfaceLayout *i: interface_layouts)
        {
@@ -1776,6 +1789,7 @@ void SpirVGenerator::visit(FunctionDeclaration &func)
        {
                Id param_id = allocate_id(*func.parameters[i], param_type_ids[i]);
                writer.write_op(content.functions, OP_FUNCTION_PARAMETER, param_type_ids[i], param_id);
+               writer.write_op_name(param_id, func.parameters[i]->name);
                // TODO This is probably incorrect if the parameter is assigned to.
                variable_load_ids[func.parameters[i].get()] = param_id;
        }