summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c32
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_post_vs.c53
-rw-r--r--src/gallium/include/pipe/p_context.h8
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h3
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c11
-rw-r--r--src/mesa/state_tracker/st_draw.c64
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c13
-rw-r--r--src/mesa/state_tracker/st_program.c32
-rw-r--r--src/mesa/state_tracker/st_program.h2
15 files changed, 111 insertions, 131 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index a4f1fcddc1a..cc5f7f01059 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -366,13 +366,6 @@ void draw_set_render( struct draw_context *draw,
draw->render = render;
}
-void draw_set_edgeflags( struct draw_context *draw,
- const unsigned *edgeflag )
-{
- draw->pt.user.edgeflag = edgeflag;
-}
-
-
/**
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index d529e4e9a27..465b8f10c6c 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -143,9 +143,6 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw,
const void *buffer,
unsigned size );
-void draw_set_edgeflags( struct draw_context *draw,
- const unsigned *edgeflag );
-
/***********************************************************************
* draw_prim.c
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 41fcb16a0a5..0750e6e3797 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -142,8 +142,6 @@ struct draw_context
/* user-space vertex data, buffers */
struct {
- const unsigned *edgeflag;
-
/** vertex element/index buffer (ex: glDrawElements) */
const void *elts;
/** bytes per index (0, 1, 2 or 4) */
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 4865a2d8542..139ae1fe552 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -318,8 +318,10 @@ draw_arrays(struct draw_context *draw, unsigned prim,
boolean draw_pt_get_edgeflag( struct draw_context *draw,
unsigned idx )
{
- if (draw->pt.user.edgeflag)
+ if (draw->pt.user.edgeflag) {
+ float *ef = draw->pt.verted_buffer[idx]
return (draw->pt.user.edgeflag[idx/32] & (1 << (idx%32))) != 0;
+ }
else
return 1;
}
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 7a17a9fb6b2..b5c8c82f4a6 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -149,11 +149,6 @@ struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw );
struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw);
-/* More helpers:
- */
-boolean draw_pt_get_edgeflag( struct draw_context *draw,
- unsigned idx );
-
/*******************************************************************************
* HW vertex emit:
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 65c3a34c347..cb609f8c41e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -120,7 +120,12 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
fetch->translate = translate_cache_find(fetch->cache, &key);
{
- static struct vertex_header vh = { 0, 1, 0, UNDEFINED_VERTEX_ID, { .0f, .0f, .0f, .0f } };
+ static struct vertex_header vh = { 0,
+ 1,
+ 0,
+ UNDEFINED_VERTEX_ID,
+ { .0f, .0f, .0f, .0f } };
+
fetch->translate->set_buffer(fetch->translate,
draw->pt.nr_vertex_buffers,
&vh,
@@ -128,9 +133,6 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
}
}
- fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
- draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) &&
- draw->pt.user.edgeflag);
}
@@ -158,16 +160,10 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
count,
verts );
- /* Edgeflags are hard to fit into a translate program, populate
- * them separately if required. In the setup above they are
- * defaulted to one, so only need this if there is reason to change
- * that default:
+ /* Extract edgeflag values from vertex data into the header.
*/
if (fetch->need_edgeflags) {
- for (i = 0; i < count; i++) {
- struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
- vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] );
- }
+ extract_edge_flags( fetch, count );
}
}
@@ -194,16 +190,12 @@ void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
count,
verts );
- /* Edgeflags are hard to fit into a translate program, populate
- * them separately if required. In the setup above they are
- * defaulted to one, so only need this if there is reason to change
- * that default:
+ /* Extract edgeflag values from vertex data into the header. XXX:
+ * this should be done after the vertex shader is run.
+ * Bypass-vs-and-clip interaction with pipeline???
*/
if (fetch->need_edgeflags) {
- for (i = 0; i < count; i++) {
- struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
- vh->edgeflag = draw_pt_get_edgeflag( draw, start + i );
- }
+ extract_edge_flags( fetch, count );
}
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index df6c265b7ec..d41436858ad 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -86,7 +86,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
(boolean)draw->bypass_clipping,
(boolean)(draw->identity_viewport ||
draw->rasterizer->bypass_vs_clip_and_viewport),
- (boolean)draw->rasterizer->gl_rasterization_rules );
+ (boolean)draw->rasterizer->gl_rasterization_rules,
+ need_edgeflags );
if (!(opt & PT_PIPELINE)) {
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 6c1cb48e8b8..0745b168de2 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -147,6 +147,34 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
+/* As above plus edgeflags
+ */
+static boolean
+post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs,
+ struct vertex_header *vertices,
+ unsigned count,
+ unsigned stride )
+{
+ if (!post_vs_cliptest_viewport_gl( pvs, vertices, count, stride))
+ return FALSE;
+
+ /* If present, copy edgeflag VS output into vertex header.
+ * Otherwise, leave header as is.
+ */
+ if (pvs->draw->vs.edgeflag_output) {
+ struct vertex_header *out = vertices;
+ int ef = pvs->draw->vs.edgeflag_output;
+
+ for (j = 0; j < count; j++) {
+ const float *edgeflag = out->data[ef];
+ out->edgeflag = (edgeflag[0] != 1.0f);
+ }
+ }
+}
+
+
+
+
/* If bypass_clipping is set, skip cliptest and rhw divide.
*/
static boolean post_vs_viewport( struct pt_post_vs *pvs,
@@ -203,15 +231,26 @@ void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
boolean bypass_viewport,
boolean opengl )
{
- if (bypass_clipping) {
- if (bypass_viewport)
- pvs->run = post_vs_none;
- else
- pvs->run = post_vs_viewport;
+ if (!need_edgeflags) {
+ if (bypass_clipping) {
+ if (bypass_viewport)
+ pvs->run = post_vs_none;
+ else
+ pvs->run = post_vs_viewport;
+ }
+ else {
+ /* if (opengl) */
+ pvs->run = post_vs_cliptest_viewport_gl;
+ }
}
else {
- /* if (opengl) */
- pvs->run = post_vs_cliptest_viewport_gl;
+ /* If we need to copy edgeflags to the vertex header, it should
+ * mean we're running the primitive pipeline. Hence the bypass
+ * flags should be false.
+ */
+ assert(!bypass_clipping);
+ assert(!bypass_viewport);
+ pvs->run = post_vs_cliptest_viewport_gl_edgeflag;
}
}
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index f896001eb12..11bcdc0a24c 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -57,14 +57,6 @@ struct pipe_context {
void (*destroy)( struct pipe_context * );
-
- /* Possible interface for setting edgeflags. These aren't really
- * vertex elements, so don't fit there.
- */
- void (*set_edgeflags)( struct pipe_context *,
- const unsigned *bitfield );
-
-
/**
* VBO drawing (return false on fallbacks (temporary??))
*/
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 588ca5e026d..c051d4dae84 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -127,7 +127,8 @@ struct tgsi_declaration_range
#define TGSI_SEMANTIC_GENERIC 5
#define TGSI_SEMANTIC_NORMAL 6
#define TGSI_SEMANTIC_FACE 7
-#define TGSI_SEMANTIC_COUNT 8 /**< number of semantic values */
+#define TGSI_SEMANTIC_EDGEFLAG 8
+#define TGSI_SEMANTIC_COUNT 9 /**< number of semantic values */
struct tgsi_declaration_semantic
{
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 09baff875bc..e209634c904 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -106,7 +106,16 @@ find_translated_vp(struct st_context *st,
/* Nothing in our key yet. This will change:
*/
memset(&key, 0, sizeof key);
- key.dummy = 0;
+
+ /* When this is true, we will add an extra input to the vertex
+ * shader translation (for edgeflags), an extra output with
+ * edgeflag semantics, and extend the vertex shader to pass through
+ * the input to the output. We'll need to use similar logic to set
+ * up the extra vertex_element input for edgeflags.
+ */
+ key.passthrough_edgeflags = (ctx->Polygon.FrontMode != GL_FILL ||
+ ctx->Polygon.BackMode != GL_FILL);
+
/* Do we need to throw away old translations after a change in the
* GL program string?
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index e13ae57a0ec..773a3f17cdd 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -217,59 +217,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
}
-/*
- * If edge flags are needed, setup an bitvector of flags and call
- * pipe->set_edgeflags().
- * XXX memleak: need to free the returned pointer at some point
- */
-static void *
-setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
- const struct gl_client_array *array)
-{
- struct pipe_context *pipe = ctx->st->pipe;
-
- if ((primMode == GL_TRIANGLES ||
- primMode == GL_QUADS ||
- primMode == GL_POLYGON) &&
- (ctx->Polygon.FrontMode != GL_FILL ||
- ctx->Polygon.BackMode != GL_FILL)) {
- /* need edge flags */
- GLint i;
- unsigned *vec;
- struct st_buffer_object *stobj = st_buffer_object(array->BufferObj);
- ubyte *map;
-
- if (!stobj || stobj->Base.Name == 0) {
- /* edge flags are not in a VBO */
- return NULL;
- }
-
- vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32));
- if (!vec)
- return NULL;
-
- map = pipe_buffer_map(pipe->screen, stobj->buffer, PIPE_BUFFER_USAGE_CPU_READ);
- map = ADD_POINTERS(map, array->Ptr);
- for (i = 0; i < count; i++) {
- if (*((float *) map))
- vec[i/32] |= 1 << (i % 32);
-
- map += array->StrideB;
- }
-
- pipe_buffer_unmap(pipe->screen, stobj->buffer);
-
- pipe->set_edgeflags(pipe, vec);
-
- return vec;
- }
- else {
- /* edge flags not needed */
- pipe->set_edgeflags(pipe, NULL);
- return NULL;
- }
-}
/**
@@ -671,10 +619,6 @@ st_draw_vbo(GLcontext *ctx,
* through to driver & draw module. These interfaces still
* need a bit of work...
*/
- setup_edgeflags(ctx, prims[i].mode,
- prims[i].start + indexOffset, prims[i].count,
- arrays[VERT_ATTRIB_EDGEFLAG]);
-
pipe->draw_range_elements(pipe, indexBuf, indexSize,
min_index,
max_index,
@@ -683,10 +627,6 @@ st_draw_vbo(GLcontext *ctx,
}
else {
for (i = 0; i < nr_prims; i++) {
- setup_edgeflags(ctx, prims[i].mode,
- prims[i].start + indexOffset, prims[i].count,
- arrays[VERT_ATTRIB_EDGEFLAG]);
-
pipe->draw_elements(pipe, indexBuf, indexSize,
prims[i].mode,
prims[i].start + indexOffset, prims[i].count);
@@ -699,10 +639,6 @@ st_draw_vbo(GLcontext *ctx,
/* non-indexed */
GLuint i;
for (i = 0; i < nr_prims; i++) {
- setup_edgeflags(ctx, prims[i].mode,
- prims[i].start, prims[i].count,
- arrays[VERT_ATTRIB_EDGEFLAG]);
-
pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count);
}
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 1611d53e2fe..9fd670cac23 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -741,6 +741,7 @@ emit_face_var( struct st_translate *t,
const struct tgsi_token *
st_translate_mesa_program(
GLcontext *ctx,
+ struct ureg_program *ureg;
uint procType,
const struct gl_program *program,
GLuint numInputs,
@@ -754,7 +755,6 @@ st_translate_mesa_program(
const ubyte outputSemanticIndex[] )
{
struct st_translate translate, *t;
- struct ureg_program *ureg;
const struct tgsi_token *tokens = NULL;
unsigned i;
@@ -764,11 +764,7 @@ st_translate_mesa_program(
t->procType = procType;
t->inputMapping = inputMapping;
t->outputMapping = outputMapping;
- t->ureg = ureg_create( procType );
- if (t->ureg == NULL)
- return NULL;
-
- ureg = t->ureg;
+ t->ureg = ureg;
/*_mesa_print_program(program);*/
@@ -899,8 +895,7 @@ st_translate_mesa_program(
t->insn[t->labels[i].branch_target] );
}
- tokens = ureg_get_tokens( ureg, NULL );
- ureg_destroy( ureg );
+ return PIPE_OK;
out:
FREE(t->insn);
@@ -919,7 +914,7 @@ out:
debug_assert(0);
}
- return tokens;
+ return PIPE_ERROR_OUT_OF_MEMORY;
}
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 5c81a033f9c..876d92539e9 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -192,10 +192,16 @@ st_translate_vertex_program(struct st_context *st,
{
struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient);
struct pipe_context *pipe = st->pipe;
+ struct ureg_program *ureg;
- vpv->state.tokens =
+ ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
+
+ error =
st_translate_mesa_program(st->ctx,
TGSI_PROCESSOR_VERTEX,
+ ureg,
&stvp->Base.Base,
/* inputs */
stvp->num_inputs,
@@ -209,6 +215,20 @@ st_translate_vertex_program(struct st_context *st,
stvp->output_semantic_name,
stvp->output_semantic_index );
+ if (ret)
+ goto fail;
+
+ /* Edgeflags will be the last input:
+ */
+ if (key.passthrough_edgeflags) {
+ ureg_MOV( ureg,
+ ureg_DECL_output( ureg, TGSI_SEMANTIC_EDGEFLAG, 0 ),
+ ureg_DECL_next_vs_input(ureg));
+ }
+
+ tokens = ureg_get_tokens( ureg, NULL );
+ ureg_destroy( ureg );
+
vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
@@ -222,6 +242,10 @@ st_translate_vertex_program(struct st_context *st,
}
return vpv;
+
+fail:
+ ureg_destroy( ureg );
+ return NULL;
}
@@ -243,6 +267,7 @@ st_translate_fragment_program(struct st_context *st,
GLuint interpMode[16]; /* XXX size? */
GLuint attr;
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
+ struct ureg_program *ureg;
GLuint vslot = 0;
uint fs_num_inputs = 0;
@@ -377,6 +402,11 @@ st_translate_fragment_program(struct st_context *st,
if (!inputMapping)
inputMapping = defaultInputMapping;
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+
stfp->state.tokens =
st_translate_mesa_program(st->ctx,
TGSI_PROCESSOR_FRAGMENT,
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 88aadbd7510..91392785e55 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -73,7 +73,7 @@ struct st_fragment_program
struct st_vp_varient_key
{
- char dummy; /* currently unused */
+ boolean passthrough_edgeflags;
};