*/
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
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],
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,
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),
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: