X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_state_derived.c;h=9fe0ddf1fb21af88e40289c3837b26fc43f629d8;hb=7b4a7a111754ff0849a1b7a131d359ea0b0cb847;hp=a8b3142d8cf60a08811f8e00bf5f1a6963238575;hpb=0cbb49aff59f7a671d153d9baa70aa78b07da538;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index a8b3142d8cf..9fe0ddf1fb2 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,15 +48,26 @@ 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; - unsigned vs_index; + int vs_index; uint i; + draw_prepare_shader_outputs(llvmpipe->draw); + + /* + * 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 @@ -67,30 +78,50 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) 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]); + fsInfo->input_semantic_name[i], + fsInfo->input_semantic_index[i]); - if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR && - lpfs->info.base.input_semantic_index[i] < 2) { - int idx = lpfs->info.base.input_semantic_index[i]; + 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; } + 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); /* - * Emit the requested fs attribute for all but position. + * 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.) */ - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + } 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 an 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()). + */ + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); + } } /* Figure out if we need bcolor as well. @@ -99,21 +130,42 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_BCOLOR, i); - if (vs_index > 0) { + if (vs_index >= 0) { llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs; - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } } - /* Figure out if we need pointsize as well. */ 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); + } + + /* 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); + } + } + + /* 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); @@ -138,24 +190,52 @@ 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_GS | + LP_NEW_TCS | + LP_NEW_TES | 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)) - llvmpipe_update_fs( llvmpipe ); + LP_NEW_OCCLUSION_QUERY)) + llvmpipe_update_fs(llvmpipe); + + if (llvmpipe->dirty & (LP_NEW_FS | + LP_NEW_FRAMEBUFFER | + LP_NEW_RASTERIZER | + LP_NEW_DEPTH_STENCIL_ALPHA)) { + + /* + * Rasterization is disabled if there is no pixel shader and + * both depth and stencil testing are disabled: + * http://msdn.microsoft.com/en-us/library/windows/desktop/bb205125 + * FIXME: set rasterizer_discard in state tracker instead. + */ + boolean null_fs = !llvmpipe->fs || + llvmpipe->fs->info.base.num_instructions <= 1; + boolean discard = + (llvmpipe->sample_mask & 1) == 0 || + (llvmpipe->rasterizer ? llvmpipe->rasterizer->rasterizer_discard : FALSE) || + (null_fs && + !llvmpipe->depth_stencil->depth.enabled && + !llvmpipe->depth_stencil->stencil[0].enabled); + lp_setup_set_rasterizer_discard(llvmpipe->setup, discard); + } if (llvmpipe->dirty & (LP_NEW_FS | - LP_NEW_RASTERIZER)) + LP_NEW_FRAMEBUFFER | + LP_NEW_RASTERIZER)) llvmpipe_update_setup( llvmpipe ); if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) @@ -163,7 +243,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) &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, @@ -172,19 +252,42 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) llvmpipe->stencil_ref.ref_value); } - if (llvmpipe->dirty & LP_NEW_CONSTANTS) - lp_setup_set_fs_constants(llvmpipe->setup, - llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]); + if (llvmpipe->dirty & LP_NEW_FS_CONSTANTS) + lp_setup_set_fs_constants(llvmpipe->setup, + ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]), + llvmpipe->constants[PIPE_SHADER_FRAGMENT]); + + if (llvmpipe->dirty & LP_NEW_FS_SSBOS) + lp_setup_set_fs_ssbos(llvmpipe->setup, + ARRAY_SIZE(llvmpipe->ssbos[PIPE_SHADER_FRAGMENT]), + llvmpipe->ssbos[PIPE_SHADER_FRAGMENT]); + + if (llvmpipe->dirty & LP_NEW_FS_IMAGES) + lp_setup_set_fs_images(llvmpipe->setup, + ARRAY_SIZE(llvmpipe->images[PIPE_SHADER_FRAGMENT]), + llvmpipe->images[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; }