[Mesa-dev] [PATCH v2 27/31] glsl: implement ARB_bindless_texture conversions
Nicolai Hähnle
nhaehnle at gmail.com
Wed Apr 26 08:02:40 UTC 2017
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.
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
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list