Example #1
0
   virtual void visit_field(const glsl_type *type, const char *name,
                            bool row_major)
   {
      assert(!type->is_record());
      assert(!(type->is_array() && type->fields.array->is_record()));
      assert(!type->is_interface());
      assert(!(type->is_array() && type->fields.array->is_interface()));

      (void) row_major;

      /* Count the number of samplers regardless of whether the uniform is
       * already in the hash table.  The hash table prevents adding the same
       * uniform for multiple shader targets, but in this case we want to
       * count it for each shader target.
       */
      const unsigned values = values_for_type(type);
      if (type->contains_sampler()) {
	 this->num_shader_samplers +=
	    type->is_array() ? type->array_size() : 1;
      } else {
	 /* Accumulate the total number of uniform slots used by this shader.
	  * Note that samplers do not count against this limit because they
	  * don't use any storage on current hardware.
	  */
	 if (!is_ubo_var)
	    this->num_shader_uniform_components += values;
      }

      /* If the uniform is already in the map, there's nothing more to do.
       */
      unsigned id;
      if (this->map->get(id, name))
	 return;

      this->map->put(this->num_active_uniforms, name);

      /* Each leaf uniform occupies one entry in the list of active
       * uniforms.
       */
      this->num_active_uniforms++;
      this->num_values += values;
   }
   virtual void visit_field(const glsl_type *type, const char *name,
                            bool row_major)
   {
      assert(!type->is_record());
      assert(!(type->is_array() && type->fields.array->is_record()));
      assert(!type->is_interface());
      assert(!(type->is_array() && type->fields.array->is_interface()));

      (void) row_major;

      unsigned id;
      bool found = this->map->get(id, name);
      assert(found);

      if (!found)
	 return;

      /* If there is already storage associated with this uniform, it means
       * that it was set while processing an earlier shader stage.  For
       * example, we may be processing the uniform in the fragment shader, but
       * the uniform was already processed in the vertex shader.
       */
      if (this->uniforms[id].storage != NULL) {
	 /* If the uniform already has storage set from another shader stage,
	  * mark the samplers used for this shader stage.
	  */
	 if (type->contains_sampler()) {
	    const unsigned count = MAX2(1, this->uniforms[id].array_elements);
	    const unsigned shadow = (type->is_array())
	       ? type->fields.array->sampler_shadow : type->sampler_shadow;

	    for (unsigned i = 0; i < count; i++) {
	       const unsigned s = this->uniforms[id].sampler + i;

	       this->shader_samplers_used |= 1U << s;
	       this->shader_shadow_samplers |= shadow << s;
	    }
	 }

	 return;
      }

      const glsl_type *base_type;
      if (type->is_array()) {
	 this->uniforms[id].array_elements = type->length;
	 base_type = type->fields.array;
      } else {
	 this->uniforms[id].array_elements = 0;
	 base_type = type;
      }

      if (base_type->is_sampler()) {
	 this->uniforms[id].sampler = this->next_sampler;

	 /* Increment the sampler by 1 for non-arrays and by the number of
	  * array elements for arrays.
	  */
	 this->next_sampler += MAX2(1, this->uniforms[id].array_elements);

	 const gl_texture_index target = base_type->sampler_index();
	 const unsigned shadow = base_type->sampler_shadow;
	 for (unsigned i = this->uniforms[id].sampler
		 ; i < MIN2(this->next_sampler, MAX_SAMPLERS)
		 ; i++) {
	    this->targets[i] = target;
	    this->shader_samplers_used |= 1U << i;
	    this->shader_shadow_samplers |= shadow << i;
	 }

      } else {
	 this->uniforms[id].sampler = ~0;
      }

      this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
      this->uniforms[id].type = base_type;
      this->uniforms[id].initialized = 0;
      this->uniforms[id].num_driver_storage = 0;
      this->uniforms[id].driver_storage = NULL;
      this->uniforms[id].storage = this->values;
      if (this->ubo_block_index != -1) {
	 this->uniforms[id].block_index = this->ubo_block_index;

	 unsigned alignment = type->std140_base_alignment(ubo_row_major);
	 this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
	 this->uniforms[id].offset = this->ubo_byte_offset;
	 this->ubo_byte_offset += type->std140_size(ubo_row_major);

	 if (type->is_array()) {
	    this->uniforms[id].array_stride =
	       glsl_align(type->fields.array->std140_size(ubo_row_major), 16);
	 } else {
	    this->uniforms[id].array_stride = 0;
	 }

	 if (type->is_matrix() ||
	     (type->is_array() && type->fields.array->is_matrix())) {
	    this->uniforms[id].matrix_stride = 16;
	    this->uniforms[id].row_major = ubo_row_major;
	 } else {
	    this->uniforms[id].matrix_stride = 0;
	    this->uniforms[id].row_major = false;
	 }
      } else {
	 this->uniforms[id].block_index = -1;
	 this->uniforms[id].offset = -1;
	 this->uniforms[id].array_stride = -1;
	 this->uniforms[id].matrix_stride = -1;
	 this->uniforms[id].row_major = false;
      }

      this->values += values_for_type(type);
   }
   virtual void visit_field(const glsl_type *type, const char *name,
                            bool row_major, const glsl_type *record_type,
                            bool last_field)
   {
      assert(!type->without_array()->is_record());
      assert(!type->without_array()->is_interface());

      unsigned id;
      bool found = this->map->get(id, name);
      assert(found);

      if (!found)
	 return;

      const glsl_type *base_type;
      if (type->is_array()) {
	 this->uniforms[id].array_elements = type->length;
	 base_type = type->fields.array;
      } else {
	 this->uniforms[id].array_elements = 0;
	 base_type = type;
      }

      /* This assigns uniform indices to sampler and image uniforms. */
      handle_samplers(base_type, &this->uniforms[id]);
      handle_images(base_type, &this->uniforms[id]);

      /* If there is already storage associated with this uniform, it means
       * that it was set while processing an earlier shader stage.  For
       * example, we may be processing the uniform in the fragment shader, but
       * the uniform was already processed in the vertex shader.
       */
      if (this->uniforms[id].storage != NULL) {
         return;
      }

      /* Assign explicit locations. */
      if (current_var->data.explicit_location) {
         /* Set sequential locations for struct fields. */
         if (record_type != NULL) {
            const unsigned entries = MAX2(1, this->uniforms[id].array_elements);
            this->uniforms[id].remap_location =
               current_var->data.location + field_counter;
            field_counter += entries;
         } else {
            this->uniforms[id].remap_location = current_var->data.location;
         }
      } else {
         /* Initialize to to indicate that no location is set */
         this->uniforms[id].remap_location = UNMAPPED_UNIFORM_LOC;
      }

      this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
      this->uniforms[id].type = base_type;
      this->uniforms[id].initialized = 0;
      this->uniforms[id].num_driver_storage = 0;
      this->uniforms[id].driver_storage = NULL;
      this->uniforms[id].storage = this->values;
      this->uniforms[id].atomic_buffer_index = -1;
      if (this->ubo_block_index != -1) {
	 this->uniforms[id].block_index = this->ubo_block_index;

	 const unsigned alignment = record_type
	    ? record_type->std140_base_alignment(row_major)
	    : type->std140_base_alignment(row_major);
	 this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
	 this->uniforms[id].offset = this->ubo_byte_offset;
	 this->ubo_byte_offset += type->std140_size(row_major);

         if (last_field)
            this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, 16);

	 if (type->is_array()) {
	    this->uniforms[id].array_stride =
	       glsl_align(type->fields.array->std140_size(row_major), 16);
	 } else {
	    this->uniforms[id].array_stride = 0;
	 }

	 if (type->without_array()->is_matrix()) {
	    this->uniforms[id].matrix_stride = 16;
	    this->uniforms[id].row_major = row_major;
	 } else {
	    this->uniforms[id].matrix_stride = 0;
	    this->uniforms[id].row_major = false;
	 }
      } else {
	 this->uniforms[id].block_index = -1;
	 this->uniforms[id].offset = -1;
	 this->uniforms[id].array_stride = -1;
	 this->uniforms[id].matrix_stride = -1;
	 this->uniforms[id].row_major = false;
      }

      this->values += values_for_type(type);
   }
