X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_atom_shader.c;h=0bb229579263d1a57c5c2680a4544978407f8e8a;hb=53bc28920a8524d7bc795c3ce6398dc34a8e2152;hp=e22899729a657ccc459d5cf8017a3f35ba6a52b3;hpb=de1c38299ceb3160ed0c163d4dd8944ec6589a7f;p=mesa.git diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index e22899729a6..0bb22957926 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2003 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -37,34 +37,67 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "main/framebuffer.h" +#include "main/texobj.h" +#include "main/texstate.h" #include "program/program.h" #include "pipe/p_context.h" - +#include "pipe/p_shader_tokens.h" #include "util/u_simple_shaders.h" - #include "cso_cache/cso_context.h" +#include "util/u_debug.h" #include "st_context.h" #include "st_atom.h" #include "st_program.h" -/** - * Return pointer to a pass-through fragment shader. - * This shader is used when a texture is missing/incomplete. - */ -static void * -get_passthrough_fs(struct st_context *st) +/** Compress the fog function enums into a 2-bit value */ +static GLuint +translate_fog_mode(GLenum mode) { - if (!st->passthrough_fs) { - st->passthrough_fs = - util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_COLOR, - TGSI_INTERPOLATE_PERSPECTIVE, - TRUE); + switch (mode) { + case GL_LINEAR: return 1; + case GL_EXP: return 2; + case GL_EXP2: return 3; + default: + return 0; } +} - return st->passthrough_fs; +static unsigned +get_texture_target(struct gl_context *ctx, const unsigned unit) +{ + struct gl_texture_object *texObj = _mesa_get_tex_unit(ctx, unit)->_Current; + gl_texture_index index; + + if (texObj) { + index = _mesa_tex_target_to_index(ctx, texObj->Target); + } else { + /* fallback for missing texture */ + index = TEXTURE_2D_INDEX; + } + + /* Map mesa texture target to TGSI texture target. + * Copied from st_mesa_to_tgsi.c, the shadow part is omitted */ + switch(index) { + case TEXTURE_2D_MULTISAMPLE_INDEX: return TGSI_TEXTURE_2D_MSAA; + case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: return TGSI_TEXTURE_2D_ARRAY_MSAA; + case TEXTURE_BUFFER_INDEX: return TGSI_TEXTURE_BUFFER; + case TEXTURE_1D_INDEX: return TGSI_TEXTURE_1D; + case TEXTURE_2D_INDEX: return TGSI_TEXTURE_2D; + case TEXTURE_3D_INDEX: return TGSI_TEXTURE_3D; + case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE; + case TEXTURE_CUBE_ARRAY_INDEX: return TGSI_TEXTURE_CUBE_ARRAY; + case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT; + case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_1D_ARRAY; + case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_2D_ARRAY; + case TEXTURE_EXTERNAL_INDEX: return TGSI_TEXTURE_2D; + default: + debug_assert(0); + return TGSI_TEXTURE_1D; + } } @@ -83,32 +116,44 @@ update_fp( struct st_context *st ) assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); memset(&key, 0, sizeof(key)); - key.st = st; + key.st = st->has_shareable_shaders ? NULL : st; /* _NEW_FRAG_CLAMP */ key.clamp_color = st->clamp_frag_color_in_shader && st->ctx->Color._ClampFragmentColor; + /* _NEW_MULTISAMPLE | _NEW_BUFFERS */ + key.persample_shading = + st->force_persample_in_shader && + _mesa_is_multisample_enabled(st->ctx) && + st->ctx->Multisample.SampleShading && + st->ctx->Multisample.MinSampleShadingValue * + _mesa_geometric_samples(st->ctx->DrawBuffer) > 1; + + if (stfp->ati_fs) { + unsigned u; + + if (st->ctx->Fog.Enabled) { + key.fog = translate_fog_mode(st->ctx->Fog.Mode); + } + + for (u = 0; u < MAX_NUM_FRAGMENT_REGISTERS_ATI; u++) { + key.texture_targets[u] = get_texture_target(st->ctx, u); + } + } + st->fp_variant = st_get_fp_variant(st, stfp, &key); st_reference_fragprog(st, &st->fp, stfp); - if (st->missing_textures) { - /* use a pass-through frag shader that uses no textures */ - void *fs = get_passthrough_fs(st); - cso_set_fragment_shader_handle(st->cso_context, fs); - } - else { - cso_set_fragment_shader_handle(st->cso_context, - st->fp_variant->driver_shader); - } + cso_set_fragment_shader_handle(st->cso_context, + st->fp_variant->driver_shader); } const struct st_tracked_state st_update_fp = { - "st_update_fp", /* name */ { /* dirty */ - _NEW_BUFFERS, /* mesa */ + _NEW_BUFFERS | _NEW_MULTISAMPLE | _NEW_FOG, /* mesa */ ST_NEW_FRAGMENT_PROGRAM /* st */ }, update_fp /* update */ @@ -134,21 +179,23 @@ update_vp( struct st_context *st ) assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); memset(&key, 0, sizeof key); - key.st = st; /* variants are per-context */ + key.st = st->has_shareable_shaders ? NULL : st; /* When this is true, we will add an extra input to the vertex * shader translation (for edgeflags), an extra output with * edgeflag semantics, and extend the vertex shader to pass through * the input to the output. We'll need to use similar logic to set * up the extra vertex_element input for edgeflags. - * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA */ - key.passthrough_edgeflags = (st->vertdata_edgeflags && ( - st->ctx->Polygon.FrontMode != GL_FILL || - st->ctx->Polygon.BackMode != GL_FILL)); + key.passthrough_edgeflags = st->vertdata_edgeflags; key.clamp_color = st->clamp_vert_color_in_shader && - st->ctx->Light._ClampVertexColor; + st->ctx->Light._ClampVertexColor && + (stvp->Base.Base.OutputsWritten & + (VARYING_SLOT_COL0 | + VARYING_SLOT_COL1 | + VARYING_SLOT_BFC0 | + VARYING_SLOT_BFC1)); st->vp_variant = st_get_vp_variant(st, stvp, &key); @@ -162,10 +209,9 @@ update_vp( struct st_context *st ) const struct st_tracked_state st_update_vp = { - "st_update_vp", /* name */ { /* dirty */ - _NEW_POLYGON, /* mesa */ - ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */ + 0, /* mesa */ + ST_NEW_VERTEX_PROGRAM /* st */ }, update_vp /* update */ }; @@ -176,7 +222,6 @@ static void update_gp( struct st_context *st ) { struct st_geometry_program *stgp; - struct st_gp_variant_key key; if (!st->ctx->GeometryProgram._Current) { cso_set_geometry_shader_handle(st->cso_context, NULL); @@ -184,12 +229,10 @@ update_gp( struct st_context *st ) } stgp = st_geometry_program(st->ctx->GeometryProgram._Current); - assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM); - - memset(&key, 0, sizeof(key)); - key.st = st; + assert(stgp->Base.Base.Target == GL_GEOMETRY_PROGRAM_NV); - st->gp_variant = st_get_gp_variant(st, stgp, &key); + st->gp_variant = st_get_basic_variant(st, PIPE_SHADER_GEOMETRY, + &stgp->tgsi, &stgp->variants); st_reference_geomprog(st, &st->gp, stgp); @@ -198,10 +241,104 @@ update_gp( struct st_context *st ) } const struct st_tracked_state st_update_gp = { - "st_update_gp", /* name */ { /* dirty */ 0, /* mesa */ ST_NEW_GEOMETRY_PROGRAM /* st */ }, update_gp /* update */ }; + + + +static void +update_tcp( struct st_context *st ) +{ + struct st_tessctrl_program *sttcp; + + if (!st->ctx->TessCtrlProgram._Current) { + cso_set_tessctrl_shader_handle(st->cso_context, NULL); + return; + } + + sttcp = st_tessctrl_program(st->ctx->TessCtrlProgram._Current); + assert(sttcp->Base.Base.Target == GL_TESS_CONTROL_PROGRAM_NV); + + st->tcp_variant = st_get_basic_variant(st, PIPE_SHADER_TESS_CTRL, + &sttcp->tgsi, &sttcp->variants); + + st_reference_tesscprog(st, &st->tcp, sttcp); + + cso_set_tessctrl_shader_handle(st->cso_context, + st->tcp_variant->driver_shader); +} + +const struct st_tracked_state st_update_tcp = { + { /* dirty */ + 0, /* mesa */ + ST_NEW_TESSCTRL_PROGRAM /* st */ + }, + update_tcp /* update */ +}; + + + +static void +update_tep( struct st_context *st ) +{ + struct st_tesseval_program *sttep; + + if (!st->ctx->TessEvalProgram._Current) { + cso_set_tesseval_shader_handle(st->cso_context, NULL); + return; + } + + sttep = st_tesseval_program(st->ctx->TessEvalProgram._Current); + assert(sttep->Base.Base.Target == GL_TESS_EVALUATION_PROGRAM_NV); + + st->tep_variant = st_get_basic_variant(st, PIPE_SHADER_TESS_EVAL, + &sttep->tgsi, &sttep->variants); + + st_reference_tesseprog(st, &st->tep, sttep); + + cso_set_tesseval_shader_handle(st->cso_context, + st->tep_variant->driver_shader); +} + +const struct st_tracked_state st_update_tep = { + { /* dirty */ + 0, /* mesa */ + ST_NEW_TESSEVAL_PROGRAM /* st */ + }, + update_tep /* update */ +}; + + + +static void +update_cp( struct st_context *st ) +{ + struct st_compute_program *stcp; + + if (!st->ctx->ComputeProgram._Current) { + cso_set_compute_shader_handle(st->cso_context, NULL); + return; + } + + stcp = st_compute_program(st->ctx->ComputeProgram._Current); + assert(stcp->Base.Base.Target == GL_COMPUTE_PROGRAM_NV); + + st->cp_variant = st_get_cp_variant(st, &stcp->tgsi, &stcp->variants); + + st_reference_compprog(st, &st->cp, stcp); + + cso_set_compute_shader_handle(st->cso_context, + st->cp_variant->driver_shader); +} + +const struct st_tracked_state st_update_cp = { + { /* dirty */ + 0, /* mesa */ + ST_NEW_COMPUTE_PROGRAM /* st */ + }, + update_cp /* update */ +};