[Mesa-dev] [PATCH v2 27/31] glsl: implement ARB_bindless_texture conversions
Timothy Arceri
tarceri at itsqueeze.com
Wed Apr 26 04:45:19 UTC 2017
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?
>
> /* 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:
>
More information about the mesa-dev
mailing list