Example #4
0
   virtual void visit_field(const glsl_type *type, const char *name,
                            bool row_major)
   {
      assert(!type->is_record());
      assert(!(type->is_array() && type->fields.array->is_record()));
      assert(!type->is_interface());
      assert(!(type->is_array() && type->fields.array->is_interface()));

      (void) row_major;

      unsigned id;
      bool found = this->map->get(id, name);
      assert(found);

      if (!found)
	 return;

      const glsl_type *base_type;
      if (type->is_array()) {
	 this->uniforms[id].array_elements = type->length;
	 base_type = type->fields.array;
      } else {
	 this->uniforms[id].array_elements = 0;
	 base_type = type;
      }

      /* This assigns sampler uniforms to sampler units. */
      handle_samplers(base_type, &this->uniforms[id]);

      /* If there is already storage associated with this uniform, it means
       * that it was set while processing an earlier shader stage.  For
       * example, we may be processing the uniform in the fragment shader, but
       * the uniform was already processed in the vertex shader.
       */
      if (this->uniforms[id].storage != NULL) {
         return;
      }

      this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
      this->uniforms[id].type = base_type;
      this->uniforms[id].initialized = 0;
      this->uniforms[id].num_driver_storage = 0;
      this->uniforms[id].driver_storage = NULL;
      this->uniforms[id].storage = this->values;
      if (this->ubo_block_index != -1) {
	 this->uniforms[id].block_index = this->ubo_block_index;

	 unsigned alignment = type->std140_base_alignment(ubo_row_major);
	 this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
	 this->uniforms[id].offset = this->ubo_byte_offset;
	 this->ubo_byte_offset += type->std140_size(ubo_row_major);

	 if (type->is_array()) {
	    this->uniforms[id].array_stride =
	       glsl_align(type->fields.array->std140_size(ubo_row_major), 16);
	 } else {
	    this->uniforms[id].array_stride = 0;
	 }

	 if (type->is_matrix() ||
	     (type->is_array() && type->fields.array->is_matrix())) {
	    this->uniforms[id].matrix_stride = 16;
	    this->uniforms[id].row_major = ubo_row_major;
	 } else {
	    this->uniforms[id].matrix_stride = 0;
	    this->uniforms[id].row_major = false;
	 }
      } else {
	 this->uniforms[id].block_index = -1;
	 this->uniforms[id].offset = -1;
	 this->uniforms[id].array_stride = -1;
	 this->uniforms[id].matrix_stride = -1;
	 this->uniforms[id].row_major = false;
      }

      this->values += values_for_type(type);
   }
