*/
+#include "pipe/p_context.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "draw_context.h"
#include "draw_gs.h"
-struct draw_context *draw_create( void )
+struct draw_context *draw_create( struct pipe_context *pipe )
{
struct draw_context *draw = CALLOC_STRUCT( draw_context );
if (draw == NULL)
if (!draw_gs_init( draw ))
goto fail;
+ draw->pipe = pipe;
+
return draw;
fail:
void draw_destroy( struct draw_context *draw )
{
+ struct pipe_context *pipe = draw->pipe;
+ int i, j;
+
if (!draw)
return;
-
+ /* free any rasterizer CSOs that we may have created.
+ */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ if (draw->rasterizer_no_cull[i][j]) {
+ pipe->delete_rasterizer_state(pipe, draw->rasterizer_no_cull[i][j]);
+ }
+ }
+ }
/* Not so fast -- we're just borrowing this at the moment.
*
* This causes the drawing pipeline to be rebuilt.
*/
void draw_set_rasterizer_state( struct draw_context *draw,
- const struct pipe_rasterizer_state *raster )
+ const struct pipe_rasterizer_state *raster,
+ void *rast_handle )
{
- draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+ if (!draw->suspend_flushing) {
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
- draw->rasterizer = raster;
- draw->bypass_clipping = draw->driver.bypass_clipping;
+ draw->rasterizer = raster;
+ draw->rast_handle = rast_handle;
+
+ draw->bypass_clipping = draw->driver.bypass_clipping;
+ }
}
return draw->gs.position_output;
return draw->vs.position_output;
}
+
+
+/**
+ * Return a pointer/handle for a driver/CSO rasterizer object which
+ * disabled culling, stippling, unfilled tris, etc.
+ * This is used by some pipeline stages (such as wide_point, aa_line
+ * and aa_point) which convert points/lines into triangles. In those
+ * cases we don't want to accidentally cull the triangles.
+ *
+ * \param scissor should the rasterizer state enable scissoring?
+ * \param flatshade should the rasterizer state use flat shading?
+ * \return rasterizer CSO handle
+ */
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+ boolean scissor,
+ boolean flatshade )
+{
+ if (!draw->rasterizer_no_cull[scissor][flatshade]) {
+ /* create now */
+ struct pipe_context *pipe = draw->pipe;
+ struct pipe_rasterizer_state rast;
+
+ memset(&rast, 0, sizeof(rast));
+ rast.scissor = scissor;
+ rast.flatshade = flatshade;
+ rast.front_winding = PIPE_WINDING_CCW;
+ rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules;
+
+ draw->rasterizer_no_cull[scissor][flatshade] =
+ pipe->create_rasterizer_state(pipe, &rast);
+ }
+ return draw->rasterizer_no_cull[scissor][flatshade];
+}
struct tgsi_sampler;
-struct draw_context *draw_create( void );
+struct draw_context *draw_create( struct pipe_context *pipe );
void draw_destroy( struct draw_context *draw );
const struct pipe_clip_state *clip );
void draw_set_rasterizer_state( struct draw_context *draw,
- const struct pipe_rasterizer_state *raster );
+ const struct pipe_rasterizer_state *raster,
+ void *rast_handle );
void draw_set_rasterize_stage( struct draw_context *draw,
struct draw_stage *stage );
void **);
void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
struct pipe_texture **);
-
- struct pipe_context *pipe;
};
static boolean
generate_aaline_fs(struct aaline_stage *aaline)
{
+ struct pipe_context *pipe = aaline->stage.draw->pipe;
const struct pipe_shader_state *orig_fs = &aaline->fs->state;
struct pipe_shader_state aaline_fs;
struct aa_transform_context transform;
aaline->fs->sampler_unit = transform.freeSampler;
aaline->fs->aaline_fs
- = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
+ = aaline->driver_create_fs_state(pipe, &aaline_fs);
if (aaline->fs->aaline_fs == NULL)
goto fail;
static boolean
aaline_create_texture(struct aaline_stage *aaline)
{
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = aaline->stage.draw->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture texTemp;
uint level;
aaline_create_sampler(struct aaline_stage *aaline)
{
struct pipe_sampler_state sampler;
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = aaline->stage.draw->pipe;
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
bind_aaline_fragment_shader(struct aaline_stage *aaline)
{
struct draw_context *draw = aaline->stage.draw;
+ struct pipe_context *pipe = draw->pipe;
if (!aaline->fs->aaline_fs &&
!generate_aaline_fs(aaline))
return FALSE;
draw->suspend_flushing = TRUE;
- aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
+ aaline->driver_bind_fs_state(pipe, aaline->fs->aaline_fs);
draw->suspend_flushing = FALSE;
return TRUE;
{
auto struct aaline_stage *aaline = aaline_stage(stage);
struct draw_context *draw = stage->draw;
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
uint num_samplers;
+ void *r;
assert(draw->rasterizer->line_smooth);
draw->suspend_flushing = TRUE;
aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
+
+ /* Disable triangle culling, stippling, unfilled mode etc. */
+ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+ pipe->bind_rasterizer_state(pipe, r);
+
draw->suspend_flushing = FALSE;
/* now really draw first line */
{
struct draw_context *draw = stage->draw;
struct aaline_stage *aaline = aaline_stage(stage);
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = draw->pipe;
stage->line = aaline_first_line;
stage->next->flush( stage->next, flags );
aaline->state.sampler);
aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
aaline->state.texture);
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ }
+
draw->suspend_flushing = FALSE;
draw->extra_shader_outputs.slot = 0;
aaline_destroy(struct draw_stage *stage)
{
struct aaline_stage *aaline = aaline_stage(stage);
+ struct pipe_context *pipe = stage->draw->pipe;
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
}
if (aaline->sampler_cso)
- aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
+ pipe->delete_sampler_state(pipe, aaline->sampler_cso);
if (aaline->texture)
pipe_texture_reference(&aaline->texture, NULL);
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
+
if (aafs == NULL)
return NULL;
aafs->state = *fs;
/* pass-through */
- aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
+ aafs->driver_fs = aaline->driver_create_fs_state(pipe, fs);
return aafs;
}
/* save current */
aaline->fs = aafs;
/* pass-through */
- aaline->driver_bind_fs_state(aaline->pipe,
- (aafs ? aafs->driver_fs : NULL));
+ aaline->driver_bind_fs_state(pipe, (aafs ? aafs->driver_fs : NULL));
}
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
+
/* pass-through */
- aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
+ aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
if (aafs->aaline_fs)
- aaline->driver_delete_fs_state(aaline->pipe, aafs->aaline_fs);
+ aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
FREE(aafs);
}
aaline->num_samplers = num;
/* pass-through */
- aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
+ aaline->driver_bind_sampler_states(pipe, num, sampler);
}
aaline->num_textures = num;
/* pass-through */
- aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
+ aaline->driver_set_sampler_textures(pipe, num, texture);
}
if (!aaline)
goto fail;
- aaline->pipe = pipe;
-
/* create special texture, sampler state */
if (!aaline_create_texture(aaline))
goto fail;
const struct pipe_shader_state *);
void (*driver_bind_fs_state)(struct pipe_context *, void *);
void (*driver_delete_fs_state)(struct pipe_context *, void *);
-
- struct pipe_context *pipe;
};
struct pipe_shader_state aapoint_fs;
struct aa_transform_context transform;
const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS;
+ struct pipe_context *pipe = aapoint->stage.draw->pipe;
aapoint_fs = *orig_fs; /* copy to init */
aapoint_fs.tokens = tgsi_alloc_tokens(newLen);
#endif
aapoint->fs->aapoint_fs
- = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
+ = aapoint->driver_create_fs_state(pipe, &aapoint_fs);
if (aapoint->fs->aapoint_fs == NULL)
goto fail;
bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
{
struct draw_context *draw = aapoint->stage.draw;
+ struct pipe_context *pipe = draw->pipe;
if (!aapoint->fs->aapoint_fs &&
!generate_aapoint_fs(aapoint))
return FALSE;
draw->suspend_flushing = TRUE;
- aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
+ aapoint->driver_bind_fs_state(pipe, aapoint->fs->aapoint_fs);
draw->suspend_flushing = FALSE;
return TRUE;
{
auto struct aapoint_stage *aapoint = aapoint_stage(stage);
struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
+ void *r;
assert(draw->rasterizer->point_smooth);
}
}
+ draw->suspend_flushing = TRUE;
+
+ /* Disable triangle culling, stippling, unfilled mode etc. */
+ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+ pipe->bind_rasterizer_state(pipe, r);
+
+ draw->suspend_flushing = FALSE;
+
/* now really draw first point */
stage->point = aapoint_point;
stage->point(stage, header);
{
struct draw_context *draw = stage->draw;
struct aapoint_stage *aapoint = aapoint_stage(stage);
- struct pipe_context *pipe = aapoint->pipe;
+ 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->driver_fs);
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ }
+
draw->suspend_flushing = FALSE;
draw->extra_shader_outputs.slot = 0;
aafs->state = *fs;
/* pass-through */
- aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
+ aafs->driver_fs = aapoint->driver_create_fs_state(pipe, fs);
return aafs;
}
/* save current */
aapoint->fs = aafs;
/* pass-through */
- aapoint->driver_bind_fs_state(aapoint->pipe,
+ aapoint->driver_bind_fs_state(pipe,
(aafs ? aafs->driver_fs : NULL));
}
struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
/* pass-through */
- aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
+ aapoint->driver_delete_fs_state(pipe, aafs->driver_fs);
if (aafs->aapoint_fs)
- aapoint->driver_delete_fs_state(aapoint->pipe, aafs->aapoint_fs);
+ aapoint->driver_delete_fs_state(pipe, aafs->aapoint_fs);
FREE(aafs);
}
{
struct aapoint_stage *aapoint;
- pipe->draw = (void *) draw;
-
/*
* Create / install AA point drawing / prim stage
*/
if (aapoint == NULL)
return FALSE;
- aapoint->pipe = pipe;
-
/* save original driver functions */
aapoint->driver_create_fs_state = pipe->create_fs_state;
aapoint->driver_bind_fs_state = pipe->bind_fs_state;
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
*/
+#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
}
+static void wideline_first_line( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
+ void *r;
+
+ /* 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;
+
+ stage->line = wideline_line;
+
+ wideline_line(stage, header);
+}
+
+
static void wideline_flush( struct draw_stage *stage, unsigned flags )
{
+ struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+
+ stage->line = wideline_first_line;
stage->next->flush( stage->next, flags );
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ draw->suspend_flushing = TRUE;
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ draw->suspend_flushing = FALSE;
+ }
}
wide->stage.name = "wide-line";
wide->stage.next = NULL;
wide->stage.point = draw_pipe_passthrough_point;
- wide->stage.line = wideline_line;
+ wide->stage.line = wideline_first_line;
wide->stage.tri = draw_pipe_passthrough_tri;
wide->stage.flush = wideline_flush;
wide->stage.reset_stipple_counter = wideline_reset_stipple_counter;
*/
+#include "pipe/p_context.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "pipe/p_defines.h"
{
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 * draw->rasterizer->point_size;
wide->xbias = 0.0;
wide->xbias = 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 ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) ||
(draw->rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)) {
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 );
stage->draw->extra_shader_outputs.slot = 0;
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ draw->suspend_flushing = TRUE;
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ draw->suspend_flushing = FALSE;
+ }
}
*/
struct draw_context
{
+ struct pipe_context *pipe;
+
/** Drawing/primitive pipeline stages */
struct {
struct draw_stage *first; /**< one of the following */
double mrd; /**< minimum resolvable depth value, for polygon offset */
- /* pipe state that we need: */
+ /** Current rasterizer state given to us by the driver */
const struct pipe_rasterizer_state *rasterizer;
+ /** Driver CSO handle for the current rasterizer state */
+ void *rast_handle;
+
+ /** Rasterizer CSOs without culling/stipple/etc */
+ void *rasterizer_no_cull[2][2];
+
struct pipe_viewport_state viewport;
boolean identity_viewport;
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+ boolean scissor,
+ boolean flatshade );
+
#endif /* DRAW_PRIVATE_H */
/*
* Create drawing context and plug our rendering stage into it.
*/
- i915->draw = draw_create();
+ i915->draw = draw_create(&i915->base);
assert(i915->draw);
if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
/* pass-through to draw module */
draw_set_rasterizer_state(i915->draw,
- (i915->rasterizer ? i915->rasterizer->templ : NULL));
+ (i915->rasterizer ? i915->rasterizer->templ : NULL),
+ raster);
i915->dirty |= I915_NEW_RASTERIZER;
}
/*
* Create drawing context and plug our rendering stage into it.
*/
- llvmpipe->draw = draw_create();
+ llvmpipe->draw = draw_create(&llvmpipe->pipe);
if (!llvmpipe->draw)
goto fail;
llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rast)
{
+ /* We do nothing special with rasterizer state.
+ * The CSO handle is just a pointer to a pipe_rasterizer_state object.
+ */
return mem_dup(rast, sizeof(*rast));
}
-void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
- void *rasterizer)
+
+
+void
+llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ const struct pipe_rasterizer_state *rasterizer =
+ (const struct pipe_rasterizer_state *) handle;
if (llvmpipe->rasterizer == rasterizer)
return;
/* pass-through to draw module */
- draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
+ draw_set_rasterizer_state(llvmpipe->draw, rasterizer, handle);
llvmpipe->rasterizer = rasterizer;
llvmpipe->dirty |= LP_NEW_RASTERIZER;
}
+
void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
void *rasterizer)
{
nv50_init_state_functions(nv50);
nv50_init_query_functions(nv50);
- nv50->draw = draw_create();
+ nv50->draw = draw_create(&nv50->pipe);
assert(nv50->draw);
draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
/* Create a Draw. This is used for SW TCL. */
- r300->draw = draw_create();
+ r300->draw = draw_create(&r300->context);
/* Enable our renderer. */
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
/* Enable Draw's clipping. */
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_rasterizer_state(r300->draw, &rs->rs);
+ draw_set_rasterizer_state(r300->draw, &rs->rs, state);
}
if (rs) {
/*
* Create drawing context and plug our rendering stage into it.
*/
- softpipe->draw = draw_create();
+ softpipe->draw = draw_create(&softpipe->pipe);
if (!softpipe->draw)
goto fail;
return;
/* pass-through to draw module */
- draw_set_rasterizer_state(softpipe->draw, rasterizer);
+ draw_set_rasterizer_state(softpipe->draw, rasterizer, rasterizer);
softpipe->rasterizer = rasterizer;
svga->curr.rast = raster;
- draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL);
+ draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL,
+ state);
svga->dirty |= SVGA_NEW_RAST;
}
/*
* Create drawing context and plug our rendering stage into it.
*/
- svga->swtnl.draw = draw_create();
+ svga->swtnl.draw = draw_create(&svga->pipe);
if (svga->swtnl.draw == NULL)
goto fail;
if (dirty & SVGA_NEW_RAST)
draw_set_rasterizer_state(svga->swtnl.draw,
- &svga->curr.rast->templ);
+ &svga->curr.rast->templ,
+ (void *) svga->curr.rast);
if (dirty & SVGA_NEW_FRAME_BUFFER)
draw_set_mrd(svga->swtnl.draw,
_vbo_CreateContext(ctx);
#if FEATURE_feedback || FEATURE_drawpix
- st->draw = draw_create(); /* for selection/feedback */
+ st->draw = draw_create(pipe); /* for selection/feedback */
/* Disable draw options that might convert points/lines to tris, etc.
* as that would foul-up feedback/selection mode.
assert(draw);
draw_set_viewport_state(draw, &st->state.viewport);
draw_set_clip_state(draw, &st->state.clip);
- draw_set_rasterizer_state(draw, &st->state.rasterizer);
+ draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
set_feedback_vertex_format(ctx);