i965/skl: Send a message header when doing constant loads SIMD4x2
[mesa.git] / src / mesa / drivers / dri / i965 / brw_program.c
index f69c3129c011e246c40472a74cba9039bab56e72..70b5a6289e22b50cd07c4dcc76ddac3b9ea1c4c5 100644 (file)
 #include "main/enums.h"
 #include "main/shaderobj.h"
 #include "program/prog_parameter.h"
+#include "program/prog_print.h"
 #include "program/program.h"
 #include "program/programopt.h"
 #include "tnl/tnl.h"
-#include "glsl/ralloc.h"
+#include "util/ralloc.h"
+#include "glsl/ir.h"
 
 #include "brw_context.h"
+#include "brw_shader.h"
 #include "brw_wm.h"
+#include "intel_batchbuffer.h"
 
 static unsigned
 get_new_program_id(struct intel_screen *screen)
@@ -52,25 +56,6 @@ get_new_program_id(struct intel_screen *screen)
    return id;
 }
 
-static void brwBindProgram( struct gl_context *ctx,
-                           GLenum target,
-                           struct gl_program *prog )
-{
-   struct brw_context *brw = brw_context(ctx);
-
-   switch (target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
-      break;
-   case MESA_GEOMETRY_PROGRAM:
-      brw->state.dirty.brw |= BRW_NEW_GEOMETRY_PROGRAM;
-      break;
-   case GL_FRAGMENT_PROGRAM_ARB:
-      brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
-      break;
-   }
-}
-
 static struct gl_program *brwNewProgram( struct gl_context *ctx,
                                      GLenum target,
                                      GLuint id )
@@ -125,8 +110,7 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx,
    }
 
    default:
-      assert(!"Unsupported target in brwNewProgram()");
-      return NULL;
+      unreachable("Unsupported target in brwNewProgram()");
    }
 }
 
@@ -137,14 +121,6 @@ static void brwDeleteProgram( struct gl_context *ctx,
 }
 
 
-static GLboolean
-brwIsProgramNative(struct gl_context *ctx,
-                  GLenum target,
-                  struct gl_program *prog)
-{
-   return true;
-}
-
 static GLboolean
 brwProgramStringNotify(struct gl_context *ctx,
                       GLenum target,
@@ -162,6 +138,10 @@ brwProgramStringNotify(struct gl_context *ctx,
       if (newFP == curFP)
         brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
       newFP->id = get_new_program_id(brw->intelScreen);
+
+      brw_add_texrect_params(prog);
+
+      brw_fs_precompile(ctx, NULL, prog);
       break;
    }
    case GL_VERTEX_PROGRAM_ARB: {
@@ -180,6 +160,10 @@ brwProgramStringNotify(struct gl_context *ctx,
       /* Also tell tnl about it:
        */
       _tnl_program_string(ctx, target, prog);
+
+      brw_add_texrect_params(prog);
+
+      brw_vs_precompile(ctx, NULL, prog);
       break;
    }
    default:
@@ -190,15 +174,49 @@ brwProgramStringNotify(struct gl_context *ctx,
        * this function should only ever be called with a target of
        * GL_VERTEX_PROGRAM_ARB or GL_FRAGMENT_PROGRAM_ARB.
        */
-      assert(!"Unexpected target in brwProgramStringNotify");
-      break;
+      unreachable("Unexpected target in brwProgramStringNotify");
    }
 
-   brw_add_texrect_params(prog);
-
    return true;
 }
 
+static void
+brw_memory_barrier(struct gl_context *ctx, GLbitfield barriers)
+{
+   struct brw_context *brw = brw_context(ctx);
+   unsigned bits = (PIPE_CONTROL_DATA_CACHE_INVALIDATE |
+                    PIPE_CONTROL_NO_WRITE |
+                    PIPE_CONTROL_CS_STALL);
+   assert(brw->gen >= 7 && brw->gen <= 8);
+
+   if (barriers & (GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT |
+                   GL_ELEMENT_ARRAY_BARRIER_BIT |
+                   GL_COMMAND_BARRIER_BIT))
+      bits |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+
+   if (barriers & GL_UNIFORM_BARRIER_BIT)
+      bits |= (PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
+               PIPE_CONTROL_CONST_CACHE_INVALIDATE);
+
+   if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT)
+      bits |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+
+   if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT)
+      bits |= PIPE_CONTROL_RENDER_TARGET_FLUSH;
+
+   if (barriers & GL_FRAMEBUFFER_BARRIER_BIT)
+      bits |= (PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+               PIPE_CONTROL_RENDER_TARGET_FLUSH);
+
+   /* Typed surface messages are handled by the render cache on IVB, so we
+    * need to flush it too.
+    */
+   if (brw->gen == 7 && !brw->is_haswell)
+      bits |= PIPE_CONTROL_RENDER_TARGET_FLUSH;
+
+   brw_emit_pipe_control_flush(brw, bits);
+}
+
 void
 brw_add_texrect_params(struct gl_program *prog)
 {
@@ -250,15 +268,14 @@ void brwInitFragProgFuncs( struct dd_function_table *functions )
 {
    assert(functions->ProgramStringNotify == _tnl_program_string);
 
-   functions->BindProgram = brwBindProgram;
    functions->NewProgram = brwNewProgram;
    functions->DeleteProgram = brwDeleteProgram;
-   functions->IsProgramNative = brwIsProgramNative;
    functions->ProgramStringNotify = brwProgramStringNotify;
 
    functions->NewShader = brw_new_shader;
-   functions->NewShaderProgram = brw_new_shader_program;
    functions->LinkShader = brw_link_shader;
+
+   functions->MemoryBarrier = brw_memory_barrier;
 }
 
 void
@@ -318,17 +335,17 @@ static void
 print_shader_time_line(const char *stage, const char *name,
                        int shader_num, uint64_t time, uint64_t total)
 {
-   printf("%-6s%-6s", stage, name);
+   fprintf(stderr, "%-6s%-18s", stage, name);
 
    if (shader_num != -1)
-      printf("%4d: ", shader_num);
+      fprintf(stderr, "%4d: ", shader_num);
    else
-      printf("    : ");
+      fprintf(stderr, "    : ");
 
-   printf("%16lld (%7.2f Gcycles)      %4.1f%%\n",
-          (long long)time,
-          (double)time / 1000000000.0,
-          (double)time / total * 100.0);
+   fprintf(stderr, "%16lld (%7.2f Gcycles)      %4.1f%%\n",
+           (long long)time,
+           (double)time / 1000000000.0,
+           (double)time / total * 100.0);
 }
 
 static void
@@ -399,31 +416,34 @@ brw_report_shader_time(struct brw_context *brw)
    }
 
    if (total == 0) {
-      printf("No shader time collected yet\n");
+      fprintf(stderr, "No shader time collected yet\n");
       return;
    }
 
    qsort(sorted, brw->shader_time.num_entries, sizeof(sorted[0]), compare_time);
 
