#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)
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 )
}
}
+ case GL_COMPUTE_PROGRAM_NV: {
+ struct brw_compute_program *prog = CALLOC_STRUCT(brw_compute_program);
+ if (prog) {
+ prog->id = get_new_program_id(brw->intelScreen);
+
+ return _mesa_init_compute_program(ctx, &prog->program, target, id);
+ } else {
+ return NULL;
+ }
+ }
+
default:
- assert(!"Unsupported target in brwNewProgram()");
- return NULL;
+ unreachable("Unsupported target in brwNewProgram()");
}
}
}
-static GLboolean
-brwIsProgramNative(struct gl_context *ctx,
- GLenum target,
- struct gl_program *prog)
-{
- return true;
-}
-
static GLboolean
brwProgramStringNotify(struct gl_context *ctx,
GLenum target,
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: {
/* Also tell tnl about it:
*/
_tnl_program_string(ctx, target, prog);
+
+ brw_add_texrect_params(prog);
+
+ brw_vs_precompile(ctx, NULL, prog);
break;
}
default:
* 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)
{
{
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
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
}
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";
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);
drm_intel_bo_unreference(brw->shader_time.bo);
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)
+{
+ /* Compare all the struct up to the pointers. */
+ if (memcmp(a, b, offsetof(struct brw_stage_prog_data, param)))
+ return false;
+
+ if (memcmp(a->param, b->param, a->nr_params * sizeof(void *)))
+ return false;
+
+ if (memcmp(a->pull_param, b->pull_param, a->nr_pull_params * sizeof(void *)))
+ return false;
+
+ return true;
+}
+
+void
+brw_stage_prog_data_free(const void *p)
+{
+ struct brw_stage_prog_data *prog_data = (struct brw_stage_prog_data *)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);
+ }
+}