From 561dc036f25cfd9d9bad8996b11ccd185b4bef3f Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 25 Apr 2017 16:32:16 -0400 Subject: [PATCH] CompilerMSL round floating point tex coords for read() and tex array index. --- spirv_msl.cpp | 38 ++++++++++++++++++++++---------------- spirv_msl.hpp | 1 + 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 74ef7abb..c0324103 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -1038,9 +1038,10 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool bool forward = should_forward(coord); auto coord_expr = to_enclosed_expression(coord); auto &coord_type = expression_type(coord); + bool coord_is_fp = (coord_type.basetype == SPIRType::Float) || (coord_type.basetype == SPIRType::Double); + bool is_cube_fetch = false; string tex_coords = coord_expr; - string face_expr; const char *alt_coord = ""; switch (imgtype.image.dim) @@ -1048,25 +1049,23 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool case Dim1D: if (coord_type.vecsize > 1) - { tex_coords += ".x"; - alt_coord = ".y"; - } if (is_fetch) - tex_coords = "uint(" + tex_coords + ")"; + tex_coords = "uint(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")"; + + alt_coord = ".y"; break; case DimBuffer: if (coord_type.vecsize > 1) - { tex_coords += ".x"; - alt_coord = ".y"; - } if (is_fetch) - tex_coords = "uint2(" + tex_coords + ", 0)"; // Metal textures are 2D + tex_coords = "uint2(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ", 0)"; // Metal textures are 2D + + alt_coord = ".y"; break; @@ -1075,7 +1074,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool tex_coords += ".xy"; if (is_fetch) - tex_coords = "uint2(" + tex_coords + ")"; + tex_coords = "uint2(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")"; alt_coord = ".z"; @@ -1086,7 +1085,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool tex_coords += ".xyz"; if (is_fetch) - tex_coords = "uint3(" + tex_coords + ")"; + tex_coords = "uint3(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")"; alt_coord = ".w"; @@ -1095,8 +1094,9 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool case DimCube: if (is_fetch) { - tex_coords = "uint2(" + tex_coords + ".xy)"; - face_expr = coord_expr + ".z"; + is_cube_fetch = true; + tex_coords += ".xy"; + tex_coords = "uint2(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")"; } else { @@ -1121,12 +1121,12 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool farg_str += tex_coords; // If fetch from cube, add face explicitly - if (!face_expr.empty()) - farg_str += ", uint(" + face_expr + ")"; + if (is_cube_fetch) + farg_str += ", uint(" + round_fp_tex_coords(coord_expr + ".z", coord_is_fp) + ")"; // If array, use alt coord if (imgtype.image.arrayed) - farg_str += ", uint(" + coord_expr + alt_coord + ")"; + farg_str += ", uint(" + round_fp_tex_coords(coord_expr + alt_coord, coord_is_fp) + ")"; // Depth compare reference value if (dref) @@ -1232,6 +1232,12 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool return farg_str; } +// If the texture coordinates are floating point, invokes MSL round() function to round them. +string CompilerMSL::round_fp_tex_coords(string tex_coords, bool coord_is_fp) +{ + return coord_is_fp ? ("round(" + tex_coords + ")") : tex_coords; +} + // Returns a string to use in an image sampling function argument. // The ID must be a scalar constant. string CompilerMSL::to_component_argument(uint32_t id) diff --git a/spirv_msl.hpp b/spirv_msl.hpp index ecad29e6..a46ca0d9 100644 --- a/spirv_msl.hpp +++ b/spirv_msl.hpp @@ -181,6 +181,7 @@ protected: std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma); std::string member_attribute_qualifier(const SPIRType &type, uint32_t index); std::string argument_decl(const SPIRFunction::Parameter &arg); + std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp); uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype); uint32_t get_ordered_member_location(uint32_t type_id, uint32_t index); size_t get_declared_type_size(uint32_t type_id) const;