v3d: Add missing macro for stvpmd instruction
[mesa.git] / src / broadcom / compiler / v3d_nir_lower_image_load_store.c
index e74206b394912542a2e7ebc7517860dc3c8ba479..7b6b0b15cf842e8d9351a0382f8659b5eff516e8 100644 (file)
  */
 
 bool
-v3d_gl_format_is_return_32(GLenum format)
+v3d_gl_format_is_return_32(enum pipe_format format)
 {
-        switch (format) {
-        case GL_R8:
-        case GL_R8_SNORM:
-        case GL_R8UI:
-        case GL_R8I:
-        case GL_RG8:
-        case GL_RG8_SNORM:
-        case GL_RG8UI:
-        case GL_RG8I:
-        case GL_RGBA8:
-        case GL_RGBA8_SNORM:
-        case GL_RGBA8UI:
-        case GL_RGBA8I:
-        case GL_R11F_G11F_B10F:
-        case GL_RGB10_A2:
-        case GL_RGB10_A2UI:
-        case GL_R16F:
-        case GL_R16UI:
-        case GL_R16I:
-        case GL_RG16F:
-        case GL_RG16UI:
-        case GL_RG16I:
-        case GL_RGBA16F:
-        case GL_RGBA16UI:
-        case GL_RGBA16I:
-                return false;
-        case GL_R16:
-        case GL_R16_SNORM:
-        case GL_RG16:
-        case GL_RG16_SNORM:
-        case GL_RGBA16:
-        case GL_RGBA16_SNORM:
-        case GL_R32F:
-        case GL_R32UI:
-        case GL_R32I:
-        case GL_RG32F:
-        case GL_RG32UI:
-        case GL_RG32I:
-        case GL_RGBA32F:
-        case GL_RGBA32UI:
-        case GL_RGBA32I:
-                return true;
-        default:
-                unreachable("Invalid image format");
-        }
+        const struct util_format_description *desc =
+                util_format_description(format);
+        const struct util_format_channel_description *chan = &desc->channel[0];
+
+        return chan->size > 16 || (chan->size == 16 && chan->normalized);
 }
 
 /* Packs a 32-bit vector of colors in the range [0, (1 << bits[i]) - 1] to a
@@ -124,192 +84,74 @@ pack_bits(nir_builder *b, nir_ssa_def *color, const unsigned *bits,
         return nir_vec(b, results, DIV_ROUND_UP(offset, 32));
 }
 
-static nir_ssa_def *
-pack_unorm(nir_builder *b, nir_ssa_def *color, const unsigned *bits,
-           int num_components)
-{
-        color = nir_channels(b, color, (1 << num_components) - 1);
-        color = nir_format_float_to_unorm(b, color, bits);
-        return pack_bits(b, color, bits, color->num_components, false);
-}
-
-static nir_ssa_def *
-pack_snorm(nir_builder *b, nir_ssa_def *color, const unsigned *bits,
-           int num_components)
-{
-        color = nir_channels(b, color, (1 << num_components) - 1);
-        color = nir_format_float_to_snorm(b, color, bits);
-        return pack_bits(b, color, bits, color->num_components, true);
-}
-
-static nir_ssa_def *
-pack_uint(nir_builder *b, nir_ssa_def *color, const unsigned *bits,
-          int num_components)
-{
-        color = nir_channels(b, color, (1 << num_components) - 1);
-        color = nir_format_clamp_uint(b, color, bits);
-        return pack_bits(b, color, bits, num_components, false);
-}
-
-static nir_ssa_def *
-pack_sint(nir_builder *b, nir_ssa_def *color, const unsigned *bits,
-          int num_components)
-{
-        color = nir_channels(b, color, (1 << num_components) - 1);
-        color = nir_format_clamp_uint(b, color, bits);
-        return pack_bits(b, color, bits, num_components, true);
-}
-
-static nir_ssa_def *
-pack_half(nir_builder *b, nir_ssa_def *color, const unsigned *bits,
-          int num_components)
-{
-        color = nir_channels(b, color, (1 << num_components) - 1);
-        color = nir_format_float_to_half(b, color);
-        return pack_bits(b, color, bits, color->num_components, false);
-}
-
 static void
 v3d_nir_lower_image_store(nir_builder *b, nir_intrinsic_instr *instr)
 {
-        nir_variable *var = nir_intrinsic_get_var(instr, 0);
-        GLenum format = var->data.image.format;
-        static const unsigned bits_8[4] = {8, 8, 8, 8};
-        static const unsigned bits_16[4] = {16, 16, 16, 16};
-        static const unsigned bits_1010102[4] = {10, 10, 10, 2};
+        enum pipe_format format = nir_intrinsic_format(instr);
+        const struct util_format_description *desc =
+                util_format_description(format);
+        const struct util_format_channel_description *r_chan = &desc->channel[0];
+        unsigned num_components = util_format_get_nr_components(format);
 
         b->cursor = nir_before_instr(&instr->instr);
 
-        nir_ssa_def *unformatted = nir_ssa_for_src(b, instr->src[3], 4);
+        nir_ssa_def *color = nir_channels(b,
+                                          nir_ssa_for_src(b, instr->src[3], 4),
+                                          (1 << num_components) - 1);
         nir_ssa_def *formatted = NULL;
-        switch (format) {
-        case GL_RGBA32F:
-        case GL_RGBA32UI:
-        case GL_RGBA32I:
-                /* For 4-component 32-bit components, there's no packing to be
-                 * done.
-                 */
-                return;
 
