X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=9cb1b7f2e112a8d8d06d85dc92ab3f1d8561dcd5;hb=2b1dc627491c987b0459226dcb8ac6aadd7ee4d3;hp=61e2d594e6c641105379dfd6c671a82b1991f5fa;hpb=215d5bed27ad3de92557ae1b631695a036d29741;p=libs%2Fgl.git diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 61e2d594..9cb1b7f2 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -114,7 +114,11 @@ const SpirVGenerator::BuiltinFunctionInfo SpirVGenerator::builtin_functions[] = { "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 }, + { "texelFetch", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture_fetch }, + { "imageSize", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query }, + { "imageSamples", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query }, + { "imageLoad", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture_fetch }, + { "imageStore", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture_store }, { "EmitVertex", "", "", OP_EMIT_VERTEX, { }, 0, 0 }, { "EndPrimitive", "", "", OP_END_PRIMITIVE, { }, 0, 0 }, { "dFdx", "f", "", OP_DP_DX, { 1 }, 0, 0 }, @@ -199,6 +203,50 @@ SpirVGenerator::BuiltinSemantic SpirVGenerator::get_builtin_semantic(const strin throw invalid_argument("SpirVGenerator::get_builtin_semantic"); } +SpirVFormat SpirVGenerator::get_format(const std::string &name) +{ + if(name.empty()) + return FORMAT_UNKNOWN; + else if(name=="rgba32f") + return FORMAT_RGBA32F; + else if(name=="rgba16f") + return FORMAT_RGBA16F; + else if(name=="r32f") + return FORMAT_R32F; + else if(name=="rgba8") + return FORMAT_RGBA8; + else if(name=="rgba8_snorm") + return FORMAT_RGBA8_SNORM; + else if(name=="rg32f") + return FORMAT_RG32F; + else if(name=="rg16f") + return FORMAT_RG16F; + else if(name=="r16f") + return FORMAT_R16F; + else if(name=="rgba16") + return FORMAT_RGBA16; + else if(name=="rg16") + return FORMAT_RG16; + else if(name=="rg8") + return FORMAT_RG8; + else if(name=="r16") + return FORMAT_RG16; + else if(name=="r8") + return FORMAT_RG8; + else if(name=="rgba16_snorm") + return FORMAT_RGBA16_SNORM; + else if(name=="rg16_snorm") + return FORMAT_RG16_SNORM; + else if(name=="rg8_snorm") + return FORMAT_RG8_SNORM; + else if(name=="r16_snorm") + return FORMAT_RG16_SNORM; + else if(name=="r8_snorm") + return FORMAT_RG8_SNORM; + else + throw invalid_argument("SpirVGenerator::get_format"); +} + void SpirVGenerator::use_capability(Capability cap) { if(used_capabilities.count(cap)) @@ -1292,11 +1340,13 @@ void SpirVGenerator::visit_builtin_texture_query(FunctionCall &call, const vecto Opcode opcode; if(call.name=="textureSize") opcode = OP_IMAGE_QUERY_SIZE_LOD; + else if(call.name=="imageSize") + opcode = OP_IMAGE_QUERY_SIZE; else if(call.name=="textureQueryLod") opcode = OP_IMAGE_QUERY_LOD; else if(call.name=="textureQueryLevels") opcode = OP_IMAGE_QUERY_LEVELS; - else if(call.name=="textureSamples") + else if(call.name=="textureSamples" || call.name=="imageSamples") opcode = OP_IMAGE_QUERY_SAMPLES; else throw internal_error("invalid texture query call"); @@ -1304,7 +1354,7 @@ void SpirVGenerator::visit_builtin_texture_query(FunctionCall &call, const vecto 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]); @@ -1369,19 +1419,54 @@ void SpirVGenerator::visit_builtin_texture(FunctionCall &call, const vector end_expression(opcode); } -void SpirVGenerator::visit_builtin_texel_fetch(FunctionCall &call, const vector &argument_ids) +void SpirVGenerator::visit_builtin_texture_fetch(FunctionCall &call, const vector &argument_ids) +{ + const ImageTypeDeclaration &image = dynamic_cast(*call.arguments[0]->type); + + Opcode opcode; + if(call.name=="texelFetch") + opcode = OP_IMAGE_FETCH; + else if(call.name=="imageLoad") + opcode = OP_IMAGE_READ; + else + throw internal_error("invalid texture fetch call"); + + bool need_sample = image.multisample; + bool need_lod = (opcode==OP_IMAGE_FETCH && !need_sample); + + 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]); + 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_texture_store(FunctionCall &call, const vector &argument_ids) { if(argument_ids.size()!=3) - throw internal_error("invalid texelFetch call"); + throw internal_error("invalid texture store call"); const ImageTypeDeclaration &image = dynamic_cast(*call.arguments[0]->type); - r_expression_result_id = begin_expression(OP_IMAGE_FETCH, get_id(*call.type), 4); + begin_expression(OP_IMAGE_WRITE, get_id(*call.type), 3+image.multisample*2); for(unsigned i=0; i<2; ++i) writer.write(argument_ids[i]); - writer.write(image.multisample ? 0x40 : 0x02); // Sample or Lod writer.write(argument_ids.back()); - end_expression(OP_IMAGE_FETCH); + if(image.multisample) + { + writer.write(0x40); // Sample + writer.write(argument_ids[2]); + } + end_expression(OP_IMAGE_WRITE); + + r_expression_result_id = 0; } void SpirVGenerator::visit_builtin_interpolate(FunctionCall &call, const vector &argument_ids) @@ -1499,7 +1584,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image) writer.write(image.array); writer.write(image.multisample); writer.write(image.sampled ? 1 : 2); - writer.write(0); // Format (unknown) + writer.write(get_format(image.format)); writer.end_op(OP_TYPE_IMAGE); if(image.sampled) @@ -1513,6 +1598,9 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image) use_capability(image.sampled ? CAP_SAMPLED_1D : CAP_IMAGE_1D); else if(image.dimensions==ImageTypeDeclaration::CUBE && image.array) use_capability(image.sampled ? CAP_SAMPLED_CUBE_ARRAY : CAP_IMAGE_CUBE_ARRAY); + + if(image.multisample && !image.sampled) + use_capability(CAP_STORAGE_IMAGE_MULTISAMPLE); } void SpirVGenerator::visit(StructDeclaration &strct)