[Mesa-dev] [PATCH 2/3] i965: Implement a new type_size_4x() function.

Kenneth Graunke kenneth at whitecape.org
Thu Oct 15 15:17:20 PDT 2015


Often, shader inputs/outputs are required to be aligned to vec4 slots
for one reason or another.  When working with the scalar backend, we
want to count the number of scalar components, yet still respect the
vec4 packing rules as required.

The new "hybrid" type_size_4x() function pads everything out to vec4
slots, similar to type_size_vec4(), but counts in scalar components,
similar to type_size_scalar().

Cc: mesa-stable at lists.freedesktop.org
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_fs.cpp   | 52 ++++++++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_shader.h |  1 +
 2 files changed, 53 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 01a7c99..4af88c5 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -499,6 +499,58 @@ type_size_scalar(const struct glsl_type *type)
 }
 
 /**
+ * Returns the number of scalar components needed to store type, assuming
+ * that vectors are padded out to vec4.
+ *
+ * This has the packing rules of type_size_vec4(), but counts components
+ * similar to type_size_scalar().
+ */
+extern "C" int
+type_size_4x(const struct glsl_type *type)
+{
+   int size;
+
+   switch (type->base_type) {
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_BOOL:
+      if (type->is_matrix()) {
+         return 4 * type->matrix_columns;
+      } else {
+         /* Regardless of the size of vector, it's padded out to a vec4. */
+         return 4;
+      }
+   case GLSL_TYPE_ARRAY:
+      return type_size_4x(type->fields.array) * type->length;
+   case GLSL_TYPE_STRUCT:
+      size = 0;
+      for (unsigned i = 0; i < type->length; i++) {
+	 size += type_size_4x(type->fields.structure[i].type);
+      }
+      return size;
+   case GLSL_TYPE_SAMPLER:
+      /* Samplers take up no register space, since they're baked in at
+       * link time.
+       */
+      return 0;
+   case GLSL_TYPE_ATOMIC_UINT:
+      return 0;
+   case GLSL_TYPE_SUBROUTINE:
+      return 4;
+   case GLSL_TYPE_IMAGE:
+      return ALIGN(BRW_IMAGE_PARAM_SIZE, 4);
+   case GLSL_TYPE_VOID:
+   case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
+   case GLSL_TYPE_DOUBLE:
+      unreachable("not reached");
+   }
+
+   return 0;
+}
+
+/**
  * Create a MOV to read the timestamp register.
  *
  * The caller is responsible for emitting the MOV.  The return value is
diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
index ad2de5e..06a5b4c 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.h
+++ b/src/mesa/drivers/dri/i965/brw_shader.h
@@ -316,6 +316,7 @@ bool brw_cs_precompile(struct gl_context *ctx,
                        struct gl_program *prog);
 
 int type_size_scalar(const struct glsl_type *type);
+int type_size_4x(const struct glsl_type *type);
 int type_size_vec4(const struct glsl_type *type);
 
 bool is_scalar_shader_stage(const struct brw_compiler *compiler, int stage);
-- 
2.6.1



More information about the mesa-dev mailing list