X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_wm.c;h=b590b177ece0a60cce123eb95b37374ba4a30c72;hb=5c0436dbf87fef76ba67456f215d9285c38f1816;hp=dfd008ee416d0c95f978fb01cab1c58db23e7482;hpb=8b994d0f3bb4249fc33a9fe1a6fcad1755fbba20;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index dfd008ee416..b590b177ece 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -36,11 +36,12 @@ #include "main/formats.h" #include "main/fbobject.h" #include "main/samplerobj.h" +#include "main/framebuffer.h" #include "program/prog_parameter.h" #include "program/program.h" #include "intel_mipmap_tree.h" -#include "glsl/ralloc.h" +#include "util/ralloc.h" /** * Return a bitfield where bit n is set if barycentric interpolation mode n @@ -116,6 +117,25 @@ brw_compute_barycentric_interp_modes(struct brw_context *brw, return barycentric_interp_modes; } +static uint8_t +computed_depth_mode(struct gl_fragment_program *fp) +{ + if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) { + switch (fp->FragDepthLayout) { + case FRAG_DEPTH_LAYOUT_NONE: + case FRAG_DEPTH_LAYOUT_ANY: + return BRW_PSCDEPTH_ON; + case FRAG_DEPTH_LAYOUT_GREATER: + return BRW_PSCDEPTH_ON_GE; + case FRAG_DEPTH_LAYOUT_LESS: + return BRW_PSCDEPTH_ON_LE; + case FRAG_DEPTH_LAYOUT_UNCHANGED: + return BRW_PSCDEPTH_OFF; + } + } + return BRW_PSCDEPTH_OFF; +} + bool brw_wm_prog_data_compare(const void *in_a, const void *in_b) { @@ -140,14 +160,15 @@ brw_wm_prog_data_compare(const void *in_a, const void *in_b) * Depending on the instructions used (i.e. flow control instructions) * we'll use one of two code generators. */ -bool do_wm_prog(struct brw_context *brw, - struct gl_shader_program *prog, - struct brw_fragment_program *fp, - struct brw_wm_prog_key *key) +bool +brw_codegen_wm_prog(struct brw_context *brw, + struct gl_shader_program *prog, + struct brw_fragment_program *fp, + struct brw_wm_prog_key *key) { struct gl_context *ctx = &brw->ctx; void *mem_ctx = ralloc_context(NULL); - struct brw_wm_compile *c; + struct brw_wm_prog_data prog_data; const GLuint *program; struct gl_shader *fs = NULL; GLuint program_size; @@ -155,7 +176,18 @@ bool do_wm_prog(struct brw_context *brw, if (prog) fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; - c = rzalloc(mem_ctx, struct brw_wm_compile); + memset(&prog_data, 0, sizeof(prog_data)); + /* key->alpha_test_func means simulating alpha testing via discards, + * so the shader definitely kills pixels. + */ + prog_data.uses_kill = fp->program.UsesKill || key->alpha_test_func; + prog_data.uses_omask = + fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK); + prog_data.computed_depth_mode = computed_depth_mode(&fp->program); + + /* Use ALT floating point mode for ARB programs so that 0^0 == 1. */ + if (!prog) + prog_data.base.use_alt_mode = true; /* Allocate the references to the uniforms that will end up in the * prog_data associated with the compiled program, and which will be freed @@ -169,35 +201,36 @@ bool do_wm_prog(struct brw_context *brw, } /* The backend also sometimes adds params for texture size. */ param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; - c->prog_data.base.param = rzalloc_array(NULL, const float *, param_count); - c->prog_data.base.pull_param = - rzalloc_array(NULL, const float *, param_count); - c->prog_data.base.nr_params = param_count; + prog_data.base.param = + rzalloc_array(NULL, const gl_constant_value *, param_count); + prog_data.base.pull_param = + rzalloc_array(NULL, const gl_constant_value *, param_count); + prog_data.base.nr_params = param_count; - c->prog_data.barycentric_interp_modes = + prog_data.barycentric_interp_modes = brw_compute_barycentric_interp_modes(brw, key->flat_shade, key->persample_shading, &fp->program); - program = brw_wm_fs_emit(brw, mem_ctx, key, &c->prog_data, + program = brw_wm_fs_emit(brw, mem_ctx, key, &prog_data, &fp->program, prog, &program_size); if (program == NULL) { ralloc_free(mem_ctx); return false; } - if (c->prog_data.total_scratch) { + if (prog_data.base.total_scratch) { brw_get_scratch_bo(brw, &brw->wm.base.scratch_bo, - c->prog_data.total_scratch * brw->max_wm_threads); + prog_data.base.total_scratch * brw->max_wm_threads); } if (unlikely(INTEL_DEBUG & DEBUG_WM)) fprintf(stderr, "\n"); - brw_upload_cache(&brw->cache, BRW_WM_PROG, + brw_upload_cache(&brw->cache, BRW_CACHE_FS_PROG, key, sizeof(struct brw_wm_prog_key), program, program_size, - &c->prog_data, sizeof(c->prog_data), + &prog_data, sizeof(prog_data), &brw->wm.base.prog_offset, &brw->wm.prog_data); ralloc_free(mem_ctx); @@ -235,6 +268,14 @@ brw_debug_recompile_sampler_key(struct brw_context *brw, old_key->gl_clamp_mask[2], key->gl_clamp_mask[2]); found |= key_debug(brw, "gather channel quirk on any texture unit", old_key->gather_channel_quirk_mask, key->gather_channel_quirk_mask); + found |= key_debug(brw, "compressed multisample layout", + old_key->compressed_multisample_layout_mask, + key->compressed_multisample_layout_mask); + + for (unsigned int i = 0; i < MAX_SAMPLERS; i++) { + found |= key_debug(brw, "textureGather workarounds", + old_key->gen6_gather_wa[i], key->gen6_gather_wa[i]); + } return found; } @@ -252,7 +293,7 @@ brw_wm_debug_recompile(struct brw_context *brw, for (unsigned int i = 0; i < brw->cache.size; i++) { for (c = brw->cache.items[i]; c; c = c->next) { - if (c->cache_id == BRW_WM_PROG) { + if (c->cache_id == BRW_CACHE_FS_PROG) { old_key = c->key; if (old_key->program_string_id == key->program_string_id) @@ -275,6 +316,10 @@ brw_wm_debug_recompile(struct brw_context *brw, old_key->stats_wm, key->stats_wm); found |= key_debug(brw, "flat shading", old_key->flat_shade, key->flat_shade); + found |= key_debug(brw, "per-sample shading", + old_key->persample_shading, key->persample_shading); + found |= key_debug(brw, "per-sample shading and 2x MSAA", + old_key->persample_2x, key->persample_2x); found |= key_debug(brw, "number of color buffers", old_key->nr_color_regions, key->nr_color_regions); found |= key_debug(brw, "MRT alpha test or alpha-to-coverage", @@ -347,7 +392,8 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx, if (alpha_depth || (brw->gen < 8 && !brw->is_haswell)) key->swizzles[s] = brw_get_texture_swizzle(ctx, t); - if (sampler->MinFilter != GL_NEAREST && + if (brw->gen < 8 && + sampler->MinFilter != GL_NEAREST && sampler->MagFilter != GL_NEAREST) { if (sampler->WrapS == GL_CLAMP) key->gl_clamp_mask[0] |= 1 << s; @@ -386,6 +432,27 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx, } } +static bool +brw_wm_state_dirty (struct brw_context *brw) +{ + return brw_state_dirty(brw, + _NEW_BUFFERS | + _NEW_COLOR | + _NEW_DEPTH | + _NEW_FRAG_CLAMP | + _NEW_HINT | + _NEW_LIGHT | + _NEW_LINE | + _NEW_MULTISAMPLE | + _NEW_POLYGON | + _NEW_STENCIL | + _NEW_TEXTURE, + BRW_NEW_FRAGMENT_PROGRAM | + BRW_NEW_REDUCED_PRIMITIVE | + BRW_NEW_STATS_WM | + BRW_NEW_VUE_MAP_GEOM_OUT); +} + static void brw_wm_populate_key( struct brw_context *brw, struct brw_wm_prog_key *key ) { @@ -397,7 +464,7 @@ static void brw_wm_populate_key( struct brw_context *brw, GLuint lookup = 0; GLuint line_aa; bool program_uses_dfdy = fp->program.UsesDFdy; - bool multisample_fbo = ctx->DrawBuffer->Visual.samples > 1; + const bool multisample_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1; memset(key, 0, sizeof(*key)); @@ -458,13 +525,8 @@ static void brw_wm_populate_key( struct brw_context *brw, key->line_aa = line_aa; /* _NEW_HINT */ - if (brw->disable_derivative_optimization) { - key->high_quality_derivatives = - ctx->Hint.FragmentShaderDerivative != GL_FASTEST; - } else { - key->high_quality_derivatives = - ctx->Hint.FragmentShaderDerivative == GL_NICEST; - } + key->high_quality_derivatives = + ctx->Hint.FragmentShaderDerivative == GL_NICEST; if (brw->gen < 6) key->stats_wm = brw->stats_wm; @@ -501,7 +563,7 @@ static void brw_wm_populate_key( struct brw_context *brw, * drawable height in order to invert the Y axis. */ if (fp->program.Base.InputsRead & VARYING_BIT_POS) { - key->drawable_height = ctx->DrawBuffer->Height; + key->drawable_height = _mesa_geometric_height(ctx->DrawBuffer); } if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) { @@ -519,6 +581,8 @@ static void brw_wm_populate_key( struct brw_context *brw, /* Ignore sample qualifier while computing this flag. */ key->persample_shading = _mesa_get_min_invocations_per_fragment(ctx, &fp->program, true) > 1; + if (key->persample_shading) + key->persample_2x = _mesa_geometric_samples(ctx->DrawBuffer) == 2; key->compute_pos_offset = _mesa_get_min_invocations_per_fragment(ctx, &fp->program, false) > 1 && @@ -550,47 +614,26 @@ static void brw_wm_populate_key( struct brw_context *brw, key->program_string_id = fp->id; } - -static void +void brw_upload_wm_prog(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; + struct gl_shader_program *current = ctx->_Shader->_CurrentFragmentProgram; struct brw_wm_prog_key key; struct brw_fragment_program *fp = (struct brw_fragment_program *) brw->fragment_program; + if (!brw_wm_state_dirty(brw)) + return; + brw_wm_populate_key(brw, &key); - if (!brw_search_cache(&brw->cache, BRW_WM_PROG, + if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG, &key, sizeof(key), &brw->wm.base.prog_offset, &brw->wm.prog_data)) { - bool success = do_wm_prog(brw, ctx->_Shader->_CurrentFragmentProgram, fp, - &key); + bool success = brw_codegen_wm_prog(brw, current, fp, &key); (void) success; assert(success); } brw->wm.base.prog_data = &brw->wm.prog_data->base; } - - -const struct brw_tracked_state brw_wm_prog = { - .dirty = { - .mesa = (_NEW_COLOR | - _NEW_DEPTH | - _NEW_STENCIL | - _NEW_POLYGON | - _NEW_LINE | - _NEW_HINT | - _NEW_LIGHT | - _NEW_FRAG_CLAMP | - _NEW_BUFFERS | - _NEW_TEXTURE | - _NEW_MULTISAMPLE), - .brw = (BRW_NEW_FRAGMENT_PROGRAM | - BRW_NEW_REDUCED_PRIMITIVE | - BRW_NEW_VUE_MAP_GEOM_OUT | - BRW_NEW_STATS_WM) - }, - .emit = brw_upload_wm_prog -}; -