summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-12-09 19:03:10 +0100
committerRoland Scheidegger <[email protected]>2009-12-09 19:03:10 +0100
commita08e348a84f57ed5e8bf5888f1ce13934d2ce8fa (patch)
tree595ffc983588c5441c39ff11c3a089e521f94e53 /src/mesa/state_tracker
parent59f6af51b858340139fe2139e2698fef8a5ad62f (diff)
gallium: first steps to treat edgeflags as regular vertex element
The idea here is to eliminate the set_edgeflags() call in pipe_context by treating edgeflags as a regular vertex element. Edgeflags provoke special treatment in hardware, which means we need to label them in some way, in this case we'll be passing them through the vertex shader and labelling the vertex shader output with a new TGSI semantic (TGSI_SEMANTIC_EDGEFLAG).
Diffstat (limited to 'src/mesa/state_tracker')
-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
5 files changed, 46 insertions, 76 deletions
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;
};