static void aaline_flush(struct draw_stage *stage, unsigned flags) { struct draw_context *draw = stage->draw; struct aaline_stage *aaline = aaline_stage(stage); struct pipe_context *pipe = draw->pipe; stage->line = aaline_first_line; stage->next->flush( stage->next, flags ); /* restore original frag shader, texture, sampler state */ draw->suspend_flushing = TRUE; aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, aaline->state.sampler); aaline->driver_set_sampler_views(pipe, aaline->num_sampler_views, aaline->state.sampler_views); /* restore original rasterizer state */ if (draw->rast_handle) { pipe->bind_rasterizer_state(pipe, draw->rast_handle); } draw->suspend_flushing = FALSE; draw_remove_extra_vertex_attribs(draw); }
/** * Prepare outputs slots from the draw module * * Certain parts of the draw module can emit additional * outputs that can be quite useful to the backends, a good * example of it is the process of decomposing primitives * into wireframes (aka. lines) which normally would lose * the face-side information, but using this method we can * inject another shader output which passes the original * face side information to the backend. */ void draw_prepare_shader_outputs(struct draw_context *draw) { draw_remove_extra_vertex_attribs(draw); draw_prim_assembler_prepare_outputs(draw->ia); draw_unfilled_prepare_outputs(draw, draw->pipeline.unfilled); if (draw->pipeline.aapoint) draw_aapoint_prepare_outputs(draw, draw->pipeline.aapoint); if (draw->pipeline.aaline) draw_aaline_prepare_outputs(draw, draw->pipeline.aaline); }
static void widepoint_flush( struct draw_stage *stage, unsigned flags ) { struct draw_context *draw = stage->draw; struct pipe_context *pipe = draw->pipe; stage->point = widepoint_first_point; stage->next->flush( stage->next, flags ); draw_remove_extra_vertex_attribs(draw); /* restore original rasterizer state */ if (draw->rast_handle) { draw->suspend_flushing = TRUE; pipe->bind_rasterizer_state(pipe, draw->rast_handle); draw->suspend_flushing = FALSE; } }
static void aapoint_flush(struct draw_stage *stage, unsigned flags) { struct draw_context *draw = stage->draw; struct aapoint_stage *aapoint = aapoint_stage(stage); struct pipe_context *pipe = draw->pipe; stage->point = aapoint_first_point; stage->next->flush( stage->next, flags ); /* restore original frag shader */ draw->suspend_flushing = TRUE; aapoint->driver_bind_fs_state(pipe, aapoint->fs ? aapoint->fs->driver_fs : NULL); /* restore original rasterizer state */ if (draw->rast_handle) { pipe->bind_rasterizer_state(pipe, draw->rast_handle); } draw->suspend_flushing = FALSE; draw_remove_extra_vertex_attribs(draw); }
static void widepoint_first_point(struct draw_stage *stage, struct prim_header *header) { struct widepoint_stage *wide = widepoint_stage(stage); struct draw_context *draw = stage->draw; struct pipe_context *pipe = draw->pipe; const struct pipe_rasterizer_state *rast = draw->rasterizer; void *r; wide->half_point_size = 0.5f * rast->point_size; wide->xbias = 0.0; wide->ybias = 0.0; if (rast->half_pixel_center) { wide->xbias = 0.125; wide->ybias = -0.125; } /* Disable triangle culling, stippling, unfilled mode etc. */ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade); draw->suspend_flushing = TRUE; pipe->bind_rasterizer_state(pipe, r); draw->suspend_flushing = FALSE; /* XXX we won't know the real size if it's computed by the vertex shader! */ if ((rast->point_size > draw->pipeline.wide_point_threshold) || (rast->point_quad_rasterization && draw->pipeline.point_sprite)) { stage->point = widepoint_point; } else { stage->point = draw_pipe_passthrough_point; } draw_remove_extra_vertex_attribs(draw); if (rast->point_quad_rasterization) { const struct draw_fragment_shader *fs = draw->fs.fragment_shader; uint i; assert(fs); wide->num_texcoord_gen = 0; /* Loop over fragment shader inputs looking for the PCOORD input or inputs * for which bit 'k' in sprite_coord_enable is set. */ for (i = 0; i < fs->info.num_inputs; i++) { int slot; const unsigned sn = fs->info.input_semantic_name[i]; const unsigned si = fs->info.input_semantic_index[i]; if (sn == wide->sprite_coord_semantic) { /* Note that sprite_coord_enable is a bitfield of 32 bits. */ if (si >= 32 || !(rast->sprite_coord_enable & (1 << si))) continue; } else if (sn != TGSI_SEMANTIC_PCOORD) { continue; } /* OK, this generic attribute needs to be replaced with a * sprite coord (see above). */ slot = draw_alloc_extra_vertex_attrib(draw, sn, si); /* add this slot to the texcoord-gen list */ wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot; } } wide->psize_slot = -1; if (rast->point_size_per_vertex) { /* find PSIZ vertex output */ const struct draw_vertex_shader *vs = draw->vs.vertex_shader; uint i; for (i = 0; i < vs->info.num_outputs; i++) { if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { wide->psize_slot = i; break; } } } stage->point( stage, header ); }