nir: Add a flag to lower_io to force "sample" interpolation
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_tcs.cpp
index 8bd150ad1b43fcd84383a20de175244a7a92fe35..498fb7cfbcf18e86234420c77c42bc9ccc3e5cb8 100644 (file)
@@ -201,6 +201,7 @@ vec4_tcs_visitor::emit_input_urb_read(const dst_reg &dst,
 void
 vec4_tcs_visitor::emit_output_urb_read(const dst_reg &dst,
                                        unsigned base_offset,
+                                       unsigned first_component,
                                        const src_reg &indirect_offset)
 {
    vec4_instruction *inst;
@@ -216,6 +217,12 @@ vec4_tcs_visitor::emit_output_urb_read(const dst_reg &dst,
    read->offset = base_offset;
    read->mlen = 1;
    read->base_mrf = -1;
+
+   if (first_component) {
+      src_reg src = src_reg(dst);
+      src.swizzle = BRW_SWZ_COMP_INPUT(first_component);
+      emit(MOV(dst, src));
+   }
 }
 
 void
@@ -295,14 +302,15 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          case GL_QUADS: {
             /* DWords 3-2 (reversed); use offset 0 and WZYX swizzle. */
             dst_reg tmp(this, glsl_type::vec4_type);
-            emit_output_urb_read(tmp, 0, src_reg());
+            emit_output_urb_read(tmp, 0, 0, src_reg());
             emit(MOV(writemask(dst, WRITEMASK_XY),
                      swizzle(src_reg(tmp), BRW_SWIZZLE_WZYX)));
             break;
          }
          case GL_TRIANGLES:
             /* DWord 4; use offset 1 but normal swizzle/writemask. */
-            emit_output_urb_read(writemask(dst, WRITEMASK_X), 1, src_reg());
+            emit_output_urb_read(writemask(dst, WRITEMASK_X), 1, 0,
+                                 src_reg());
             break;
          case GL_ISOLINES:
             /* All channels are undefined. */
@@ -334,10 +342,11 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          }
 
          dst_reg tmp(this, glsl_type::vec4_type);
-         emit_output_urb_read(tmp, 1, src_reg());
+         emit_output_urb_read(tmp, 1, 0, src_reg());
          emit(MOV(dst, swizzle(src_reg(tmp), swiz)));
       } else {
-         emit_output_urb_read(dst, imm_offset, indirect_offset);
+         emit_output_urb_read(dst, imm_offset, nir_intrinsic_component(instr),
+                              indirect_offset);
       }
       break;
    }
@@ -406,6 +415,13 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          }
       }
 
+      unsigned first_component = nir_intrinsic_component(instr);
+      if (first_component) {
+         assert(swiz == BRW_SWIZZLE_XYZW);
+         swiz = BRW_SWZ_COMP_OUTPUT(first_component);
+         mask = mask << first_component;
+      }
+
       emit_urb_write(swizzle(value, swiz), mask,
                      imm_offset, indirect_offset);
       break;
@@ -435,7 +451,7 @@ brw_compile_tcs(const struct brw_compiler *compiler,
                 unsigned *final_assembly_size,
                 char **error_str)
 {
-   const struct brw_device_info *devinfo = compiler->devinfo;
+   const struct gen_device_info *devinfo = compiler->devinfo;
    struct brw_vue_prog_data *vue_prog_data = &prog_data->base;
    const bool is_scalar = compiler->scalar_stage[MESA_SHADER_TESS_CTRL];
 
@@ -455,6 +471,9 @@ brw_compile_tcs(const struct brw_compiler *compiler,
    nir = brw_nir_apply_sampler_key(nir, devinfo, &key->tex, is_scalar);
    brw_nir_lower_vue_inputs(nir, is_scalar, &input_vue_map);
    brw_nir_lower_tcs_outputs(nir, &vue_prog_data->vue_map);
+   if (key->quads_workaround)
+      brw_nir_apply_tcs_quads_workaround(nir);
+
    nir = brw_postprocess_nir(nir, compiler->devinfo, is_scalar);
 
    if (is_scalar)