-        case GL_R32F:
-        case GL_R32UI:
-        case GL_R32I:
-                /* For other 32-bit components, just reduce the size of
-                 * the input vector.
+        if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
+                formatted = nir_format_pack_11f11f10f(b, color);
+        } else if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
+                formatted = nir_format_pack_r9g9b9e5(b, color);
+        } else if (r_chan->size == 32) {
+                /* For 32-bit formats, we just have to move the vector
+                 * across (possibly reducing the number of channels).
                  */
-                formatted = nir_channels(b, unformatted, 1);
-                break;
-        case GL_RG32F:
-        case GL_RG32UI:
-        case GL_RG32I:
-                formatted = nir_channels(b, unformatted, 2);
-                break;
-
-        case GL_R8:
-                formatted = pack_unorm(b, unformatted, bits_8, 1);
-                break;
-        case GL_RG8:
-                formatted = pack_unorm(b, unformatted, bits_8, 2);
-                break;
-        case GL_RGBA8:
-                formatted = pack_unorm(b, unformatted, bits_8, 4);
-                break;
-
-        case GL_R8_SNORM:
-                formatted = pack_snorm(b, unformatted, bits_8, 1);
-                break;
-        case GL_RG8_SNORM:
-                formatted = pack_snorm(b, unformatted, bits_8, 2);
-                break;
-        case GL_RGBA8_SNORM:
-                formatted = pack_snorm(b, unformatted, bits_8, 4);
-                break;
-
-        case GL_R16:
-                formatted = pack_unorm(b, unformatted, bits_16, 1);
-                break;
-        case GL_RG16:
-                formatted = pack_unorm(b, unformatted, bits_16, 2);
-                break;
-        case GL_RGBA16:
-                formatted = pack_unorm(b, unformatted, bits_16, 4);
-                break;
-
-        case GL_R16_SNORM:
-                formatted = pack_snorm(b, unformatted, bits_16, 1);
-                break;
-        case GL_RG16_SNORM:
-                formatted = pack_snorm(b, unformatted, bits_16, 2);
-                break;
-        case GL_RGBA16_SNORM:
-                formatted = pack_snorm(b, unformatted, bits_16, 4);
-                break;
-
-        case GL_R16F:
-                formatted = pack_half(b, unformatted, bits_16, 1);
-                break;
-        case GL_RG16F:
-                formatted = pack_half(b, unformatted, bits_16, 2);
-                break;
-        case GL_RGBA16F:
-                formatted = pack_half(b, unformatted, bits_16, 4);
-                break;
-
-        case GL_R8UI:
-                formatted = pack_uint(b, unformatted, bits_8, 1);
-                break;
-        case GL_R8I:
-                formatted = pack_sint(b, unformatted, bits_8, 1);
-                break;
-        case GL_RG8UI:
-                formatted = pack_uint(b, unformatted, bits_8, 2);
-                break;
-        case GL_RG8I:
-                formatted = pack_sint(b, unformatted, bits_8, 2);
-                break;
-        case GL_RGBA8UI:
-                formatted = pack_uint(b, unformatted, bits_8, 4);
-                break;
-        case GL_RGBA8I:
-                formatted = pack_sint(b, unformatted, bits_8, 4);
-                break;
-
-        case GL_R16UI:
-                formatted = pack_uint(b, unformatted, bits_16, 1);
-                break;
-        case GL_R16I:
-                formatted = pack_sint(b, unformatted, bits_16, 1);
-                break;
-        case GL_RG16UI:
-                formatted = pack_uint(b, unformatted, bits_16, 2);
-                break;
-        case GL_RG16I:
-                formatted = pack_sint(b, unformatted, bits_16, 2);
-                break;
-        case GL_RGBA16UI:
-                formatted = pack_uint(b, unformatted, bits_16, 4);
-                break;
-        case GL_RGBA16I:
-                formatted = pack_sint(b, unformatted, bits_16, 4);
-                break;
-
-        case GL_R11F_G11F_B10F:
-                formatted = nir_format_pack_11f11f10f(b, unformatted);
-                break;
-        case GL_RGB9_E5:
-                formatted = nir_format_pack_r9g9b9e5(b, unformatted);
-                break;
-
-        case GL_RGB10_A2:
-                formatted = pack_unorm(b, unformatted, bits_1010102, 4);
-                break;
+                formatted = color;
+        } else {
+                static const unsigned bits_8[4] = {8, 8, 8, 8};
+                static const unsigned bits_16[4] = {16, 16, 16, 16};
+                static const unsigned bits_1010102[4] = {10, 10, 10, 2};
+                const unsigned *bits;
+
+                switch (r_chan->size) {
+                case 8:
+                        bits = bits_8;
+                        break;
+                case 10:
+                        bits = bits_1010102;
+                        break;
+                case 16:
+                        bits = bits_16;
+                        break;
+                default:
+                        unreachable("unrecognized bits");
+                }
 
-        case GL_RGB10_A2UI:
-                formatted = pack_uint(b, unformatted, bits_1010102, 4);
-                break;
+                bool pack_mask = false;
+                if (r_chan->pure_integer &&
+                    r_chan->type == UTIL_FORMAT_TYPE_SIGNED) {
+                        formatted = nir_format_clamp_sint(b, color, bits);
+                        pack_mask = true;
+                } else if (r_chan->pure_integer &&
+                           r_chan->type == UTIL_FORMAT_TYPE_UNSIGNED) {
+                        formatted = nir_format_clamp_uint(b, color, bits);
+                } else if (r_chan->normalized &&
+                           r_chan->type == UTIL_FORMAT_TYPE_SIGNED) {
+                        formatted = nir_format_float_to_snorm(b, color, bits);
+                        pack_mask = true;
+                } else if (r_chan->normalized &&
+                           r_chan->type == UTIL_FORMAT_TYPE_UNSIGNED) {
+                        formatted = nir_format_float_to_unorm(b, color, bits);
+                } else {
+                        assert(r_chan->size == 16);
+                        assert(r_chan->type == UTIL_FORMAT_TYPE_FLOAT);
+                        formatted = nir_format_float_to_half(b, color);
+                }
 
-        default:
-                unreachable("bad format");
+                formatted = pack_bits(b, formatted, bits, num_components,
+                                      pack_mask);
         }
 
         nir_instr_rewrite_src(&instr->instr, &instr->src[3],
@@ -321,19 +163,20 @@ static void
 v3d_nir_lower_image_load(nir_builder *b, nir_intrinsic_instr *instr)
 {
         static const unsigned bits16[] = {16, 16, 16, 16};
-        nir_variable *var = nir_intrinsic_get_var(instr, 0);
-        const struct glsl_type *sampler_type = glsl_without_array(var->type);
-        enum glsl_base_type base_type =
-                glsl_get_sampler_result_type(sampler_type);
+        enum pipe_format format = nir_intrinsic_format(instr);
 
-        if (v3d_gl_format_is_return_32(var->data.image.format))
+        if (v3d_gl_format_is_return_32(format))
                 return;
 
         b->cursor = nir_after_instr(&instr->instr);
 
         assert(instr->dest.is_ssa);
         nir_ssa_def *result = &instr->dest.ssa;
-        if (base_type == GLSL_TYPE_FLOAT) {
+        if (util_format_is_pure_uint(format)) {
+                result = nir_format_unpack_uint(b, result, bits16, 4);
+        } else if (util_format_is_pure_sint(format)) {
+                result = nir_format_unpack_sint(b, result, bits16, 4);
+        } else {
             nir_ssa_def *rg = nir_channel(b, result, 0);
             nir_ssa_def *ba = nir_channel(b, result, 1);
             result = nir_vec4(b,
@@ -341,11 +184,6 @@ v3d_nir_lower_image_load(nir_builder *b, nir_intrinsic_instr *instr)
                               nir_unpack_half_2x16_split_y(b, rg),
                               nir_unpack_half_2x16_split_x(b, ba),
                               nir_unpack_half_2x16_split_y(b, ba));
-        } else if (base_type == GLSL_TYPE_INT) {
-                result = nir_format_unpack_sint(b, result, bits16, 4);
-        } else {
-                assert(base_type == GLSL_TYPE_UINT);
-                result = nir_format_unpack_uint(b, result, bits16, 4);
         }
 
         nir_ssa_def_rewrite_uses_after(&instr->dest.ssa, nir_src_for_ssa(result),
@@ -371,10 +209,10 @@ v3d_nir_lower_image_load_store(nir_shader *s)
                                         nir_instr_as_intrinsic(instr);
 
                                 switch (intr->intrinsic) {
-                                case nir_intrinsic_image_deref_load:
+                                case nir_intrinsic_image_load:
                                         v3d_nir_lower_image_load(&b, intr);
                                         break;
-                                case nir_intrinsic_image_deref_store:
+                                case nir_intrinsic_image_store:
                                         v3d_nir_lower_image_store(&b, intr);
                                         break;
                                 default: