i965: Move SOL PSIZ hacks from draw time to link time.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 28 Feb 2017 20:29:43 +0000 (12:29 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 1 Jun 2017 07:08:29 +0000 (00:08 -0700)
We can just update the gl_transform_feedback_info fields at link time
to make the VUE header fields have the right location and component.
Then we don't need to handle them specially at draw time, which is
expensive.

Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
src/intel/compiler/gen6_gs_visitor.cpp
src/mesa/drivers/dri/i965/brw_link.cpp
src/mesa/drivers/dri/i965/genX_state_upload.c

index fe9f834f0ce66dad39bb3a22b311e9db6356cd51..66c69fb058f7e989c8c9bd2f0ed65ac0bf0770e6 100644 (file)
@@ -687,18 +687,7 @@ gen6_gs_visitor::xfb_program(unsigned vertex, unsigned num_verts)
          emit(MOV(dst_reg(this->vertex_output_offset), brw_imm_d(offset)));
          memcpy(data.reladdr, &this->vertex_output_offset, sizeof(src_reg));
          data.type = output_reg[varying][0].type;
-
-         /* PSIZ, LAYER and VIEWPORT are packed in different channels of the
-          * same slot, so make sure we write the appropriate channel
-          */
-         if (varying == VARYING_SLOT_PSIZ)
-            data.swizzle = BRW_SWIZZLE_WWWW;
-         else if (varying == VARYING_SLOT_LAYER)
-            data.swizzle = BRW_SWIZZLE_YYYY;
-         else if (varying == VARYING_SLOT_VIEWPORT)
-            data.swizzle = BRW_SWIZZLE_ZZZZ;
-         else
-            data.swizzle = gs_prog_data->transform_feedback_swizzles[binding];
+         data.swizzle = gs_prog_data->transform_feedback_swizzles[binding];
 
          /* Write data */
          inst = emit(GS_OPCODE_SVB_WRITE, mrf_reg, data, sol_temp);
index 57aaf6b9dc0c979a0fdd651a7f1e36a5c4525774..e9158c596c5b43a2a50d5e850d3cd59068ea00a6 100644 (file)
@@ -28,6 +28,7 @@
 #include "compiler/glsl/ir_optimization.h"
 #include "compiler/glsl/program.h"
 #include "program/program.h"
+#include "main/mtypes.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "main/uniforms.h"
@@ -176,6 +177,39 @@ unify_interfaces(struct shader_info **infos)
    }
 }
 
+static void
+update_xfb_info(struct gl_transform_feedback_info *xfb_info)
+{
+   if (!xfb_info)
+      return;
+
+   for (unsigned i = 0; i < xfb_info->NumOutputs; i++) {
+      struct gl_transform_feedback_output *output = &xfb_info->Outputs[i];
+
+      /* The VUE header contains three scalar fields packed together:
+       * - gl_PointSize is stored in VARYING_SLOT_PSIZ.w
+       * - gl_Layer is stored in VARYING_SLOT_PSIZ.y
+       * - gl_ViewportIndex is stored in VARYING_SLOT_PSIZ.z
+       */
+      switch (output->OutputRegister) {
+      case VARYING_SLOT_LAYER:
+         assert(output->NumComponents == 1);
+         output->OutputRegister = VARYING_SLOT_PSIZ;
+         output->ComponentOffset = 1;
+         break;
+      case VARYING_SLOT_VIEWPORT:
+         assert(output->NumComponents == 1);
+         output->OutputRegister = VARYING_SLOT_PSIZ;
+         output->ComponentOffset = 2;
+         break;
+      case VARYING_SLOT_PSIZ:
+         assert(output->NumComponents == 1);
+         output->ComponentOffset = 3;
+         break;
+      }
+   }
+}
+
 extern "C" GLboolean
 brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
 {
@@ -199,6 +233,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
       prog->ShadowSamplers = shader->shadow_samplers;
       _mesa_update_shader_textures_used(shProg, prog);
 
+      update_xfb_info(prog->sh.LinkedTransformFeedback);
+
       bool debug_enabled =
          (INTEL_DEBUG & intel_debug_flag_for_shader_stage(shader->Stage));
 
index 76d2ea887b191d3947bdb83e0927af501840757b..a2ed2e72710989b3966778d9fbb209132d35fef2 100644 (file)
@@ -3087,32 +3087,14 @@ genX(upload_3dstate_so_decl_list)(struct brw_context *brw,
       unsigned decl_buffer_slot = buffer;
       assert(stream_id < MAX_VERTEX_STREAMS);
 
-      /* gl_PointSize is stored in VARYING_SLOT_PSIZ.w
-       * gl_Layer is stored in VARYING_SLOT_PSIZ.y
-       * gl_ViewportIndex is stored in VARYING_SLOT_PSIZ.z
-       */
-      if (varying == VARYING_SLOT_PSIZ) {
-         assert(components == 1);
-         component_mask <<= 3;
-      } else if (varying == VARYING_SLOT_LAYER) {
-         assert(components == 1);
-         component_mask <<= 1;
-      } else if (varying == VARYING_SLOT_VIEWPORT) {
-         assert(components == 1);
-         component_mask <<= 2;
-      } else {
-         component_mask <<= linked_xfb_info->Outputs[i].ComponentOffset;
-      }
+      component_mask <<= linked_xfb_info->Outputs[i].ComponentOffset;
 
       buffer_mask[stream_id] |= 1 << buffer;
 
+      assert(vue_map->varying_to_slot[varying] >= 0);
+
       decl.OutputBufferSlot = decl_buffer_slot;
-      if (varying == VARYING_SLOT_LAYER || varying == VARYING_SLOT_VIEWPORT) {
-         decl.RegisterIndex = vue_map->varying_to_slot[VARYING_SLOT_PSIZ];
-      } else {
-         assert(vue_map->varying_to_slot[varying] >= 0);
-         decl.RegisterIndex = vue_map->varying_to_slot[varying];
-      }
+      decl.RegisterIndex = vue_map->varying_to_slot[varying];
       decl.ComponentMask = component_mask;
 
       /* Mesa doesn't store entries for gl_SkipComponents in the Outputs[]