panfrost: Implement integer varyings
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 27 Dec 2019 21:01:34 +0000 (16:01 -0500)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 30 Dec 2019 22:11:08 +0000 (17:11 -0500)
We need to actually work out the varying format on demand, rather than
assuming rgba32f.

Fixes dEQP-GLES3.functional.fragment_out.basic.int.*

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/pan_assemble.c
src/panfrost/midgard/midgard_compile.c
src/panfrost/midgard/midgard_compile.h

index 6928f33faaed0d7338ca8dbabd2288a7985db0a0..acb688651e6877049f416f12ecf2345afa26ca6e 100644 (file)
@@ -148,7 +148,7 @@ panfrost_shader_compile(
 
                 /* Default to a vec4 varying */
                 struct mali_attr_meta v = {
-                        .format = MALI_RGBA32F,
+                        .format = program.varying_type[i],
                         .swizzle = default_vec4_swizzle,
                         .unknown1 = 0x2,
                 };
index abdd07cbb96816d0f87426a7eb6648d116ae77e5..0c7d60cd675fb545d0d2d52f8d80256d96f82fbc 100644 (file)
@@ -2533,6 +2533,58 @@ midgard_get_first_tag_from_block(compiler_context *ctx, unsigned block_idx)
         return first_tag;
 }
 
+static unsigned
+pan_format_from_nir_base(nir_alu_type base)
+{
+        switch (base) {
+        case nir_type_int:
+                return MALI_FORMAT_SINT;
+        case nir_type_uint:
+        case nir_type_bool:
+                return MALI_FORMAT_UINT;
+        case nir_type_float:
+                return MALI_CHANNEL_FLOAT;
+        default:
+                unreachable("Invalid base");
+        }
+}
+
+static unsigned
+pan_format_from_nir_size(nir_alu_type base, unsigned size)
+{
+        if (base == nir_type_float) {
+                switch (size) {
+                case 16: return MALI_FORMAT_SINT;
+                case 32: return MALI_FORMAT_UNORM;
+                default:
+                        unreachable("Invalid float size for format");
+                }
+        } else {
+                switch (size) {
+                case 1:
+                case 8:  return MALI_CHANNEL_8;
+                case 16: return MALI_CHANNEL_16;
+                case 32: return MALI_CHANNEL_32;
+                default:
+                         unreachable("Invalid int size for format");
+                }
+        }
+}
+
+static enum mali_format
+pan_format_from_glsl(const struct glsl_type *type)
+{
+        enum glsl_base_type glsl_base = glsl_get_base_type(glsl_without_array(type));
+        nir_alu_type t = nir_get_nir_type_for_glsl_base_type(glsl_base);
+
+        unsigned base = nir_alu_type_get_base_type(t);
+        unsigned size = nir_alu_type_get_type_size(t);
+
+        return pan_format_from_nir_base(base) |
+                pan_format_from_nir_size(base, size) |
+                MALI_NR_CHANNELS(4);
+}
+
 int
 midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_blend, unsigned blend_rt, unsigned gpu_id, bool shaderdb)
 {
@@ -2573,6 +2625,7 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
 
                 for (int c = 0; c < sz; ++c) {
                         program->varyings[loc + c] = var->data.location + c;
+                        program->varying_type[loc + c] = pan_format_from_glsl(var->type);
                         max_varying = MAX2(max_varying, loc + c);
                 }
         }
index 317a2b9e4c42762045d2e96a7ee6bbcd7e3011d5..9f29cab50767e04d8c632ad4debd395d23b4760b 100644 (file)
@@ -78,6 +78,7 @@ typedef struct {
         unsigned sysvals[MAX_SYSVAL_COUNT];
 
         unsigned varyings[32];
+        enum mali_format varying_type[32];
 
         /* Boolean properties of the program */
         bool writes_point_size;