i965: Use force_compat_profile driconf option
[mesa.git] / src / mesa / drivers / dri / i965 / brw_sf.c
index 5acbf189969059adfc514e6d469da020d58cacde..f4073fa6cffd81550bc444feb9c776e69ab6c525 100644 (file)
   *   Keith Whitwell <keithw@vmware.com>
   */
 
-
+#include "compiler/nir/nir.h"
 #include "main/macros.h"
 #include "main/mtypes.h"
 #include "main/enums.h"
 #include "main/fbobject.h"
+#include "main/state.h"
 
 #include "intel_batchbuffer.h"
 
 #include "brw_defines.h"
 #include "brw_context.h"
-#include "brw_eu.h"
 #include "brw_util.h"
-#include "brw_sf.h"
 #include "brw_state.h"
+#include "compiler/brw_eu.h"
 
 #include "util/ralloc.h"
 
 static void compile_sf_prog( struct brw_context *brw,
                             struct brw_sf_prog_key *key )
 {
-   struct brw_sf_compile c;
-   const GLuint *program;
+   const unsigned *program;
    void *mem_ctx;
-   GLuint program_size;
-
-   memset(&c, 0, sizeof(c));
+   unsigned program_size;
 
    mem_ctx = ralloc_context(NULL);
-   /* Begin the compilation:
-    */
-   brw_init_codegen(brw->intelScreen->devinfo, &c.func, mem_ctx);
-
-   c.key = *key;
-   c.vue_map = brw->vue_map_geom_out;
-   if (c.key.do_point_coord) {
-      /*
-       * gl_PointCoord is a FS instead of VS builtin variable, thus it's
-       * not included in c.vue_map generated in VS stage. Here we add
-       * it manually to let SF shader generate the needed interpolation
-       * coefficient for FS shader.
-       */
-      c.vue_map.varying_to_slot[BRW_VARYING_SLOT_PNTC] = c.vue_map.num_slots;
-      c.vue_map.slot_to_varying[c.vue_map.num_slots++] = BRW_VARYING_SLOT_PNTC;
-   }
-   c.urb_entry_read_offset = BRW_SF_URB_ENTRY_READ_OFFSET;
-   c.nr_attr_regs = (c.vue_map.num_slots + 1)/2 - c.urb_entry_read_offset;
-   c.nr_setup_regs = c.nr_attr_regs;
-
-   c.prog_data.urb_read_length = c.nr_attr_regs;
-   c.prog_data.urb_entry_size = c.nr_setup_regs * 2;
-   c.has_flat_shading = brw_any_flat_varyings(&key->interpolation_mode);
 
-   /* Which primitive?  Or all three?
-    */
-   switch (key->primitive) {
-   case SF_TRIANGLES:
-      c.nr_verts = 3;
-      brw_emit_tri_setup( &c, true );
-      break;
-   case SF_LINES:
-      c.nr_verts = 2;
-      brw_emit_line_setup( &c, true );
-      break;
-   case SF_POINTS:
-      c.nr_verts = 1;
-      if (key->do_point_sprite)
-         brw_emit_point_sprite_setup( &c, true );
-      else
-         brw_emit_point_setup( &c, true );
-      break;
-   case SF_UNFILLED_TRIS:
-      c.nr_verts = 3;
-      brw_emit_anyprim_setup( &c );
-      break;
-   default:
-      unreachable("not reached");
-   }
-
-   /* FINISHME: SF programs use calculated jumps (i.e., JMPI with a register
-    * source). Compacting would be difficult.
-    */
-   /* brw_compact_instructions(&c.func, 0, 0, NULL); */
-
-   /* get the program
-    */
-   program = brw_get_program(&c.func, &program_size);
-
-   if (unlikely(INTEL_DEBUG & DEBUG_SF)) {
-      fprintf(stderr, "sf:\n");
-      brw_disassemble(brw->intelScreen->devinfo,
-                      c.func.store, 0, program_size, stderr);
-      fprintf(stderr, "\n");
-   }
+   struct brw_sf_prog_data prog_data;
+   program = brw_compile_sf(brw->screen->compiler, mem_ctx, key, &prog_data,
+                            &brw->vue_map_geom_out, &program_size);
 
    brw_upload_cache(&brw->cache, BRW_CACHE_SF_PROG,
-                   &c.key, sizeof(c.key),
+                   key, sizeof(*key),
                    program, program_size,
-                   &c.prog_data, sizeof(c.prog_data),
+                   &prog_data, sizeof(prog_data),
                    &brw->sf.prog_offset, &brw->sf.prog_data);
    ralloc_free(mem_ctx);
 }
 
 /* Calculate interpolants for triangle and line rasterization.
  */
