X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=61e5937856b30d7abc38afc2d5143b03e1ca4b1e;hb=c585c065b7831eb6ae05e48edc36953d2534db2b;hp=e1ba981b552f1b63de515334bdd516ed0846159f;hpb=6ef956d2f41512081e6c19d41a1230e177547dde;p=libs%2Fgl.git diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index e1ba981b..61e59378 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -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 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,13 +1296,15 @@ 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"); ImageTypeDeclaration &image_arg0 = dynamic_cast(*call.arguments[0]->type); Id image_id; - if(image_arg0.sampled) + if(image_arg0.sampled && opcode!=OP_IMAGE_QUERY_LOD) { Id image_type_id = get_item(image_type_ids, get_id(image_arg0)); image_id = write_expression(OP_IMAGE, image_type_id, argument_ids[0]); @@ -1364,15 +1371,25 @@ void SpirVGenerator::visit_builtin_texture(FunctionCall &call, const vector void SpirVGenerator::visit_builtin_texel_fetch(FunctionCall &call, const vector &argument_ids) { - if(argument_ids.size()!=3) - throw internal_error("invalid texelFetch call"); + const ImageTypeDeclaration &image = dynamic_cast(*call.arguments[0]->type); + + Opcode opcode = OP_IMAGE_FETCH; + + bool need_sample = image.multisample; + bool need_lod = !need_sample; - r_expression_result_id = begin_expression(OP_IMAGE_FETCH, get_id(*call.type), 4); + if(argument_ids.size()!=2U+need_sample+need_lod) + throw internal_error("invalid texture fetch call"); + + 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(2); // Lod - writer.write(argument_ids.back()); - end_expression(OP_IMAGE_FETCH); + if(need_lod || need_sample) + { + writer.write(need_lod*0x02 | need_sample*0x40); + writer.write(argument_ids.back()); + } + end_expression(opcode); } void SpirVGenerator::visit_builtin_interpolate(FunctionCall &call, const vector &argument_ids) @@ -1488,7 +1505,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); @@ -1701,7 +1718,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) {