aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe/lp_state_derived.c
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2010-01-06 16:44:43 +0000
committerKeith Whitwell <[email protected]>2010-01-06 16:44:43 +0000
commit5ce0380a0f585b9e1fb616b749f7fd18a8afada1 (patch)
tree0c7ba3835c94a8fe7c9c392c387209a3f5350a21 /src/gallium/drivers/llvmpipe/lp_state_derived.c
parent6a7b6a530dd7740457d4bdd3b804c6eabff4e1b3 (diff)
llvmpipe: merge setup and draw vbuf submodules
The setup tiling engine is now plugged directly into the draw module as a rendering backend. Removed a couple of layering violations such that the setup code no longer reaches out into the surrounding llvmpipe state or context.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_state_derived.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c223
1 files changed, 72 insertions, 151 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index a18efcc0e0f..ab827045ed6 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -37,17 +37,6 @@
#include "lp_state.h"
-/**
- * Mark the current vertex layout as "invalid".
- * We'll validate the vertex layout later, when we start to actually
- * render a point or line or tri.
- */
-static void
-invalidate_vertex_layout(struct llvmpipe_context *llvmpipe)
-{
- llvmpipe->vertex_info.num_attribs = 0;
-}
-
/**
* The vertex info describes how to convert the post-transformed vertices
@@ -57,150 +46,95 @@ invalidate_vertex_layout(struct llvmpipe_context *llvmpipe)
* This function validates the vertex layout and returns a pointer to a
* vertex_info object.
*/
-struct vertex_info *
-llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
+static void
+compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
- struct vertex_info *vinfo = &llvmpipe->vertex_info;
-
- if (vinfo->num_attribs == 0) {
- /* compute vertex layout now */
- const struct lp_fragment_shader *lpfs = llvmpipe->fs;
- const enum interp_mode colorInterp
- = llvmpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
- struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
- const uint num = draw_num_vs_outputs(llvmpipe->draw);
- uint i;
-
- /* Tell draw_vbuf to simply emit the whole post-xform vertex
- * as-is. No longer any need to try and emit draw vertex_header
- * info.
- */
- vinfo_vbuf->num_attribs = 0;
- for (i = 0; i < num; i++) {
- draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
- }
- draw_compute_vertex_size(vinfo_vbuf);
+ const struct lp_fragment_shader *lpfs = llvmpipe->fs;
+ struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
+ const uint num = draw_num_vs_outputs(llvmpipe->draw);
+ uint i;
+
+ /* Tell draw_vbuf to simply emit the whole post-xform vertex as-is.
+ *
+ * Not really sure if this is the best approach.
+ */
+ vinfo_vbuf->num_attribs = 0;
+ for (i = 0; i < num; i++) {
+ draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
+ }
+ draw_compute_vertex_size(vinfo_vbuf);
- /*
- * Loop over fragment shader inputs, searching for the matching output
- * from the vertex shader.
- */
- vinfo->num_attribs = 0;
- for (i = 0; i < lpfs->info.num_inputs; i++) {
- int src;
- enum interp_mode interp;
- switch (lpfs->info.input_interpolate[i]) {
- case TGSI_INTERPOLATE_CONSTANT:
- interp = INTERP_CONSTANT;
- break;
- case TGSI_INTERPOLATE_LINEAR:
- interp = INTERP_LINEAR;
- break;
- case TGSI_INTERPOLATE_PERSPECTIVE:
- interp = INTERP_PERSPECTIVE;
- break;
- default:
- assert(0);
- interp = INTERP_LINEAR;
- }
+ lp_setup_set_vertex_info(llvmpipe->setup, vinfo_vbuf);
- switch (lpfs->info.input_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- src = draw_find_vs_output(llvmpipe->draw,
- TGSI_SEMANTIC_POSITION, 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
- break;
+/*
+ llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
+ TGSI_SEMANTIC_PSIZE, 0);
+*/
- case TGSI_SEMANTIC_COLOR:
- src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_COLOR,
- lpfs->info.input_semantic_index[i]);
- draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
- break;
+ /* Now match FS inputs against emitted vertex data. It's also
+ * entirely possible to just have a fixed layout for FS input,
+ * determined by the fragment shader itself, and adjust the draw
+ * outputs to match that.
+ */
+ {
+ struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
- case TGSI_SEMANTIC_FOG:
- src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
- break;
+ for (i = 0; i < lpfs->info.num_inputs; i++) {
- case TGSI_SEMANTIC_GENERIC:
+ /* This can be precomputed, except for flatshade:
+ */
+ switch (lpfs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_FACE:
- /* this includes texcoords and varying vars */
- src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_GENERIC,
- lpfs->info.input_semantic_index[i]);
- draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
+ inputs[i].interp = LP_INTERP_FACING;
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ inputs[i].interp = LP_INTERP_POSITION;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ /* Colors are linearly interpolated in the fragment shader
+ * even when flatshading is active. This just tells the
+ * setup module to use coefficients with ddx==0 and
+ * ddy==0.
+ */
+ if (llvmpipe->rasterizer->flatshade)
+ inputs[i].interp = LP_INTERP_CONSTANT;
+ else
+ inputs[i].interp = LP_INTERP_LINEAR;
break;
default:
- assert(0);
- }
- }
-
- llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
- TGSI_SEMANTIC_PSIZE, 0);
- if (llvmpipe->psize_slot > 0) {
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
- llvmpipe->psize_slot);
- }
-
- draw_compute_vertex_size(vinfo);
-
- {
- struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
-
- for (i = 0; i < lpfs->info.num_inputs; i++) {
- switch (vinfo->attrib[i].interp_mode) {
- case INTERP_CONSTANT:
+ switch (lpfs->info.input_interpolate[i]) {
+ case TGSI_INTERPOLATE_CONSTANT:
inputs[i].interp = LP_INTERP_CONSTANT;
break;
- case INTERP_LINEAR:
+ case TGSI_INTERPOLATE_LINEAR:
inputs[i].interp = LP_INTERP_LINEAR;
break;
- case INTERP_PERSPECTIVE:
+ case TGSI_INTERPOLATE_PERSPECTIVE:
inputs[i].interp = LP_INTERP_PERSPECTIVE;
break;
- case INTERP_POS:
- inputs[i].interp = LP_INTERP_POSITION;
- break;
default:
assert(0);
+ break;
}
-
- if (lpfs->info.input_semantic_name[i] == TGSI_SEMANTIC_FACE)
- inputs[i].interp = LP_INTERP_FACING;
-
- inputs[i].src_index = vinfo->attrib[i].src_index;
}
- lp_setup_set_fs_inputs(llvmpipe->setup, inputs, lpfs->info.num_inputs);
+ /* Search for each input in current vs output:
+ */
+ inputs[i].src_index =
+ draw_find_vs_output(llvmpipe->draw,
+ lpfs->info.input_semantic_name[i],
+ lpfs->info.input_semantic_index[i]);
}
- }
- return vinfo;
+ lp_setup_set_fs_inputs(llvmpipe->setup,
+ inputs,
+ lpfs->info.num_inputs);
+ }
}
-/**
- * Called from vbuf module.
- *
- * Note that there's actually two different vertex layouts in llvmpipe.
- *
- * The normal one is computed in llvmpipe_get_vertex_info() above and is
- * used by the point/line/tri "setup" code.
- *
- * The other one (this one) is only used by the vbuf module (which is
- * not normally used by default but used in testing). For the vbuf module,
- * we basically want to pass-through the draw module's vertex layout as-is.
- * When the llvmpipe vbuf code begins drawing, the normal vertex layout
- * will come into play again.
- */
-struct vertex_info *
-llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe)
-{
- (void) llvmpipe_get_vertex_info(llvmpipe);
- return &llvmpipe->vertex_info_vbuf;
-}
-
/**
* Recompute cliprect from scissor bounds, scissor enable and surface size.
@@ -273,7 +207,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
if (llvmpipe->dirty & (LP_NEW_RASTERIZER |
LP_NEW_FS |
LP_NEW_VS))
- invalidate_vertex_layout( llvmpipe );
+ compute_vertex_info( llvmpipe );
if (llvmpipe->dirty & (LP_NEW_SCISSOR |
LP_NEW_RASTERIZER |
@@ -287,36 +221,23 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
LP_NEW_TEXTURE))
llvmpipe_update_fs( llvmpipe );
- if (llvmpipe->dirty & (LP_NEW_BLEND |
- LP_NEW_DEPTH_STENCIL_ALPHA |
- LP_NEW_SAMPLER |
- LP_NEW_TEXTURE))
- llvmpipe_update_fs( llvmpipe );
-
if (llvmpipe->dirty & LP_NEW_BLEND_COLOR)
- lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color);
+ lp_setup_set_blend_color(llvmpipe->setup,
+ &llvmpipe->blend_color);
if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA)
- lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value);
+ lp_setup_set_alpha_ref_value(llvmpipe->setup,
+ llvmpipe->depth_stencil->alpha.ref_value);
if (llvmpipe->dirty & LP_NEW_CONSTANTS)
- lp_setup_set_fs_constants(llvmpipe->setup, llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer);
+ lp_setup_set_fs_constants(llvmpipe->setup,
+ llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer);
if (llvmpipe->dirty & LP_NEW_TEXTURE)
- lp_setup_set_sampler_textures(llvmpipe->setup, llvmpipe->num_textures, llvmpipe->texture);
+ lp_setup_set_sampler_textures(llvmpipe->setup,
+ llvmpipe->num_textures,
+ llvmpipe->texture);
llvmpipe->dirty = 0;
}
-
-#if 0
-void llvmpipe_prepare(struct lp_setup_context *setup)
-{
- struct llvmpipe_context *lp = setup->llvmpipe;
-
- if (lp->dirty) {
- llvmpipe_update_derived(lp);
- }
-
-}
-#endif