-static void
+void
 brw_upload_sf_prog(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
    struct brw_sf_prog_key key;
+
+   if (!brw_state_dirty(brw,
+                        _NEW_BUFFERS |
+                        _NEW_HINT |
+                        _NEW_LIGHT |
+                        _NEW_POINT |
+                        _NEW_POLYGON |
+                        _NEW_PROGRAM |
+                        _NEW_TRANSFORM,
+                        BRW_NEW_BLORP |
+                        BRW_NEW_FS_PROG_DATA |
+                        BRW_NEW_REDUCED_PRIMITIVE |
+                        BRW_NEW_VUE_MAP_GEOM_OUT))
+      return;
+
    /* _NEW_BUFFERS */
-   bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+   bool flip_y = ctx->DrawBuffer->FlipY;
 
    memset(&key, 0, sizeof(key));
 
@@ -157,15 +108,15 @@ brw_upload_sf_prog(struct brw_context *brw)
        * program.
        */
       if (key.attrs & BITFIELD64_BIT(VARYING_SLOT_EDGE))
-        key.primitive = SF_UNFILLED_TRIS;
+        key.primitive = BRW_SF_PRIM_UNFILLED_TRIS;
       else
-        key.primitive = SF_TRIANGLES;
+        key.primitive = BRW_SF_PRIM_TRIANGLES;
       break;
    case GL_LINES:
-      key.primitive = SF_LINES;
+      key.primitive = BRW_SF_PRIM_LINES;
       break;
    case GL_POINTS:
-      key.primitive = SF_POINTS;
+      key.primitive = BRW_SF_PRIM_POINTS;
       break;
    }
 
@@ -175,28 +126,34 @@ brw_upload_sf_prog(struct brw_context *brw)
    /* _NEW_POINT */
    key.do_point_sprite = ctx->Point.PointSprite;
    if (key.do_point_sprite) {
-      int i;
-
-      for (i = 0; i < 8; i++) {
-        if (ctx->Point.CoordReplace[i])
-           key.point_sprite_coord_replace |= (1 << i);
-      }
+      key.point_sprite_coord_replace = ctx->Point.CoordReplace & 0xff;
    }
-   if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(VARYING_SLOT_PNTC))
+   if (brw->programs[MESA_SHADER_FRAGMENT]->info.inputs_read &
+       BITFIELD64_BIT(VARYING_SLOT_PNTC)) {
       key.do_point_coord = 1;
+   }
+
    /*
     * Window coordinates in a FBO are inverted, which means point
     * sprite origin must be inverted, too.
     */
-   if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
+   if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) == flip_y)
       key.sprite_origin_lower_left = true;
 
-   /* BRW_NEW_INTERPOLATION_MAP */
-   key.interpolation_mode = brw->interpolation_mode;
+   /* BRW_NEW_FS_PROG_DATA */
+   const struct brw_wm_prog_data *wm_prog_data =
+      brw_wm_prog_data(brw->wm.base.prog_data);
+   if (wm_prog_data) {
+      key.contains_flat_varying = wm_prog_data->contains_flat_varying;
+
+      STATIC_ASSERT(sizeof(key.interp_mode) ==
+                    sizeof(wm_prog_data->interp_mode));
+      memcpy(key.interp_mode, wm_prog_data->interp_mode,
+             sizeof(key.interp_mode));
+   }
 
    /* _NEW_LIGHT | _NEW_PROGRAM */
-   key.do_twoside_color = ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||
-                           ctx->VertexProgram._TwoSideEnabled);
+   key.do_twoside_color = _mesa_vertex_program_two_side_enabled(ctx);
 
    /* _NEW_POLYGON */
    if (key.do_twoside_color) {
@@ -204,30 +161,11 @@ brw_upload_sf_prog(struct brw_context *brw)
        * face orientation, just as we invert the viewport in
        * sf_unit_create_from_key().
        */
-      key.frontface_ccw = ctx->Polygon._FrontBit == render_to_fbo;
+      key.frontface_ccw = brw->polygon_front_bit != flip_y;
    }
 
-   if (!brw_search_cache(&brw->cache, BRW_CACHE_SF_PROG,
-                        &key, sizeof(key),
-                        &brw->sf.prog_offset, &brw->sf.prog_data)) {
+   if (!brw_search_cache(&brw->cache, BRW_CACHE_SF_PROG, &key, sizeof(key),
+                         &brw->sf.prog_offset, &brw->sf.prog_data, true)) {
       compile_sf_prog( brw, &key );
    }
 }
-
-
-const struct brw_tracked_state brw_sf_prog = {
-   .dirty = {
-      .mesa  = _NEW_BUFFERS |
-               _NEW_HINT |
-               _NEW_LIGHT |
-               _NEW_POINT |
-               _NEW_POLYGON |
-               _NEW_PROGRAM |
-               _NEW_TRANSFORM,
-      .brw   = BRW_NEW_INTERPOLATION_MAP |
-               BRW_NEW_REDUCED_PRIMITIVE |
-               BRW_NEW_VUE_MAP_GEOM_OUT,
-   },
-   .emit = brw_upload_sf_prog
-};
-