-   printf("\n");
-   printf("type          ID      cycles spent                   %% of total\n");
+   fprintf(stderr, "\n");
+   fprintf(stderr, "type          ID                  cycles spent                   %% of total\n");
    for (int s = 0; s < brw->shader_time.num_entries; s++) {
       const char *shader_name;
       const char *stage;
       /* Work back from the sorted pointers times to a time to print. */
       int i = sorted[s] - scaled;
+      struct gl_shader_program *prog = brw->shader_time.shader_programs[i];
 
       if (scaled[i] == 0)
          continue;
 
       int shader_num = -1;
-      if (brw->shader_time.shader_programs[i]) {
-         shader_num = brw->shader_time.shader_programs[i]->Name;
+      if (prog) {
+         shader_num = prog->Name;
 
          /* The fixed function fragment shader generates GLSL IR with a Name
           * of 0, and nothing else does.
           */
-         if (shader_num == 0 &&
+         if (prog->Label) {
+            shader_name = prog->Label;
+         } else if (shader_num == 0 &&
              (brw->shader_time.types[i] == ST_FS8 ||
               brw->shader_time.types[i] == ST_FS16)) {
             shader_name = "ff";
@@ -465,7 +485,7 @@ brw_report_shader_time(struct brw_context *brw)
                              scaled[i], total);
    }
 
-   printf("\n");
+   fprintf(stderr, "\n");
    print_shader_time_line("total", "vs", -1, total_by_type[ST_VS], total);
    print_shader_time_line("total", "gs", -1, total_by_type[ST_GS], total);
    print_shader_time_line("total", "fs8", -1, total_by_type[ST_FS8], total);
@@ -545,6 +565,16 @@ brw_destroy_shader_time(struct brw_context *brw)
    brw->shader_time.bo = NULL;
 }
 
+void
+brw_mark_surface_used(struct brw_stage_prog_data *prog_data,
+                      unsigned surf_index)
+{
+   assert(surf_index < BRW_MAX_SURFACES);
+
+   prog_data->binding_table.size_bytes =
+      MAX2(prog_data->binding_table.size_bytes, (surf_index + 1) * 4);
+}
+
 bool
 brw_stage_prog_data_compare(const struct brw_stage_prog_data *a,
                             const struct brw_stage_prog_data *b)
@@ -570,3 +600,19 @@ brw_stage_prog_data_free(const void *p)
    ralloc_free(prog_data->param);
    ralloc_free(prog_data->pull_param);
 }
+
+void
+brw_dump_ir(const char *stage, struct gl_shader_program *shader_prog,
+            struct gl_shader *shader, struct gl_program *prog)
+{
+   if (shader_prog) {
+      fprintf(stderr,
+              "GLSL IR for native %s shader %d:\n", stage, shader_prog->Name);
+      _mesa_print_ir(stderr, shader->ir, NULL);
+      fprintf(stderr, "\n\n");
+   } else {
+      fprintf(stderr, "ARB_%s_program %d ir for native %s shader\n",
+              stage, prog->Id, stage);
+      _mesa_print_program(prog);
+   }
+}