X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_program.c;h=22b0227756e6b71345b36af02505dc8fa0d121e5;hb=958fc04dc51a2561c8598f42df59e3d9139e56a7;hp=ed117dd5f0837315c255bb593b2c99d0df71a620;hpb=4939c2eced8834a448fea894785ba5bfdf1076fd;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index ed117dd5f08..22b0227756e 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -42,7 +42,10 @@ #include "glsl/ir.h" #include "brw_context.h" +#include "brw_shader.h" +#include "brw_nir.h" #include "brw_wm.h" +#include "intel_batchbuffer.h" static unsigned get_new_program_id(struct intel_screen *screen) @@ -66,8 +69,7 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx, if (prog) { prog->id = get_new_program_id(brw->intelScreen); - return _mesa_init_vertex_program( ctx, &prog->program, - target, id ); + return _mesa_init_gl_program(&prog->program.Base, target, id); } else return NULL; @@ -78,19 +80,18 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx, if (prog) { prog->id = get_new_program_id(brw->intelScreen); - return _mesa_init_fragment_program( ctx, &prog->program, - target, id ); + return _mesa_init_gl_program(&prog->program.Base, target, id); } else return NULL; } - case MESA_GEOMETRY_PROGRAM: { + case GL_GEOMETRY_PROGRAM_NV: { struct brw_geometry_program *prog = CALLOC_STRUCT(brw_geometry_program); if (prog) { prog->id = get_new_program_id(brw->intelScreen); - return _mesa_init_geometry_program(ctx, &prog->program, target, id); + return _mesa_init_gl_program(&prog->program, target, id); } else { return NULL; } @@ -101,7 +102,7 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx, if (prog) { prog->id = get_new_program_id(brw->intelScreen); - return _mesa_init_compute_program(ctx, &prog->program, target, id); + return _mesa_init_gl_program(&prog->program.Base, target, id); } else { return NULL; } @@ -134,8 +135,14 @@ brwProgramStringNotify(struct gl_context *ctx, brw_fragment_program_const(brw->fragment_program); if (newFP == curFP) - brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; + brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = get_new_program_id(brw->intelScreen); + + brw_add_texrect_params(prog); + + prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_FRAGMENT, true); + + brw_fs_precompile(ctx, NULL, prog); break; } case GL_VERTEX_PROGRAM_ARB: { @@ -145,7 +152,7 @@ brwProgramStringNotify(struct gl_context *ctx, brw_vertex_program_const(brw->vertex_program); if (newVP == curVP) - brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; + brw->ctx.NewDriverState |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.IsPositionInvariant) { _mesa_insert_mvp_code(ctx, &newVP->program); } @@ -154,6 +161,13 @@ brwProgramStringNotify(struct gl_context *ctx, /* Also tell tnl about it: */ _tnl_program_string(ctx, target, prog); + + brw_add_texrect_params(prog); + + prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_VERTEX, + brw->intelScreen->compiler->scalar_vs); + + brw_vs_precompile(ctx, NULL, prog); break; } default: @@ -167,11 +181,46 @@ brwProgramStringNotify(struct gl_context *ctx, 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 <= 9); + + 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) { @@ -191,18 +240,6 @@ brw_add_texrect_params(struct gl_program *prog) } } -/* Per-thread scratch space is a power-of-two multiple of 1KB. */ -int -brw_get_scratch_size(int size) -{ - int i; - - for (i = 1024; i < size; i *= 2) - ; - - return i; -} - void brw_get_scratch_bo(struct brw_context *brw, drm_intel_bo **scratch_bo, int size) @@ -221,7 +258,7 @@ brw_get_scratch_bo(struct brw_context *brw, void brwInitFragProgFuncs( struct dd_function_table *functions ) { - assert(functions->ProgramStringNotify == _tnl_program_string); + /* assert(functions->ProgramStringNotify == _tnl_program_string); */ functions->NewProgram = brwNewProgram; functions->DeleteProgram = brwDeleteProgram; @@ -229,22 +266,28 @@ void brwInitFragProgFuncs( struct dd_function_table *functions ) functions->NewShader = brw_new_shader; functions->LinkShader = brw_link_shader; + + functions->MemoryBarrier = brw_memory_barrier; } +struct shader_times { + uint64_t time; + uint64_t written; + uint64_t reset; +}; + void brw_init_shader_time(struct brw_context *brw) { - const int max_entries = 4096; - brw->shader_time.bo = drm_intel_bo_alloc(brw->bufmgr, "shader time", - max_entries * SHADER_TIME_STRIDE, - 4096); - brw->shader_time.shader_programs = rzalloc_array(brw, struct gl_shader_program *, - max_entries); - brw->shader_time.programs = rzalloc_array(brw, struct gl_program *, - max_entries); + const int max_entries = 2048; + brw->shader_time.bo = + drm_intel_bo_alloc(brw->bufmgr, "shader time", + max_entries * SHADER_TIME_STRIDE * 3, 4096); + brw->shader_time.names = rzalloc_array(brw, const char *, max_entries); + brw->shader_time.ids = rzalloc_array(brw, int, max_entries); brw->shader_time.types = rzalloc_array(brw, enum shader_time_shader_type, max_entries); - brw->shader_time.cumulative = rzalloc_array(brw, uint64_t, + brw->shader_time.cumulative = rzalloc_array(brw, struct shader_times, max_entries); brw->shader_time.max_entries = max_entries; } @@ -264,33 +307,13 @@ compare_time(const void *a, const void *b) return 1; } -static void -get_written_and_reset(struct brw_context *brw, int i, - uint64_t *written, uint64_t *reset) -{ - enum shader_time_shader_type type = brw->shader_time.types[i]; - assert(type == ST_VS || type == ST_GS || type == ST_FS8 || type == ST_FS16); - - /* Find where we recorded written and reset. */ - int wi, ri; - - for (wi = i; brw->shader_time.types[wi] != type + 1; wi++) - ; - - for (ri = i; brw->shader_time.types[ri] != type + 2; ri++) - ; - - *written = brw->shader_time.cumulative[wi]; - *reset = brw->shader_time.cumulative[ri]; -} - static void print_shader_time_line(const char *stage, const char *name, int shader_num, uint64_t time, uint64_t total) { fprintf(stderr, "%-6s%-18s", stage, name); - if (shader_num != -1) + if (shader_num != 0) fprintf(stderr, "%4d: ", shader_num); else fprintf(stderr, " : "); @@ -309,7 +332,7 @@ brw_report_shader_time(struct brw_context *brw) uint64_t scaled[brw->shader_time.num_entries]; uint64_t *sorted[brw->shader_time.num_entries]; - uint64_t total_by_type[ST_FS16 + 1]; + uint64_t total_by_type[ST_CS + 1]; memset(total_by_type, 0, sizeof(total_by_type)); double total = 0; for (int i = 0; i < brw->shader_time.num_entries; i++) { @@ -319,23 +342,13 @@ brw_report_shader_time(struct brw_context *brw) sorted[i] = &scaled[i]; 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: - case ST_FS16_RESET: - /* We'll handle these when along with the time. */ - scaled[i] = 0; - continue; - case ST_VS: case ST_GS: case ST_FS8: case ST_FS16: - get_written_and_reset(brw, i, &written, &reset); + case ST_CS: + written = brw->shader_time.cumulative[i].written; + reset = brw->shader_time.cumulative[i].reset; break; default: @@ -347,7 +360,7 @@ brw_report_shader_time(struct brw_context *brw) break; } - uint64_t time = brw->shader_time.cumulative[i]; + uint64_t time = brw->shader_time.cumulative[i].time; if (written) { scaled[i] = time / written * (written + reset); } else { @@ -359,6 +372,7 @@ brw_report_shader_time(struct brw_context *brw) case ST_GS: case ST_FS8: case ST_FS16: + case ST_CS: total_by_type[type] += scaled[i]; break; default: @@ -378,43 +392,15 @@ brw_report_shader_time(struct brw_context *brw) 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 (prog) { - shader_num = prog->Name; - - /* The fixed function fragment shader generates GLSL IR with a Name - * of 0, and nothing else does. - */ - 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"; - shader_num = -1; - } else { - shader_name = "glsl"; - } - } else if (brw->shader_time.programs[i]) { - shader_num = brw->shader_time.programs[i]->Id; - if (shader_num == 0) { - shader_name = "ff"; - shader_num = -1; - } else { - shader_name = "prog"; - } - } else { - shader_name = "other"; - } + int shader_num = brw->shader_time.ids[i]; + const char *shader_name = brw->shader_time.names[i]; switch (brw->shader_time.types[i]) { case ST_VS: @@ -429,6 +415,9 @@ brw_report_shader_time(struct brw_context *brw) case ST_FS16: stage = "fs16"; break; + case ST_CS: + stage = "cs"; + break; default: stage = "other"; break; @@ -439,10 +428,11 @@ brw_report_shader_time(struct brw_context *brw) } 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); + print_shader_time_line("total", "vs", 0, total_by_type[ST_VS], total); + print_shader_time_line("total", "gs", 0, total_by_type[ST_GS], total); + print_shader_time_line("total", "fs8", 0, total_by_type[ST_FS8], total); + print_shader_time_line("total", "fs16", 0, total_by_type[ST_FS16], total); + print_shader_time_line("total", "cs", 0, total_by_type[ST_CS], total); } static void @@ -456,16 +446,19 @@ brw_collect_shader_time(struct brw_context *brw) * overhead compared to the cost of tracking the time in the first place. */ drm_intel_bo_map(brw->shader_time.bo, true); - - uint32_t *times = brw->shader_time.bo->virtual; + void *bo_map = brw->shader_time.bo->virtual; for (int i = 0; i < brw->shader_time.num_entries; i++) { - brw->shader_time.cumulative[i] += times[i * SHADER_TIME_STRIDE / 4]; + uint32_t *times = bo_map + i * 3 * SHADER_TIME_STRIDE; + + brw->shader_time.cumulative[i].time += times[SHADER_TIME_STRIDE * 0 / 4]; + brw->shader_time.cumulative[i].written += times[SHADER_TIME_STRIDE * 1 / 4]; + brw->shader_time.cumulative[i].reset += times[SHADER_TIME_STRIDE * 2 / 4]; } /* Zero the BO out to clear it out for our next collection. */ - memset(times, 0, brw->shader_time.bo->size); + memset(bo_map, 0, brw->shader_time.bo->size); drm_intel_bo_unmap(brw->shader_time.bo); } @@ -494,19 +487,24 @@ brw_get_shader_time_index(struct brw_context *brw, struct gl_program *prog, enum shader_time_shader_type type) { - struct gl_context *ctx = &brw->ctx; - int shader_time_index = brw->shader_time.num_entries++; assert(shader_time_index < brw->shader_time.max_entries); brw->shader_time.types[shader_time_index] = type; - _mesa_reference_shader_program(ctx, - &brw->shader_time.shader_programs[shader_time_index], - shader_prog); + int id = shader_prog ? shader_prog->Name : prog->Id; + const char *name; + if (id == 0) { + name = "ff"; + } else if (!shader_prog) { + name = "prog"; + } else if (shader_prog->Label) { + name = ralloc_strdup(brw->shader_time.names, shader_prog->Label); + } else { + name = "glsl"; + } - _mesa_reference_program(ctx, - &brw->shader_time.programs[shader_time_index], - prog); + brw->shader_time.names[shader_time_index] = name; + brw->shader_time.ids[shader_time_index] = id; return shader_time_index; } @@ -518,33 +516,6 @@ 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) -{ - /* 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) { @@ -552,21 +523,43 @@ brw_stage_prog_data_free(const void *p) ralloc_free(prog_data->param); ralloc_free(prog_data->pull_param); + ralloc_free(prog_data->image_param); } void -brw_dump_ir(struct brw_context *brw, const char *stage, - struct gl_shader_program *shader_prog, +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"); + if (shader->ir) { + 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); } } + +void +brw_setup_tex_for_precompile(struct brw_context *brw, + struct brw_sampler_prog_key_data *tex, + struct gl_program *prog) +{ + const bool has_shader_channel_select = brw->is_haswell || brw->gen >= 8; + unsigned sampler_count = _mesa_fls(prog->SamplersUsed); + for (unsigned i = 0; i < sampler_count; i++) { + if (!has_shader_channel_select && (prog->ShadowSamplers & (1 << i))) { + /* Assume DEPTH_TEXTURE_MODE is the default: X, X, X, 1 */ + tex->swizzles[i] = + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE); + } else { + /* Color sampler: assume no swizzling. */ + tex->swizzles[i] = SWIZZLE_XYZW; + } + } +}