[Mesa-dev] [PATCH v2 27/31] glsl: implement ARB_bindless_texture conversions

Samuel Pitoiset samuel.pitoiset at gmail.com
Wed Apr 26 08:25:42 UTC 2017



On 04/26/2017 10:02 AM, Nicolai Hähnle wrote:
> On 26.04.2017 06:45, Timothy Arceri wrote:
>>
>>
>> On 24/04/17 20:35, Samuel Pitoiset wrote:
>>> The ARB_bindless_texture spec says:
>>>
>>>     "Modify Section 5.4.1, Conversion and Scalar Constructors, p. 60"
>>>
>>>      (add the following constructors:)
>>>
>>>        // In the following four constructors, the low 32 bits of the
>>> sampler
>>>        // type correspond to the .x component of the uvec2 and the
>>> high 32 bits
>>>        // correspond to the .y component.
>>>        uvec2(any sampler type)     // Converts a sampler type to a
>>>                                    //   pair of 32-bit unsigned integers
>>>        any sampler type(uvec2)     // Converts a pair of 32-bit
>>> unsigned integers to
>>>                                    //   a sampler type
>>>        uvec2(any image type)       // Converts an image type to a
>>>                                    //   pair of 32-bit unsigned integers
>>>        any image type(uvec2)       // Converts a pair of 32-bit
>>> unsigned integers to
>>>                                    //   an image type
>>>
>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>>> ---
>>>   src/compiler/glsl/ast_function.cpp | 80
>>> ++++++++++++++++++++++++++++++++------
>>>   src/compiler/glsl/ir.cpp           | 12 +++++-
>>>   src/compiler/glsl/ir_clone.cpp     |  4 +-
>>>   3 files changed, 81 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/src/compiler/glsl/ast_function.cpp
>>> b/src/compiler/glsl/ast_function.cpp
>>> index 9aac9c51e4..a2b9347217 100644
>>> --- a/src/compiler/glsl/ast_function.cpp
>>> +++ b/src/compiler/glsl/ast_function.cpp
>>> @@ -740,8 +740,8 @@ convert_component(ir_rvalue *src, const glsl_type
>>> *desired_type)
>>>      if (src->type->is_error())
>>>         return src;
>>>   -   assert(a <= GLSL_TYPE_BOOL);
>>> -   assert(b <= GLSL_TYPE_BOOL);
>>> +   assert(a <= GLSL_TYPE_IMAGE);
>>> +   assert(b <= GLSL_TYPE_IMAGE);
>>>        if (a == b)
>>>         return src;
>>> @@ -769,6 +769,12 @@ convert_component(ir_rvalue *src, const glsl_type
>>> *desired_type)
>>>         case GLSL_TYPE_INT64:
>>>            result = new(ctx) ir_expression(ir_unop_i642u, src);
>>>            break;
>>> +      case GLSL_TYPE_SAMPLER:
>>> +         result = new(ctx) ir_expression(ir_unop_unpack_sampler_2x32,
>>> src);
>>> +         break;
>>> +      case GLSL_TYPE_IMAGE:
>>> +         result = new(ctx) ir_expression(ir_unop_unpack_image_2x32,
>>> src);
>>> +         break;
>>>         }
>>>         break;
>>>      case GLSL_TYPE_INT:
>>> @@ -911,6 +917,22 @@ convert_component(ir_rvalue *src, const glsl_type
>>> *desired_type)
>>>            break;
>>>         }
>>>         break;
>>> +   case GLSL_TYPE_SAMPLER:
>>> +      switch (b) {
>>> +      case GLSL_TYPE_UINT:
>>> +         result = new(ctx)
>>> +            ir_expression(ir_unop_pack_sampler_2x32, desired_type, 
>>> src);
>>> +         break;
>>> +      }
>>> +      break;
>>> +   case GLSL_TYPE_IMAGE:
>>> +      switch (b) {
>>> +      case GLSL_TYPE_UINT:
>>> +         result = new(ctx)
>>> +            ir_expression(ir_unop_pack_image_2x32, desired_type, src);
>>> +         break;
>>> +      }
>>> +      break;
>>>      }
>>>        assert(result != NULL);
>>> @@ -984,7 +1006,10 @@ static ir_rvalue *
>>>   dereference_component(ir_rvalue *src, unsigned component)
>>>   {
>>>      void *ctx = ralloc_parent(src);
>>> -   assert(component < src->type->components());
>>> +   unsigned src_components =
>>> +      src->type->is_sampler() ? 1 : src->type->components();
>>> +
>>> +   assert(component < src_components);
>>>        /* If the source is a constant, just create a new constant
>>> instead of a
>>>       * dereference of the existing constant.
>>> @@ -993,7 +1018,9 @@ dereference_component(ir_rvalue *src, unsigned
>>> component)
>>>      if (constant)
>>>         return new(ctx) ir_constant(constant, component);
>>>   -   if (src->type->is_scalar()) {
>>> +   if (src->type->is_scalar() ||
>>> +       src->type->is_sampler() ||
>>> +       src->type->is_image()) {
>>>         return src;
>>>      } else if (src->type->is_vector()) {
>>>         return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1);
>>> @@ -1933,7 +1960,8 @@ ast_function_expression::handle_method(exec_list
>>> *instructions,
>>>   static inline bool is_valid_constructor(const glsl_type *type,
>>>                                           struct
>>> _mesa_glsl_parse_state *state)
>>>   {
>>> -   return type->is_numeric() || type->is_boolean();
>>> +   return type->is_numeric() || type->is_boolean() ||
>>> +          (state->has_bindless() && (type->is_sampler() ||
>>> type->is_image()));
>>>   }
>>>     ir_rvalue *
>>> @@ -2018,7 +2046,8 @@ ast_function_expression::hir(exec_list
>>> *instructions,
>>>            return ir_rvalue::error_value(ctx);
>>>           /* Total number of components of the type being 
>>> constructed. */
>>> -      const unsigned type_components = constructor_type->components();
>>> +      const unsigned type_components =
>>> +         constructor_type->is_sampler() ? 1 :
>>> constructor_type->components();
>>
>> I haven't looked closely at this so I'm not even sure why we do this.
>> But my question is why only for samplers and not images?
> 
> Yes, unless there's some good reason not to, it seems it would make more 
> sense to have sampler and image types have vector_elements == 
> matrix_columns == 1.

It's because vector_elements = 0 for samplers and 1 for images. We 
discussed about that point with Nicolai on IRC but I'm not sure myself 
if it's correct to change it.

Though, it will help in many places.

> 
> Cheers,
> Nicolai
> 
> 
>>
>>
>>>           /* Number of components from parameters that have actually 
>>> been
>>>          * consumed.  This is used to perform several kinds of error
>>> checking.
>>> @@ -2060,7 +2089,8 @@ ast_function_expression::hir(exec_list
>>> *instructions,
>>>               nonmatrix_parameters++;
>>>              actual_parameters.push_tail(result);
>>> -         components_used += result->type->components();
>>> +         components_used +=
>>> +            result->type->is_sampler() ? 1 : 
>>> result->type->components();
>>>         }
>>>           /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
>>> @@ -2136,10 +2166,34 @@ ast_function_expression::hir(exec_list
>>> *instructions,
>>>           /* Type cast each parameter and, if possible, fold 
>>> constants.*/
>>>         foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
>>> -         const glsl_type *desired_type =
>>> -            glsl_type::get_instance(constructor_type->base_type,
>>> -                                    ir->type->vector_elements,
>>> -                                    ir->type->matrix_columns);
>>> +         const glsl_type *desired_type;
>>> +
>>> +         if (ir->type->is_sampler() || ir->type->is_image()) {
>>> +            /* Convert a sampler/image type to a pair of 32-bit 
>>> unsigned
>>> +             * integers as defined by ARB_bindless_texture. */
>>> +            if (constructor_type != glsl_type::uvec2_type) {
>>> +               _mesa_glsl_error(&loc, state, "sampler and image types
>>> can only "
>>> +                                "be converted to a pair of 32-bit
>>> unsigned "
>>> +                                "integers");
>>> +            }
>>> +            desired_type = glsl_type::uvec2_type;
>>> +         } else if (constructor_type->is_sampler() ||
>>> +                    constructor_type->is_image()) {
>>> +            /* Convert a pair of 32-bit unsigned integers to a
>>> sampler or image
>>> +             * type as defined by ARB_bindless_texture. */
>>> +            if (ir->type != glsl_type::uvec2_type) {
>>> +               _mesa_glsl_error(&loc, state, "sampler and image types
>>> can only "
>>> +                                "be converted from a pair of 32-bit
>>> unsigned "
>>> +                                "integers");
>>> +            }
>>> +            desired_type = constructor_type;
>>> +         } else {
>>> +            desired_type =
>>> +               glsl_type::get_instance(constructor_type->base_type,
>>> +                                       ir->type->vector_elements,
>>> +                                       ir->type->matrix_columns);
>>> +         }
>>> +
>>>            ir_rvalue *result = convert_component(ir, desired_type);
>>>              /* Attempt to convert the parameter to a constant valued
>>> expression.
>>> @@ -2163,7 +2217,9 @@ ast_function_expression::hir(exec_list
>>> *instructions,
>>>          */
>>>         if (all_parameters_are_constant) {
>>>            return new(ctx) ir_constant(constructor_type,
>>> &actual_parameters);
>>> -      } else if (constructor_type->is_scalar()) {
>>> +      } else if (constructor_type->is_scalar() ||
>>> (state->has_bindless() &&
>>> +                 (constructor_type->is_sampler() ||
>>> +                  constructor_type->is_image()))) {
>>>            return dereference_component((ir_rvalue *)
>>>                                         
>>> actual_parameters.get_head_raw(),
>>>                                         0);
>>> diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
>>> index 2b0d3522e5..9ebf8bc578 100644
>>> --- a/src/compiler/glsl/ir.cpp
>>> +++ b/src/compiler/glsl/ir.cpp
>>> @@ -370,6 +370,16 @@ ir_expression::ir_expression(int op, ir_rvalue 
>>> *op0)
>>>         this->type = glsl_type::vec4_type;
>>>         break;
>>>   +   case ir_unop_unpack_sampler_2x32:
>>> +   case ir_unop_unpack_image_2x32:
>>> +      this->type = glsl_type::uvec2_type;
>>> +      break;
>>> +
>>> +   case ir_unop_pack_sampler_2x32:
>>> +   case ir_unop_pack_image_2x32:
>>> +      this->type = op0->type;
>>> +      break;
>>> +
>>>      case ir_unop_frexp_sig:
>>>         this->type = op0->type;
>>>         break;
>>> @@ -624,7 +634,7 @@ ir_constant::ir_constant(const struct glsl_type
>>> *type,
>>>      this->array_elements = NULL;
>>>        assert((type->base_type >= GLSL_TYPE_UINT)
>>> -      && (type->base_type <= GLSL_TYPE_BOOL));
>>> +      && (type->base_type <= GLSL_TYPE_IMAGE));
>>>        this->type = type;
>>>      memcpy(& this->value, data, sizeof(this->value));
>>> diff --git a/src/compiler/glsl/ir_clone.cpp
>>> b/src/compiler/glsl/ir_clone.cpp
>>> index bfe2573c07..a64c7afa94 100644
>>> --- a/src/compiler/glsl/ir_clone.cpp
>>> +++ b/src/compiler/glsl/ir_clone.cpp
>>> @@ -339,6 +339,8 @@ ir_constant::clone(void *mem_ctx, struct
>>> hash_table *ht) const
>>>      case GLSL_TYPE_BOOL:
>>>      case GLSL_TYPE_UINT64:
>>>      case GLSL_TYPE_INT64:
>>> +   case GLSL_TYPE_SAMPLER:
>>> +   case GLSL_TYPE_IMAGE:
>>>         return new(mem_ctx) ir_constant(this->type, &this->value);
>>>        case GLSL_TYPE_STRUCT: {
>>> @@ -367,8 +369,6 @@ ir_constant::clone(void *mem_ctx, struct
>>> hash_table *ht) const
>>>         return c;
>>>      }
>>>   -   case GLSL_TYPE_SAMPLER:
>>> -   case GLSL_TYPE_IMAGE:
>>>      case GLSL_TYPE_ATOMIC_UINT:
>>>      case GLSL_TYPE_VOID:
>>>      case GLSL_TYPE_ERROR:
>>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
> 


More information about the mesa-dev mailing list