*/
+#include "pipe/p_context.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "draw_context.h"
#include "draw_vs.h"
#include "draw_gs.h"
+#if HAVE_LLVM
+#include "gallivm/lp_bld_init.h"
+#endif
-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)
goto fail;
+#if HAVE_LLVM
+ assert(lp_build_engine);
+ draw->engine = lp_build_engine;
+#endif
+
if (!draw_init(draw))
goto fail;
+ draw->pipe = pipe;
+
return draw;
fail:
void draw_destroy( struct draw_context *draw )
{
+ struct pipe_context *pipe;
+ int i, j;
+
if (!draw)
return;
+ pipe = draw->pipe;
+ /* 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;
+ }
}
void
draw_set_mapped_element_buffer_range( struct draw_context *draw,
unsigned eltSize,
+ int eltBias,
unsigned min_index,
unsigned max_index,
const void *elements )
{
draw->pt.user.elts = elements;
draw->pt.user.eltSize = eltSize;
+ draw->pt.user.eltBias = eltBias;
draw->pt.user.min_index = min_index;
draw->pt.user.max_index = max_index;
}
void
draw_set_mapped_element_buffer( struct draw_context *draw,
unsigned eltSize,
+ int eltBias,
const void *elements )
{
draw->pt.user.elts = elements;
draw->pt.user.eltSize = eltSize;
+ draw->pt.user.eltBias = eltBias;
draw->pt.user.min_index = 0;
draw->pt.user.max_index = 0xffffffff;
}
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
draw_set_mapped_element_buffer_range( struct draw_context *draw,
unsigned eltSize,
+ int eltBias,
unsigned min_index,
unsigned max_index,
const void *elements );
void draw_set_mapped_element_buffer( struct draw_context *draw,
unsigned eltSize,
+ int eltBias,
const void *elements );
void draw_set_mapped_vertex_buffer(struct draw_context *draw,
const struct pipe_rasterizer_state *rasterizer,
unsigned prim );
-#ifdef HAVE_LLVM
-/*******************************************************************************
- * LLVM integration
- */
-struct draw_context *draw_create_with_llvm(void);
-#endif
-
#endif /* DRAW_CONTEXT_H */
*/
struct draw_context
{
+ struct pipe_context *pipe;
+
/** Drawing/primitive pipeline stages */
struct {
struct draw_stage *first; /**< one of the following */
const void *elts;
/** bytes per index (0, 1, 2 or 4) */
unsigned eltSize;
+ int eltBias;
unsigned min_index;
unsigned max_index;
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;
#ifdef HAVE_LLVM
LLVMExecutionEngineRef engine;
+ boolean use_llvm;
#endif
void *driver_private;
};
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+ boolean scissor,
+ boolean flatshade );
+
#endif /* DRAW_PRIVATE_H */
frontend->run(frontend,
draw_pt_elt_func(draw),
draw_pt_elt_ptr(draw, start),
+ draw->pt.user.eltBias,
count);
frontend->finish( frontend );
return FALSE;
#if HAVE_LLVM
- draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit_llvm( draw );
+ draw->use_llvm = debug_get_bool_option("DRAW_USE_LLVM", TRUE);
+ if (draw->use_llvm)
+ draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit_llvm( draw );
#else
draw->pt.middle.general = NULL;
#endif
break;
default:
assert(0);
+ return;
}
- debug_printf("Element[%u + %u] -> Vertex %u:\n", start, i, ii);
+ ii += draw->pt.user.eltBias;
+ debug_printf("Element[%u + %u] + %i -> Vertex %u:\n", start, i,
+ draw->pt.user.eltBias, ii);
}
else {
/* non-indexed arrays */
i915_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
+ int indexBias,
unsigned min_index,
unsigned max_index,
unsigned prim, unsigned start, unsigned count)
*/
if (indexBuffer) {
void *mapped_indexes = i915_buffer(indexBuffer)->data;
- draw_set_mapped_element_buffer_range(draw, indexSize,
+ draw_set_mapped_element_buffer_range(draw, indexSize, indexBias,
min_index,
max_index,
mapped_indexes);
} else {
- draw_set_mapped_element_buffer(draw, 0, NULL);
+ draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}
if (indexBuffer) {
- draw_set_mapped_element_buffer(draw, 0, NULL);
+ draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}
static void
i915_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
- unsigned indexSize,
+ unsigned indexSize, int indexBias,
unsigned prim, unsigned start, unsigned count)
{
i915_draw_range_elements(pipe, indexBuffer,
- indexSize,
+ indexSize, indexBias,
0, 0xffffffff,
prim, start, count);
}
i915_draw_arrays(struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
{
- i915_draw_elements(pipe, NULL, 0, prim, start, count);
+ i915_draw_elements(pipe, NULL, 0, 0, prim, start, count);
}
/*
* 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));
struct pipe_transfer *transfer;
struct nouveau_channel* chan = nvfx->screen->base.channel;
void *map;
+ float *v;
map = pipe_buffer_map(&nvfx->pipe, vb->buffer, PIPE_TRANSFER_READ, &transfer);
- map += vb->buffer_offset + ve->src_offset;
+ map = (uint8_t *) map + vb->buffer_offset + ve->src_offset;
- float *v = map;
+ v = map;
switch (ncomp) {
case 4:
nvfx_vbo_set_idxbuf(nvfx, NULL, 0);
if (nvfx->screen->force_swtnl || !nvfx_state_validate(nvfx)) {
- nvfx_draw_elements_swtnl(pipe, NULL, 0,
+ nvfx_draw_elements_swtnl(pipe, NULL, 0, 0,
mode, start, count);
return;
}
while (count) {
- unsigned vc, nr;
+ unsigned vc, nr, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 256,
while (count) {
uint8_t *elts = (uint8_t *)ib + start;
- unsigned vc, push, restart = 0;
+ unsigned vc, push, restart = 0, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 2,
while (count) {
uint16_t *elts = (uint16_t *)ib + start;
- unsigned vc, push, restart = 0;
+ unsigned vc, push, restart = 0, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 2,
while (count) {
uint32_t *elts = (uint32_t *)ib + start;
- unsigned vc, push, restart = 0;
+ unsigned vc, push, restart = 0, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 5, 1,
static void
nvfx_draw_elements_inline(struct pipe_context *pipe,
- struct pipe_resource *ib, unsigned ib_size,
+ struct pipe_resource *ib,
+ unsigned ib_size, int ib_bias,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
return;
}
+ assert(ib_bias == 0);
+
switch (ib_size) {
case 1:
nvfx_draw_elements_u08(nvfx, map, mode, start, count);
unsigned restart = 0;
while (count) {
- unsigned nr, vc;
+ unsigned nr, vc, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 256,
void
nvfx_draw_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer, unsigned indexSize,
+ struct pipe_resource *indexBuffer,
+ unsigned indexSize, int indexBias,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
idxbuf = nvfx_vbo_set_idxbuf(nvfx, indexBuffer, indexSize);
if (nvfx->screen->force_swtnl || !nvfx_state_validate(nvfx)) {
- nvfx_draw_elements_swtnl(pipe, indexBuffer, indexSize,
- mode, start, count);
+ nvfx_draw_elements_swtnl(pipe,
+ indexBuffer, indexSize, indexBias,
+ mode, start, count);
return;
}
if (idxbuf) {
nvfx_draw_elements_vbo(pipe, mode, start, count);
} else {
- nvfx_draw_elements_inline(pipe, indexBuffer, indexSize,
+ nvfx_draw_elements_inline(pipe,
+ indexBuffer, indexSize, indexBias,
mode, start, count);
}
if (!checked[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
- if (r300->context.is_resource_referenced(&r300->context,
- vbuf->buffer,
- 0, 0)) {
+ if (r300_buffer_is_referenced(&r300->context,
+ vbuf->buffer,
+ R300_REF_CS | R300_REF_HW)) {
/* It's a very bad idea to map it... */
return FALSE;
}
void r500_emit_draw_elements(struct r300_context *r300,
struct pipe_resource* indexBuffer,
unsigned indexSize,
+ int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
return;
}
+ assert(indexBias == 0);
+
maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
void r300_emit_draw_elements(struct r300_context *r300,
struct pipe_resource* indexBuffer,
unsigned indexSize,
+ int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
unsigned count)
{
if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
- maxIndex, mode, start, count);
+ r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
} else {
r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
- maxIndex, mode, start, count);
+ r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
r300_switch_stencil_ref_side(r300);
- r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
- maxIndex, mode, start, count);
+ r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
r300_end_stencil_ref_fallback(r300);
}
}
void r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_resource* indexBuffer,
unsigned indexSize,
+ int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
u_upload_flush(r300->upload_vb);
u_upload_flush(r300->upload_ib);
if (alt_num_verts || count <= 65535) {
- r300->emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
- maxIndex, mode, start, count);
+ r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
} else {
do {
short_count = MIN2(count, 65534);
- r300->emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
- maxIndex, mode, start, short_count);
+ r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex,
+ mode, start, short_count);
start += short_count;
count -= short_count;
/* Simple helpers for context setup. Should probably be moved to util. */
void r300_draw_elements(struct pipe_context* pipe,
struct pipe_resource* indexBuffer,
- unsigned indexSize, unsigned mode,
+ unsigned indexSize, int indexBias, unsigned mode,
unsigned start, unsigned count)
{
struct r300_context *r300 = r300_context(pipe);
- pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0,
- r300->vertex_buffer_max_index,
+ pipe->draw_range_elements(pipe, indexBuffer, indexSize, indexBias,
+ 0, r300->vertex_buffer_max_index,
mode, start, count);
}
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
}
- draw_set_mapped_element_buffer(r300->draw, 0, NULL);
+ draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL);
draw_arrays(r300->draw, mode, start, count);
void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
struct pipe_resource* indexBuffer,
unsigned indexSize,
+ int indexBias,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
indices = pipe_buffer_map(pipe, indexBuffer,
PIPE_TRANSFER_READ, &ib_transfer);
- draw_set_mapped_element_buffer_range(r300->draw, indexSize,
+ draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias,
minIndex, maxIndex, indices);
draw_arrays(r300->draw, mode, start, count);
pipe_buffer_unmap(pipe, indexBuffer,
ib_transfer);
- draw_set_mapped_element_buffer_range(r300->draw, 0, start,
- start + count - 1, NULL);
+ draw_set_mapped_element_buffer_range(r300->draw, 0, 0,
+ start, start + count - 1,
+ NULL);
}
/* Object for rendering using Draw. */
svga_swtnl_draw_range_elements(struct svga_context *svga,
struct pipe_resource *indexBuffer,
unsigned indexSize,
+ int indexBias,
unsigned min_index,
unsigned max_index,
unsigned prim, unsigned start, unsigned count)
&ib_transfer);
draw_set_mapped_element_buffer_range(draw,
- indexSize,
+ indexSize, indexBias,
min_index,
max_index,
map);
if (indexBuffer) {
pipe_buffer_unmap(&svga->pipe, indexBuffer, ib_transfer);
- draw_set_mapped_element_buffer(draw, 0, NULL);
+ draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
/*
* 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;
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);
map = pipe_buffer_map(pipe, index_buffer_handle,
PIPE_TRANSFER_READ, &ib_transfer);
- draw_set_mapped_element_buffer(draw, indexSize, map);
+ draw_set_mapped_element_buffer(draw, indexSize, 0, map);
}
else {
- draw_set_mapped_element_buffer(draw, indexSize, (void *) ib->ptr);
+ draw_set_mapped_element_buffer(draw, indexSize, 0, (void *) ib->ptr);
ib_transfer = NULL;
}
}
else {
/* no index/element buffer */
- draw_set_mapped_element_buffer(draw, 0, NULL);
+ draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}
if (index_buffer_handle) {
pipe_buffer_unmap(pipe, index_buffer_handle, ib_transfer);
- draw_set_mapped_element_buffer(draw, 0, NULL);
+ draw_set_mapped_element_buffer(draw, 0, 0, NULL);
}
}