1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "util/u_math.h" 29#include "util/u_memory.h" 30#include "pipe/p_shader_tokens.h" 31#include "draw/draw_context.h" 32#include "draw/draw_vertex.h" 33#include "draw/draw_private.h" 34#include "lp_context.h" 35#include "lp_screen.h" 36#include "lp_setup.h" 37#include "lp_state.h" 38 39 40 41/** 42 * The vertex info describes how to convert the post-transformed vertices 43 * (simple float[][4]) used by the 'draw' module into vertices for 44 * rasterization. 45 * 46 * This function validates the vertex layout. 47 */ 48static void 49compute_vertex_info(struct llvmpipe_context *llvmpipe) 50{ 51 const struct tgsi_shader_info *fsInfo = &llvmpipe->fs->info.base; 52 struct vertex_info *vinfo = &llvmpipe->vertex_info; 53 int vs_index; 54 uint i; 55 56 draw_prepare_shader_outputs(llvmpipe->draw); 57 58 /* 59 * Those can't actually be 0 (because pos is always at 0). 60 * But use ints anyway to avoid confusion (in vs outputs, they 61 * can very well be at pos 0). 62 */ 63 llvmpipe->color_slot[0] = -1; 64 llvmpipe->color_slot[1] = -1; 65 llvmpipe->bcolor_slot[0] = -1; 66 llvmpipe->bcolor_slot[1] = -1; 67 llvmpipe->viewport_index_slot = -1; 68 llvmpipe->layer_slot = -1; 69 llvmpipe->face_slot = -1; 70 llvmpipe->psize_slot = -1; 71 72 /* 73 * Match FS inputs against VS outputs, emitting the necessary 74 * attributes. Could cache these structs and look them up with a 75 * combination of fragment shader, vertex shader ids. 76 */ 77 78 vinfo->num_attribs = 0; 79 80 vs_index = draw_find_shader_output(llvmpipe->draw, 81 TGSI_SEMANTIC_POSITION, 0); 82 83 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 84 85 for (i = 0; i < fsInfo->num_inputs; i++) { 86 /* 87 * Search for each input in current vs output: 88 */ 89 vs_index = draw_find_shader_output(llvmpipe->draw, 90 fsInfo->input_semantic_name[i], 91 fsInfo->input_semantic_index[i]); 92 93 if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR && 94 fsInfo->input_semantic_index[i] < 2) { 95 int idx = fsInfo->input_semantic_index[i]; 96 llvmpipe->color_slot[idx] = (int)vinfo->num_attribs; 97 } 98 99 if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_FACE) { 100 llvmpipe->face_slot = (int)vinfo->num_attribs; 101 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 102 /* 103 * For vp index and layer, if the fs requires them but the vs doesn't 104 * provide them, draw (vbuf) will give us the required 0 (slot -1). 105 * (This means in this case we'll also use those slots in setup, which 106 * isn't necessary but they'll contain the correct (0) value.) 107 */ 108 } else if (fsInfo->input_semantic_name[i] == 109 TGSI_SEMANTIC_VIEWPORT_INDEX) { 110 llvmpipe->viewport_index_slot = (int)vinfo->num_attribs; 111 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 112 } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) { 113 llvmpipe->layer_slot = (int)vinfo->num_attribs; 114 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 115 } else { 116 /* 117 * Note that we'd actually want to skip position (as we won't use 118 * the attribute in the fs) but can't. The reason is that we don't 119 * actually have an input/output map for setup (even though it looks 120 * like we do...). Could adjust for this though even without a map 121 * (in llvmpipe_create_fs_state()). 122 */ 123 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 124 } 125 } 126 127 /* Figure out if we need bcolor as well. 128 */ 129 for (i = 0; i < 2; i++) { 130 vs_index = draw_find_shader_output(llvmpipe->draw, 131 TGSI_SEMANTIC_BCOLOR, i); 132 133 if (vs_index >= 0) { 134 llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs; 135 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 136 } 137 } 138 139 /* Figure out if we need pointsize as well. 140 */ 141 vs_index = draw_find_shader_output(llvmpipe->draw, 142 TGSI_SEMANTIC_PSIZE, 0); 143 144 if (vs_index >= 0) { 145 llvmpipe->psize_slot = (int)vinfo->num_attribs; 146 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 147 } 148 149 /* Figure out if we need viewport index (if it wasn't already in fs input) */ 150 if (llvmpipe->viewport_index_slot < 0) { 151 vs_index = draw_find_shader_output(llvmpipe->draw, 152 TGSI_SEMANTIC_VIEWPORT_INDEX, 153 0); 154 if (vs_index >= 0) { 155 llvmpipe->viewport_index_slot =(int)vinfo->num_attribs; 156 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 157 } 158 } 159 160 /* Figure out if we need layer (if it wasn't already in fs input) */ 161 if (llvmpipe->layer_slot < 0) { 162 vs_index = draw_find_shader_output(llvmpipe->draw, 163 TGSI_SEMANTIC_LAYER, 164 0); 165 if (vs_index >= 0) { 166 llvmpipe->layer_slot = (int)vinfo->num_attribs; 167 draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); 168 } 169 } 170 171 draw_compute_vertex_size(vinfo); 172 lp_setup_set_vertex_info(llvmpipe->setup, vinfo); 173} 174 175 176static void 177check_linear_rasterizer(struct llvmpipe_context *lp) 178{ 179 boolean bgr8; 180 boolean permit_linear; 181 boolean single_vp; 182 boolean clipping_changed = FALSE; 183 184 bgr8 = (lp->framebuffer.nr_cbufs == 1 && lp->framebuffer.cbufs[0] && 185 util_res_sample_count(lp->framebuffer.cbufs[0]->texture) == 1 && 186 lp->framebuffer.cbufs[0]->texture->target == PIPE_TEXTURE_2D && 187 (lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_B8G8R8A8_UNORM || 188 lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_B8G8R8X8_UNORM)); 189 190 /* permit_linear means guardband, hence fake scissor, which we can only 191 * handle if there's just one vp. */ 192 single_vp = lp->viewport_index_slot < 0; 193 permit_linear = (!lp->framebuffer.zsbuf && 194 bgr8 && 195 single_vp); 196 197 /* Tell draw that we're happy doing our own x/y clipping. 198 */ 199 if (lp->permit_linear_rasterizer != permit_linear) { 200 lp->permit_linear_rasterizer = permit_linear; 201 lp_setup_set_linear_mode(lp->setup, permit_linear); 202 clipping_changed = TRUE; 203 } 204 205 if (lp->single_vp != single_vp) { 206 lp->single_vp = single_vp; 207 clipping_changed = TRUE; 208 } 209 210 /* Disable xy clipping in linear mode. 211 * 212 * Use a guard band if we don't have zsbuf. Could enable 213 * guardband always - this just to be conservative. 214 * 215 * Because we have a layering violation where the draw module emits 216 * state changes to the driver while we're already inside a draw 217 * call, need to be careful about when we make calls back to the 218 * draw module. Hence the clipping_changed flag which is as much 219 * to prevent flush recursion as it is to short-circuit noop state 220 * changes. 221 */ 222 if (clipping_changed) { 223 draw_set_driver_clipping(lp->draw, 224 FALSE, 225 FALSE, 226 permit_linear, 227 single_vp); 228 } 229} 230 231 232/** 233 * Handle state changes before clears. 234 * Called just prior to clearing (pipe::clear()). 235 */ 236void 237llvmpipe_update_derived_clear(struct llvmpipe_context *llvmpipe) 238{ 239 if (llvmpipe->dirty & (LP_NEW_FS | 240 LP_NEW_FRAMEBUFFER)) 241 check_linear_rasterizer(llvmpipe); 242} 243 244 245/** 246 * Handle state changes. 247 * Called just prior to drawing anything (pipe::draw_arrays(), etc). 248 * 249 * Hopefully this will remain quite simple, otherwise need to pull in 250 * something like the gallium frontend mechanism. 251 */ 252void 253llvmpipe_update_derived(struct llvmpipe_context *llvmpipe) 254{ 255 struct llvmpipe_screen *lp_screen = llvmpipe_screen(llvmpipe->pipe.screen); 256 257 /* Check for updated textures. 258 */ 259 if (llvmpipe->tex_timestamp != lp_screen->timestamp) { 260 llvmpipe->tex_timestamp = lp_screen->timestamp; 261 llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; 262 } 263 264 /* This needs LP_NEW_RASTERIZER because of draw_prepare_shader_outputs(). */ 265 if (llvmpipe->dirty & (LP_NEW_RASTERIZER | 266 LP_NEW_FS | 267 LP_NEW_GS | 268 LP_NEW_TCS | 269 LP_NEW_TES | 270 LP_NEW_VS)) 271 compute_vertex_info(llvmpipe); 272 273 if (llvmpipe->dirty & (LP_NEW_FS | 274 LP_NEW_FRAMEBUFFER | 275 LP_NEW_BLEND | 276 LP_NEW_SCISSOR | 277 LP_NEW_DEPTH_STENCIL_ALPHA | 278 LP_NEW_RASTERIZER | 279 LP_NEW_SAMPLER | 280 LP_NEW_SAMPLER_VIEW | 281 LP_NEW_OCCLUSION_QUERY)) 282 llvmpipe_update_fs(llvmpipe); 283 284 if (llvmpipe->dirty & (LP_NEW_FS | 285 LP_NEW_FRAMEBUFFER | 286 LP_NEW_RASTERIZER | 287 LP_NEW_SAMPLE_MASK | 288 LP_NEW_DEPTH_STENCIL_ALPHA)) { 289 290 /* 291 * Rasterization is disabled if there is no pixel shader and 292 * both depth and stencil testing are disabled: 293 * http://msdn.microsoft.com/en-us/library/windows/desktop/bb205125 294 * FIXME: set rasterizer_discard in state tracker instead. 295 */ 296 boolean null_fs = !llvmpipe->fs || 297 llvmpipe->fs->info.base.num_instructions <= 1; 298 boolean discard = 299 (llvmpipe->sample_mask) == 0 || 300 (llvmpipe->rasterizer ? llvmpipe->rasterizer->rasterizer_discard : FALSE) || 301 (null_fs && 302 !llvmpipe->depth_stencil->depth_enabled && 303 !llvmpipe->depth_stencil->stencil[0].enabled); 304 lp_setup_set_rasterizer_discard(llvmpipe->setup, discard); 305 } 306 307 if (llvmpipe->dirty & (LP_NEW_FS | 308 LP_NEW_FRAMEBUFFER | 309 LP_NEW_RASTERIZER)) 310 llvmpipe_update_setup(llvmpipe); 311 312 if (llvmpipe->dirty & LP_NEW_SAMPLE_MASK) 313 lp_setup_set_sample_mask(llvmpipe->setup, llvmpipe->sample_mask); 314 315 if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) 316 lp_setup_set_blend_color(llvmpipe->setup, 317 &llvmpipe->blend_color); 318 319 if (llvmpipe->dirty & LP_NEW_SCISSOR) 320 lp_setup_set_scissors(llvmpipe->setup, llvmpipe->scissors); 321 322 if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) { 323 lp_setup_set_alpha_ref_value(llvmpipe->setup, 324 llvmpipe->depth_stencil->alpha_ref_value); 325 lp_setup_set_stencil_ref_values(llvmpipe->setup, 326 llvmpipe->stencil_ref.ref_value); 327 } 328 329 if (llvmpipe->dirty & LP_NEW_FS_CONSTANTS) 330 lp_setup_set_fs_constants(llvmpipe->setup, 331 ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]), 332 llvmpipe->constants[PIPE_SHADER_FRAGMENT]); 333 334 if (llvmpipe->dirty & LP_NEW_FS_SSBOS) 335 lp_setup_set_fs_ssbos(llvmpipe->setup, 336 ARRAY_SIZE(llvmpipe->ssbos[PIPE_SHADER_FRAGMENT]), 337 llvmpipe->ssbos[PIPE_SHADER_FRAGMENT], llvmpipe->fs_ssbo_write_mask); 338 339 if (llvmpipe->dirty & LP_NEW_FS_IMAGES) 340 lp_setup_set_fs_images(llvmpipe->setup, 341 ARRAY_SIZE(llvmpipe->images[PIPE_SHADER_FRAGMENT]), 342 llvmpipe->images[PIPE_SHADER_FRAGMENT]); 343 344 if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW)) 345 lp_setup_set_fragment_sampler_views(llvmpipe->setup, 346 llvmpipe->num_sampler_views[PIPE_SHADER_FRAGMENT], 347 llvmpipe->sampler_views[PIPE_SHADER_FRAGMENT]); 348 349 if (llvmpipe->dirty & (LP_NEW_SAMPLER)) 350 lp_setup_set_fragment_sampler_state(llvmpipe->setup, 351 llvmpipe->num_samplers[PIPE_SHADER_FRAGMENT], 352 llvmpipe->samplers[PIPE_SHADER_FRAGMENT]); 353 354 if (llvmpipe->dirty & LP_NEW_VIEWPORT) { 355 /* 356 * Update setup and fragment's view of the active viewport state. 357 * 358 * XXX TODO: It is possible to only loop over the active viewports 359 * instead of all viewports (PIPE_MAX_VIEWPORTS). 360 */ 361 lp_setup_set_viewports(llvmpipe->setup, 362 PIPE_MAX_VIEWPORTS, 363 llvmpipe->viewports); 364 } 365 366 llvmpipe_update_derived_clear(llvmpipe); 367 368 llvmpipe->dirty = 0; 369} 370 371