/*
Copyright (C) Intel Corp. 2006. All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ Intel funded Tungsten Graphics to
develop this 3D driver.
Permission is hereby granted, free of charge, to any person obtaining
**********************************************************************/
/*
* Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Keith Whitwell <keithw@vmware.com>
*/
#include <pthread.h>
#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
uint64_t *written, uint64_t *reset)
{
enum shader_time_shader_type type = brw->shader_time.types[i];
- assert(type == ST_VS || type == ST_FS8 || type == ST_FS16);
+ assert(type == ST_VS || type == ST_GS || type == ST_FS8 || type == ST_FS16);
/* Find where we recorded written and reset. */
int wi, ri;
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
switch (type) {
case ST_VS_WRITTEN:
case ST_VS_RESET:
+ case ST_GS_WRITTEN:
+ case ST_GS_RESET:
case ST_FS8_WRITTEN:
case ST_FS8_RESET:
case ST_FS16_WRITTEN:
continue;
case ST_VS:
+ case ST_GS:
case ST_FS8:
case ST_FS16:
get_written_and_reset(brw, i, &written, &reset);
switch (type) {
case ST_VS:
+ case ST_GS:
case ST_FS8:
case ST_FS16:
total_by_type[type] += scaled[i];
}
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";
case ST_VS:
stage = "vs";
break;
+ case ST_GS:
+ stage = "gs";
+ break;
case ST_FS8:
stage = "fs8";
break;
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);
print_shader_time_line("total", "fs16", -1, total_by_type[ST_FS16], 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);
+ }
+}