gallium: rearrange vertex info/layout validation
Delay validation until someone really needs the vertex layout (vbuf alloc vertex buffer or point/line/tri setup/rendering). This will allow the vertex size to change depending on whether we're drawing points, lines or triangles.
This commit is contained in:
@@ -499,7 +499,7 @@ setup_fragcoord_coeff(struct setup_stage *setup)
|
||||
setup->coef[0].a0[2] = setup->posCoef.a0[2];
|
||||
setup->coef[0].dadx[2] = setup->posCoef.dadx[2];
|
||||
setup->coef[0].dady[2] = setup->posCoef.dady[2];
|
||||
/*w*/
|
||||
/*W*/
|
||||
setup->coef[0].a0[3] = setup->posCoef.a0[3];
|
||||
setup->coef[0].dadx[3] = setup->posCoef.dadx[3];
|
||||
setup->coef[0].dady[3] = setup->posCoef.dady[3];
|
||||
@@ -513,8 +513,9 @@ setup_fragcoord_coeff(struct setup_stage *setup)
|
||||
*/
|
||||
static void setup_tri_coefficients( struct setup_stage *setup )
|
||||
{
|
||||
const struct softpipe_context *softpipe = setup->softpipe;
|
||||
struct softpipe_context *softpipe = setup->softpipe;
|
||||
const struct pipe_shader_state *fs = &softpipe->fs->shader;
|
||||
const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
|
||||
uint fragSlot;
|
||||
|
||||
/* z and w are done by linear interpolation:
|
||||
@@ -525,10 +526,10 @@ static void setup_tri_coefficients( struct setup_stage *setup )
|
||||
/* setup interpolation for all the remaining attributes:
|
||||
*/
|
||||
for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
|
||||
const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
|
||||
const uint vertSlot = vinfo->src_index[fragSlot];
|
||||
uint j;
|
||||
|
||||
switch (softpipe->vertex_info.interp_mode[fragSlot]) {
|
||||
switch (vinfo->interp_mode[fragSlot]) {
|
||||
case INTERP_CONSTANT:
|
||||
for (j = 0; j < NUM_CHANNELS; j++)
|
||||
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
|
||||
@@ -756,8 +757,9 @@ line_persp_coeff(struct setup_stage *setup,
|
||||
static INLINE void
|
||||
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
|
||||
{
|
||||
const struct softpipe_context *softpipe = setup->softpipe;
|
||||
struct softpipe_context *softpipe = setup->softpipe;
|
||||
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
|
||||
const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
|
||||
uint fragSlot;
|
||||
|
||||
/* use setup->vmin, vmax to point to vertices */
|
||||
@@ -779,10 +781,10 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
|
||||
/* setup interpolation for all the remaining attributes:
|
||||
*/
|
||||
for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
|
||||
const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
|
||||
const uint vertSlot = vinfo->src_index[fragSlot];
|
||||
uint j;
|
||||
|
||||
switch (softpipe->vertex_info.interp_mode[fragSlot]) {
|
||||
switch (vinfo->interp_mode[fragSlot]) {
|
||||
case INTERP_CONSTANT:
|
||||
for (j = 0; j < NUM_CHANNELS; j++)
|
||||
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
|
||||
@@ -978,6 +980,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
|
||||
const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth;
|
||||
const float x = v0->data[0][0]; /* Note: data[0] is always position */
|
||||
const float y = v0->data[0][1];
|
||||
const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
|
||||
uint fragSlot;
|
||||
|
||||
/* For points, all interpolants are constant-valued.
|
||||
@@ -1003,10 +1006,10 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
|
||||
const_coeff(setup, &setup->posCoef, 0, 3);
|
||||
|
||||
for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
|
||||
const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
|
||||
const uint vertSlot = vinfo->src_index[fragSlot];
|
||||
uint j;
|
||||
|
||||
switch (softpipe->vertex_info.interp_mode[fragSlot]) {
|
||||
switch (vinfo->interp_mode[fragSlot]) {
|
||||
case INTERP_CONSTANT:
|
||||
/* fall-through */
|
||||
case INTERP_LINEAR:
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_prim_vbuf.h"
|
||||
#include "pipe/draw/draw_context.h"
|
||||
#include "pipe/draw/draw_private.h"
|
||||
@@ -73,9 +74,7 @@ static const struct vertex_info *
|
||||
sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
|
||||
{
|
||||
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
|
||||
/* XXX check for state changes? */
|
||||
assert(!cvbr->softpipe->dirty );
|
||||
return &cvbr->softpipe->vertex_info_vbuf;
|
||||
return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ struct gallivm_prog;
|
||||
#endif
|
||||
|
||||
|
||||
struct vertex_info;
|
||||
|
||||
|
||||
/** Subclass of pipe_shader_state */
|
||||
struct sp_fragment_shader_state {
|
||||
@@ -174,4 +176,12 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp);
|
||||
void
|
||||
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
|
||||
|
||||
|
||||
struct vertex_info *
|
||||
softpipe_get_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
struct vertex_info *
|
||||
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,82 +49,128 @@ find_vs_output(const struct pipe_shader_state *vs,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 softpipe_context *softpipe)
|
||||
{
|
||||
softpipe->vertex_info.num_attribs = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine how to map vertex program outputs to fragment program inputs.
|
||||
* Basically, this will be used when computing the triangle interpolation
|
||||
* coefficients from the post-transform vertex attributes.
|
||||
* The vertex info describes how to convert the post-transformed vertices
|
||||
* (simple float[][4]) used by the 'draw' module into vertices for
|
||||
* rasterization.
|
||||
*
|
||||
* This function validates the vertex layout and returns a pointer to a
|
||||
* vertex_info object.
|
||||
*/
|
||||
static void calculate_vertex_layout( struct softpipe_context *softpipe )
|
||||
struct vertex_info *
|
||||
softpipe_get_vertex_info(struct softpipe_context *softpipe)
|
||||
{
|
||||
const struct pipe_shader_state *vs = &softpipe->vs->shader;
|
||||
const struct pipe_shader_state *fs = &softpipe->fs->shader;
|
||||
const enum interp_mode colorInterp
|
||||
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
|
||||
struct vertex_info *vinfo = &softpipe->vertex_info;
|
||||
uint i;
|
||||
|
||||
if (softpipe->vbuf) {
|
||||
/* if using the post-transform vertex buffer, tell draw_vbuf to
|
||||
* simply emit the whole post-xform vertex as-is:
|
||||
*/
|
||||
struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
|
||||
vinfo_vbuf->num_attribs = 0;
|
||||
draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
|
||||
vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4;
|
||||
}
|
||||
if (vinfo->num_attribs == 0) {
|
||||
/* compute vertex layout now */
|
||||
const struct pipe_shader_state *vs = &softpipe->vs->shader;
|
||||
const struct pipe_shader_state *fs = &softpipe->fs->shader;
|
||||
const enum interp_mode colorInterp
|
||||
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
|
||||
uint i;
|
||||
|
||||
/*
|
||||
* Loop over fragment shader inputs, searching for the matching output
|
||||
* from the vertex shader.
|
||||
*/
|
||||
vinfo->num_attribs = 0;
|
||||
for (i = 0; i < fs->num_inputs; i++) {
|
||||
int src;
|
||||
switch (fs->input_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
|
||||
fs->input_semantic_index[i]);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
|
||||
#if 1
|
||||
if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
|
||||
src = 0;
|
||||
#endif
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
/* this includes texcoords and varying vars */
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
|
||||
fs->input_semantic_index[i]);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
if (softpipe->vbuf) {
|
||||
/* if using the post-transform vertex buffer, tell draw_vbuf to
|
||||
* simply emit the whole post-xform vertex as-is:
|
||||
*/
|
||||
struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
|
||||
vinfo_vbuf->num_attribs = 0;
|
||||
draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
|
||||
vinfo_vbuf->size = 4 * vs->num_outputs
|
||||
+ sizeof(struct vertex_header) / 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop over fragment shader inputs, searching for the matching output
|
||||
* from the vertex shader.
|
||||
*/
|
||||
vinfo->num_attribs = 0;
|
||||
for (i = 0; i < fs->num_inputs; i++) {
|
||||
int src;
|
||||
switch (fs->input_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
|
||||
fs->input_semantic_index[i]);
|
||||
if (src < 0)
|
||||
src = 0;
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
|
||||
#if 1
|
||||
if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
|
||||
src = 0;
|
||||
#endif
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
/* this includes texcoords and varying vars */
|
||||
src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
|
||||
fs->input_semantic_index[i]);
|
||||
assert(src >= 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
|
||||
if (softpipe->psize_slot >= 0) {
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
|
||||
softpipe->psize_slot);
|
||||
}
|
||||
|
||||
draw_compute_vertex_size(vinfo);
|
||||
}
|
||||
|
||||
softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
|
||||
if (softpipe->psize_slot >= 0) {
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
|
||||
softpipe->psize_slot);
|
||||
}
|
||||
return vinfo;
|
||||
}
|
||||
|
||||
draw_compute_vertex_size(vinfo);
|
||||
|
||||
/**
|
||||
* Called from vbuf module.
|
||||
*
|
||||
* Note that there's actually two different vertex layouts in softpipe.
|
||||
*
|
||||
* The normal one is computed in softpipe_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 softpipe vbuf code begins drawing, the normal vertex layout
|
||||
* will come into play again.
|
||||
*/
|
||||
struct vertex_info *
|
||||
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
|
||||
{
|
||||
(void) softpipe_get_vertex_info(softpipe);
|
||||
return &softpipe->vertex_info_vbuf;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +217,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe )
|
||||
if (softpipe->dirty & (SP_NEW_RASTERIZER |
|
||||
SP_NEW_FS |
|
||||
SP_NEW_VS))
|
||||
calculate_vertex_layout( softpipe );
|
||||
invalidate_vertex_layout( softpipe );
|
||||
|
||||
if (softpipe->dirty & (SP_NEW_SCISSOR |
|
||||
SP_NEW_DEPTH_STENCIL_ALPHA |
|
||||
|
||||
Reference in New Issue
Block a user