X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_state_derived.c;h=c90f2f270fe2a8ac6f50ffafb1f55b61c6800465;hb=e26a978773ba8fbff04cd2ab3342fcb02e90c06e;hp=7f68818ab47c0a6ba47ba1bb445e207f7af5cf4e;hpb=986cb9d5cf60bc11c7facc19017b5432b17240f7;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 7f68818ab47..c90f2f270fe 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.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. @@ -48,91 +48,92 @@ static void compute_vertex_info(struct llvmpipe_context *llvmpipe) { - const struct lp_fragment_shader *lpfs = llvmpipe->fs; + const struct tgsi_shader_info *fsInfo = &llvmpipe->fs->info.base; struct vertex_info *vinfo = &llvmpipe->vertex_info; - struct lp_shader_input *inputs = llvmpipe->inputs; - unsigned vs_index; + int vs_index; uint i; + draw_prepare_shader_outputs(llvmpipe->draw); + /* - * Match FS inputs against VS outputs, emitting the necessary attributes. + * Those can't actually be 0 (because pos is always at 0). + * But use ints anyway to avoid confusion (in vs outputs, they + * can very well be at pos 0). + */ + llvmpipe->color_slot[0] = -1; + llvmpipe->color_slot[1] = -1; + llvmpipe->bcolor_slot[0] = -1; + llvmpipe->bcolor_slot[1] = -1; + llvmpipe->viewport_index_slot = -1; + llvmpipe->layer_slot = -1; + llvmpipe->face_slot = -1; + llvmpipe->psize_slot = -1; + + /* + * Match FS inputs against VS outputs, emitting the necessary + * attributes. Could cache these structs and look them up with a + * combination of fragment shader, vertex shader ids. */ vinfo->num_attribs = 0; vs_index = draw_find_shader_output(llvmpipe->draw, - TGSI_SEMANTIC_POSITION, - 0); + TGSI_SEMANTIC_POSITION, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); - for (i = 0; i < lpfs->info.base.num_inputs; i++) { + for (i = 0; i < fsInfo->num_inputs; i++) { /* * Search for each input in current vs output: */ - vs_index = draw_find_shader_output(llvmpipe->draw, - lpfs->info.base.input_semantic_name[i], - lpfs->info.base.input_semantic_index[i]); - if (vs_index < 0) { - /* - * This can happen with sprite coordinates - the vertex - * shader doesn't need to provide an output as we generate - * them internally. However, lets keep pretending that there - * is something there to not confuse other code. - */ - vs_index = 0; - } + fsInfo->input_semantic_name[i], + fsInfo->input_semantic_index[i]); - /* This can be pre-computed, except for flatshade: - */ - inputs[i].usage_mask = lpfs->info.base.input_usage_mask[i]; - - switch (lpfs->info.base.input_interpolate[i]) { - case TGSI_INTERPOLATE_CONSTANT: - inputs[i].interp = LP_INTERP_CONSTANT; - break; - case TGSI_INTERPOLATE_LINEAR: - inputs[i].interp = LP_INTERP_LINEAR; - break; - case TGSI_INTERPOLATE_PERSPECTIVE: - inputs[i].interp = LP_INTERP_PERSPECTIVE; - break; - default: - assert(0); - break; + if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR && + fsInfo->input_semantic_index[i] < 2) { + int idx = fsInfo->input_semantic_index[i]; + llvmpipe->color_slot[idx] = (int)vinfo->num_attribs; } - switch (lpfs->info.base.input_semantic_name[i]) { - case TGSI_SEMANTIC_FACE: - inputs[i].interp = LP_INTERP_FACING; - break; - case TGSI_SEMANTIC_POSITION: - /* Position was already emitted above - */ - inputs[i].interp = LP_INTERP_POSITION; - inputs[i].src_index = 0; - continue; - case TGSI_SEMANTIC_COLOR: - /* Colors are linearly inputs[i].interpolated in the fragment shader - * even when flatshading is active. This just tells the - * setup module to use coefficients with ddx==0 and - * ddy==0. + if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_FACE) { + llvmpipe->face_slot = (int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + /* + * For vp index and layer, if the fs requires them but the vs doesn't + * provide them, draw (vbuf) will give us the required 0 (slot -1). + * (This means in this case we'll also use those slots in setup, which + * isn't necessary but they'll contain the correct (0) value.) + */ + } else if (fsInfo->input_semantic_name[i] == + TGSI_SEMANTIC_VIEWPORT_INDEX) { + llvmpipe->viewport_index_slot = (int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) { + llvmpipe->layer_slot = (int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + } else { + /* + * Note that we'd actually want to skip position (as we won't use + * the attribute in the fs) but can't. The reason is that we don't + * actually have a input/output map for setup (even though it looks + * like we do...). Could adjust for this though even without a map + * (in llvmpipe_create_fs_state()). */ - if (llvmpipe->rasterizer->flatshade) - inputs[i].interp = LP_INTERP_CONSTANT; - break; - - default: - break; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } + } - /* - * Emit the requested fs attribute for all but position. - */ + /* Figure out if we need bcolor as well. + */ + for (i = 0; i < 2; i++) { + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_BCOLOR, i); - inputs[i].src_index = vinfo->num_attribs; - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + if (vs_index >= 0) { + llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + } } /* Figure out if we need pointsize as well. @@ -140,20 +141,35 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_PSIZE, 0); - if (vs_index > 0) { - llvmpipe->psize_slot = vinfo->num_attribs; - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); + if (vs_index >= 0) { + llvmpipe->psize_slot = (int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } - llvmpipe->num_inputs = lpfs->info.base.num_inputs; + /* Figure out if we need viewport index (if it wasn't already in fs input) */ + if (llvmpipe->viewport_index_slot < 0) { + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_VIEWPORT_INDEX, + 0); + if (vs_index >= 0) { + llvmpipe->viewport_index_slot =(int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + } + } - draw_compute_vertex_size(vinfo); + /* Figure out if we need layer (if it wasn't already in fs input) */ + if (llvmpipe->layer_slot < 0) { + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_LAYER, + 0); + if (vs_index >= 0) { + llvmpipe->layer_slot = (int)vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + } + } + draw_compute_vertex_size(vinfo); lp_setup_set_vertex_info(llvmpipe->setup, vinfo); - - lp_setup_set_fs_inputs(llvmpipe->setup, - inputs, - lpfs->info.base.num_inputs); } @@ -174,28 +190,43 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) llvmpipe->tex_timestamp = lp_screen->timestamp; llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; } - + + /* This needs LP_NEW_RASTERIZER because of draw_prepare_shader_outputs(). */ if (llvmpipe->dirty & (LP_NEW_RASTERIZER | LP_NEW_FS | LP_NEW_VS)) - compute_vertex_info( llvmpipe ); + compute_vertex_info(llvmpipe); if (llvmpipe->dirty & (LP_NEW_FS | + LP_NEW_FRAMEBUFFER | LP_NEW_BLEND | LP_NEW_SCISSOR | LP_NEW_DEPTH_STENCIL_ALPHA | LP_NEW_RASTERIZER | LP_NEW_SAMPLER | LP_NEW_SAMPLER_VIEW | - LP_NEW_QUERY)) + LP_NEW_OCCLUSION_QUERY)) llvmpipe_update_fs( llvmpipe ); + if (llvmpipe->dirty & (LP_NEW_RASTERIZER)) { + boolean discard = + (llvmpipe->sample_mask & 1) == 0 || + (llvmpipe->rasterizer ? llvmpipe->rasterizer->rasterizer_discard : FALSE); + + lp_setup_set_rasterizer_discard(llvmpipe->setup, discard); + } + + if (llvmpipe->dirty & (LP_NEW_FS | + LP_NEW_FRAMEBUFFER | + LP_NEW_RASTERIZER)) + llvmpipe_update_setup( llvmpipe ); + if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color); if (llvmpipe->dirty & LP_NEW_SCISSOR) - lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor); + lp_setup_set_scissors(llvmpipe->setup, llvmpipe->scissors); if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) { lp_setup_set_alpha_ref_value(llvmpipe->setup, @@ -205,18 +236,31 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) } if (llvmpipe->dirty & LP_NEW_CONSTANTS) - lp_setup_set_fs_constants(llvmpipe->setup, - llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]); + lp_setup_set_fs_constants(llvmpipe->setup, + Elements(llvmpipe->constants[PIPE_SHADER_FRAGMENT]), + llvmpipe->constants[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW)) lp_setup_set_fragment_sampler_views(llvmpipe->setup, - llvmpipe->num_fragment_sampler_views, - llvmpipe->fragment_sampler_views); + llvmpipe->num_sampler_views[PIPE_SHADER_FRAGMENT], + llvmpipe->sampler_views[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & (LP_NEW_SAMPLER)) lp_setup_set_fragment_sampler_state(llvmpipe->setup, - llvmpipe->num_samplers, - llvmpipe->sampler); + llvmpipe->num_samplers[PIPE_SHADER_FRAGMENT], + llvmpipe->samplers[PIPE_SHADER_FRAGMENT]); + + if (llvmpipe->dirty & LP_NEW_VIEWPORT) { + /* + * Update setup and fragment's view of the active viewport state. + * + * XXX TODO: It is possible to only loop over the active viewports + * instead of all viewports (PIPE_MAX_VIEWPORTS). + */ + lp_setup_set_viewports(llvmpipe->setup, + PIPE_MAX_VIEWPORTS, + llvmpipe->viewports); + } llvmpipe->dirty = 0; }