Example #5
0
    virtual void visit_field(const glsl_type *type, const char *name,
                             bool row_major, const glsl_type *record_type,
                             bool /* last_field */)
    {
        assert(!type->without_array()->is_record());
        assert(!type->without_array()->is_interface());

        unsigned id;
        bool found = this->map->get(id, name);
        assert(found);

        if (!found)
            return;

        const glsl_type *base_type;
        if (type->is_array()) {
            this->uniforms[id].array_elements = type->length;
            base_type = type->fields.array;
        } else {
            this->uniforms[id].array_elements = 0;
            base_type = type;
        }

        /* This assigns uniform indices to sampler and image uniforms. */
        handle_samplers(base_type, &this->uniforms[id]);
        handle_images(base_type, &this->uniforms[id]);
        handle_subroutines(base_type, &this->uniforms[id]);

        /* If there is already storage associated with this uniform or if the
         * uniform is set as builtin, it means that it was set while processing
         * an earlier shader stage.  For example, we may be processing the
         * uniform in the fragment shader, but the uniform was already processed
         * in the vertex shader.
         */
        if (this->uniforms[id].storage != NULL || this->uniforms[id].builtin) {
            return;
        }

        /* Assign explicit locations. */
        if (current_var->data.explicit_location) {
            /* Set sequential locations for struct fields. */
            if (record_type != NULL) {
                const unsigned entries = MAX2(1, this->uniforms[id].array_elements);
                this->uniforms[id].remap_location =
                    current_var->data.location + field_counter;
                field_counter += entries;
            } else {
                this->uniforms[id].remap_location = current_var->data.location;
            }
        } else {
            /* Initialize to to indicate that no location is set */
            this->uniforms[id].remap_location = UNMAPPED_UNIFORM_LOC;
        }

        this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
        this->uniforms[id].type = base_type;
        this->uniforms[id].initialized = 0;
        this->uniforms[id].num_driver_storage = 0;
        this->uniforms[id].driver_storage = NULL;
        this->uniforms[id].atomic_buffer_index = -1;
        this->uniforms[id].hidden =
            current_var->data.how_declared == ir_var_hidden;
        this->uniforms[id].builtin = is_gl_identifier(name);

        /* Do not assign storage if the uniform is builtin */
        if (!this->uniforms[id].builtin)
            this->uniforms[id].storage = this->values;

        if (this->ubo_block_index != -1) {
            this->uniforms[id].block_index = this->ubo_block_index;

            const unsigned alignment = type->std140_base_alignment(row_major);
            this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
            this->uniforms[id].offset = this->ubo_byte_offset;
            this->ubo_byte_offset += type->std140_size(row_major);

            if (type->is_array()) {
                this->uniforms[id].array_stride =
                    glsl_align(type->fields.array->std140_size(row_major), 16);
            } else {
                this->uniforms[id].array_stride = 0;
            }

            if (type->without_array()->is_matrix()) {
                const glsl_type *matrix = type->without_array();
                const unsigned N = matrix->base_type == GLSL_TYPE_DOUBLE ? 8 : 4;
                const unsigned items = row_major ? matrix->matrix_columns : matrix->vector_elements;

                assert(items <= 4);
                this->uniforms[id].matrix_stride = glsl_align(items * N, 16);
                this->uniforms[id].row_major = row_major;
            } else {
                this->uniforms[id].matrix_stride = 0;
                this->uniforms[id].row_major = false;
            }
        } else {
            this->uniforms[id].block_index = -1;
            this->uniforms[id].offset = -1;
            this->uniforms[id].array_stride = -1;
            this->uniforms[id].matrix_stride = -1;
            this->uniforms[id].row_major = false;
        }

        this->values += values_for_type(type);
    }