static void brw_wm_populate_key( struct brw_context *brw, struct brw_wm_prog_key *key ) { /* BRW_NEW_FRAGMENT_PROGRAM */ struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program; GLuint lookup = 0; GLuint line_aa; GLuint i; memset(key, 0, sizeof(*key)); /* Build the index for table lookup */ /* _NEW_COLOR */ if (fp->program.UsesKill || brw->attribs.Color->AlphaEnabled) lookup |= IZ_PS_KILL_ALPHATEST_BIT; if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPR)) lookup |= IZ_PS_COMPUTES_DEPTH_BIT; /* _NEW_DEPTH */ if (brw->attribs.Depth->Test) lookup |= IZ_DEPTH_TEST_ENABLE_BIT; if (brw->attribs.Depth->Test && brw->attribs.Depth->Mask) /* ?? */ lookup |= IZ_DEPTH_WRITE_ENABLE_BIT; /* _NEW_STENCIL */ if (brw->attribs.Stencil->Enabled) { lookup |= IZ_STENCIL_TEST_ENABLE_BIT; if (brw->attribs.Stencil->WriteMask[0] || (brw->attribs.Stencil->TestTwoSide && brw->attribs.Stencil->WriteMask[1])) lookup |= IZ_STENCIL_WRITE_ENABLE_BIT; } /* XXX: when should this be disabled? */ if (1) lookup |= IZ_EARLY_DEPTH_TEST_BIT; line_aa = AA_NEVER; /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */ if (brw->attribs.Line->SmoothFlag) { if (brw->intel.reduced_primitive == GL_LINES) { line_aa = AA_ALWAYS; } else if (brw->intel.reduced_primitive == GL_TRIANGLES) { if (brw->attribs.Polygon->FrontMode == GL_LINE) { line_aa = AA_SOMETIMES; if (brw->attribs.Polygon->BackMode == GL_LINE || (brw->attribs.Polygon->CullFlag && brw->attribs.Polygon->CullFaceMode == GL_BACK)) line_aa = AA_ALWAYS; } else if (brw->attribs.Polygon->BackMode == GL_LINE) { line_aa = AA_SOMETIMES; if ((brw->attribs.Polygon->CullFlag && brw->attribs.Polygon->CullFaceMode == GL_FRONT)) line_aa = AA_ALWAYS; } } } brw_wm_lookup_iz(line_aa, lookup, key); /* BRW_NEW_WM_INPUT_DIMENSIONS */ key->projtex_mask = brw->wm.input_size_masks[4-1]; /* _NEW_LIGHT */ key->flat_shade = (brw->attribs.Light->ShadeModel == GL_FLAT); /* _NEW_TEXTURE */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { const struct gl_texture_unit *unit = &brw->attribs.Texture->Unit[i]; const struct gl_texture_object *t = unit->_Current; if (unit->_ReallyEnabled) { if (t->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && t->Image[0][t->BaseLevel]->_BaseFormat == GL_DEPTH_COMPONENT) { key->shadowtex_mask |= 1<<i; } if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) key->yuvtex_mask |= 1<<i; } } /* Extra info: */ key->program_string_id = fp->id; }
void brw_wm_payload_setup(struct brw_context *brw, struct brw_wm_compile *c) { struct intel_context *intel = &brw->intel; bool uses_depth = (c->fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0; unsigned barycentric_interp_modes = c->prog_data.barycentric_interp_modes; int i; if (intel->gen >= 6) { /* R0-1: masks, pixel X/Y coordinates. */ c->nr_payload_regs = 2; /* R2: only for 32-pixel dispatch.*/ /* R3-26: barycentric interpolation coordinates. These appear in the * same order that they appear in the brw_wm_barycentric_interp_mode * enum. Each set of coordinates occupies 2 registers if dispatch width * == 8 and 4 registers if dispatch width == 16. Coordinates only * appear if they were enabled using the "Barycentric Interpolation * Mode" bits in WM_STATE. */ for (i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) { if (barycentric_interp_modes & (1 << i)) { c->barycentric_coord_reg[i] = c->nr_payload_regs; c->nr_payload_regs += 2; if (c->dispatch_width == 16) { c->nr_payload_regs += 2; } } } /* R27: interpolated depth if uses source depth */ if (uses_depth) { c->source_depth_reg = c->nr_payload_regs; c->nr_payload_regs++; if (c->dispatch_width == 16) { /* R28: interpolated depth if not 8-wide. */ c->nr_payload_regs++; } } /* R29: interpolated W set if GEN6_WM_USES_SOURCE_W. */ if (uses_depth) { c->source_w_reg = c->nr_payload_regs; c->nr_payload_regs++; if (c->dispatch_width == 16) { /* R30: interpolated W if not 8-wide. */ c->nr_payload_regs++; } } /* R31: MSAA position offsets. */ /* R32-: bary for 32-pixel. */ /* R58-59: interp W for 32-pixel. */ if (c->fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) { c->source_depth_to_render_target = true; c->computes_depth = true; } } else { brw_wm_lookup_iz(intel, c); } }
static void brw_wm_populate_key( struct brw_context *brw, struct brw_wm_prog_key *key ) { unsigned lookup, line_aa; unsigned i; memset(key, 0, sizeof(*key)); /* PIPE_NEW_FRAGMENT_SHADER * PIPE_NEW_DEPTH_STENCIL_ALPHA */ lookup = (brw->curr.zstencil->iz_lookup | brw->curr.fragment_shader->iz_lookup); /* PIPE_NEW_RAST * BRW_NEW_REDUCED_PRIMITIVE */ switch (brw->reduced_primitive) { case PIPE_PRIM_POINTS: line_aa = AA_NEVER; break; case PIPE_PRIM_LINES: line_aa = (brw->curr.rast->templ.line_smooth ? AA_ALWAYS : AA_NEVER); break; default: line_aa = brw->curr.rast->unfilled_aa_line; break; } brw_wm_lookup_iz(line_aa, lookup, brw->curr.fragment_shader->uses_depth, key); /* PIPE_NEW_RAST */ key->flat_shade = brw->curr.rast->templ.flatshade; /* PIPE_NEW_BOUND_TEXTURES */ for (i = 0; i < brw->curr.num_textures; i++) { const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); if (tex->base.format == PIPE_FORMAT_UYVY) key->yuvtex_mask |= 1 << i; if (tex->base.format == PIPE_FORMAT_YUYV) key->yuvtex_swap_mask |= 1 << i; /* XXX: shadow texture */ /* key->shadowtex_mask |= 1<<i; */ } /* CACHE_NEW_VS_PROG */ key->vp_nr_outputs = brw->vs.prog_data->nr_outputs; key->nr_cbufs = brw->curr.fb.nr_cbufs; key->nr_inputs = brw->curr.fragment_shader->info.num_inputs; /* The unique fragment program ID */ key->program_string_id = brw->curr.fragment_shader->id; }