Merge branch 'softpipe_0_1_branch' of git+ssh://brianp@git.freedesktop.org/git/mesa/mesa into softpipe_0_1_branch
This commit is contained in:
@@ -51,6 +51,7 @@ struct xm_softpipe_winsys
|
||||
struct xm_buffer
|
||||
{
|
||||
int refcount;
|
||||
int size;
|
||||
void *data;
|
||||
void *mapped;
|
||||
};
|
||||
@@ -129,8 +130,12 @@ xm_buffer_data(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
|
||||
unsigned size, const void *data )
|
||||
{
|
||||
struct xm_buffer *xm_buf = xm_bo(buf);
|
||||
assert(!xm_buf->data);
|
||||
xm_buf->data = malloc(size);
|
||||
if (xm_buf->size != size) {
|
||||
if (xm_buf->data)
|
||||
free(xm_buf->data);
|
||||
xm_buf->data = malloc(size);
|
||||
xm_buf->size = size;
|
||||
}
|
||||
if (data)
|
||||
memcpy(xm_buf->data, data, size);
|
||||
}
|
||||
|
||||
@@ -201,13 +201,3 @@ void draw_set_viewport_state( struct draw_context *draw,
|
||||
* Full pipe will have vertex shader, vertex fetch of its own.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void draw_set_vertex_array_info(struct draw_context *draw,
|
||||
const struct pipe_vertex_buffer *buffers,
|
||||
const struct pipe_vertex_element *elements)
|
||||
{
|
||||
draw->vertex_buffer = buffers;
|
||||
draw->vertex_element = elements;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,10 +98,6 @@ void draw_set_vertex_attributes2( struct draw_context *draw,
|
||||
const unsigned *attrs,
|
||||
unsigned nr_attrs );
|
||||
|
||||
void draw_set_vertex_array_info(struct draw_context *draw,
|
||||
const struct pipe_vertex_buffer *buffers,
|
||||
const struct pipe_vertex_element *elements);
|
||||
|
||||
/* XXX temporary */
|
||||
void draw_vb(struct draw_context *draw,
|
||||
struct vertex_buffer *VB );
|
||||
|
||||
@@ -258,8 +258,10 @@ static void do_quad( struct draw_context *draw,
|
||||
unsigned v2,
|
||||
unsigned v3 )
|
||||
{
|
||||
do_ef_triangle( draw, 1, ~(1<<0), v0, v1, v3 );
|
||||
do_ef_triangle( draw, 0, ~(1<<1), v1, v2, v3 );
|
||||
const unsigned omitEdge2 = ~(1 << 1);
|
||||
const unsigned omitEdge3 = ~(1 << 2);
|
||||
do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 );
|
||||
do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -158,8 +158,6 @@ struct draw_context
|
||||
/* pipe state that we need: */
|
||||
struct pipe_setup_state setup;
|
||||
struct pipe_viewport_state viewport;
|
||||
const struct pipe_vertex_buffer *vertex_buffer; /**< note: pointer */
|
||||
const struct pipe_vertex_element *vertex_element; /**< note: pointer */
|
||||
|
||||
/** need to know the pipe for vertex flushing/transformation: */
|
||||
struct pipe_context *pipe;
|
||||
@@ -230,9 +228,6 @@ struct draw_context
|
||||
ubyte *verts;
|
||||
boolean in_vb;
|
||||
struct vertex_fetch *vf;
|
||||
|
||||
/* Misc for sp_draw_arrays.c (temporary?) */
|
||||
void *mapped_vbuffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -322,10 +322,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
|
||||
assert(softpipe->draw);
|
||||
draw_set_setup_stage(softpipe->draw, sp_draw_render_stage(softpipe));
|
||||
|
||||
draw_set_vertex_array_info(softpipe->draw,
|
||||
softpipe->vertex_buffer,
|
||||
softpipe->vertex_element);
|
||||
|
||||
sp_init_region_functions(softpipe);
|
||||
sp_init_surface_functions(softpipe);
|
||||
|
||||
|
||||
@@ -101,6 +101,11 @@ struct softpipe_context {
|
||||
*/
|
||||
enum interp_mode interp[PIPE_ATTRIB_MAX];
|
||||
|
||||
/*
|
||||
* Mapped vertex buffers
|
||||
*/
|
||||
ubyte *mapped_vbuffer[PIPE_ATTRIB_MAX];
|
||||
|
||||
|
||||
/* FS + setup derived state:
|
||||
*/
|
||||
|
||||
@@ -87,6 +87,36 @@ compute_clipmask(float cx, float cy, float cz, float cw)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch a float[4] vertex attribute from memory, doing format/type
|
||||
* conversion as needed.
|
||||
* XXX this might be a temporary thing.
|
||||
*/
|
||||
static void
|
||||
fetch_attrib4(const void *ptr, unsigned format, float attrib[4])
|
||||
{
|
||||
/* defaults */
|
||||
attrib[1] = 0.0;
|
||||
attrib[2] = 0.0;
|
||||
attrib[3] = 1.0;
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
attrib[3] = ((float *) ptr)[3];
|
||||
/* fall-through */
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
attrib[2] = ((float *) ptr)[2];
|
||||
/* fall-through */
|
||||
case PIPE_FORMAT_R32G32_FLOAT:
|
||||
attrib[1] = ((float *) ptr)[1];
|
||||
/* fall-through */
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
attrib[0] = ((float *) ptr)[0];
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transform vertices with the current vertex program/shader
|
||||
@@ -97,18 +127,17 @@ compute_clipmask(float cx, float cy, float cz, float cw)
|
||||
* \param vOut array of pointers to four output vertices
|
||||
*/
|
||||
static void
|
||||
run_vertex_program(struct draw_context *draw,
|
||||
const void *vbuffer, unsigned elts[4], unsigned count,
|
||||
run_vertex_program(struct softpipe_context *sp,
|
||||
unsigned elts[4], unsigned count,
|
||||
struct vertex_header *vOut[])
|
||||
{
|
||||
struct softpipe_context *sp = softpipe_context(draw->pipe);
|
||||
struct tgsi_exec_machine machine;
|
||||
unsigned int j;
|
||||
|
||||
ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX);
|
||||
ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX);
|
||||
const float *scale = draw->viewport.scale;
|
||||
const float *trans = draw->viewport.translate;
|
||||
const float *scale = sp->viewport.scale;
|
||||
const float *trans = sp->viewport.translate;
|
||||
|
||||
assert(count <= 4);
|
||||
|
||||
@@ -129,21 +158,45 @@ run_vertex_program(struct draw_context *draw,
|
||||
machine.Inputs = ALIGN16_ASSIGN(inputs);
|
||||
machine.Outputs = ALIGN16_ASSIGN(outputs);
|
||||
|
||||
|
||||
if (0)
|
||||
{
|
||||
unsigned attr;
|
||||
for (attr = 0; attr < 16; attr++) {
|
||||
if (sp->vs.inputs_read & (1 << attr)) {
|
||||
printf("attr %d: buf_off %d src_off %d pitch %d\n",
|
||||
attr,
|
||||
sp->vertex_buffer[attr].buffer_offset,
|
||||
sp->vertex_element[attr].src_offset,
|
||||
sp->vertex_buffer[attr].pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* load machine inputs */
|
||||
for (j = 0; j < count; j++) {
|
||||
unsigned attr;
|
||||
for (attr = 0; attr < 16; attr++) {
|
||||
if (sp->vs.inputs_read & (1 << attr)) {
|
||||
const float *p
|
||||
= (const float *) ((const ubyte *) vbuffer
|
||||
+ draw->vertex_buffer[attr].buffer_offset
|
||||
+ draw->vertex_element[attr].src_offset
|
||||
+ elts[j] * draw->vertex_buffer[attr].pitch);
|
||||
const void *src
|
||||
= (const void *) ((const ubyte *) sp->mapped_vbuffer[attr]
|
||||
+ sp->vertex_buffer[attr].buffer_offset
|
||||
+ sp->vertex_element[attr].src_offset
|
||||
+ elts[j] * sp->vertex_buffer[attr].pitch);
|
||||
float p[4];
|
||||
|
||||
fetch_attrib4(src, sp->vertex_element[attr].src_format, p);
|
||||
|
||||
machine.Inputs[attr].xyzw[0].f[j] = p[0]; /*X*/
|
||||
machine.Inputs[attr].xyzw[1].f[j] = p[1]; /*Y*/
|
||||
machine.Inputs[attr].xyzw[2].f[j] = p[2]; /*Z*/
|
||||
machine.Inputs[attr].xyzw[3].f[j] = 1.0; /*W*/
|
||||
machine.Inputs[attr].xyzw[3].f[j] = p[3]; /*W*/
|
||||
#if 0
|
||||
if (attr == 0) {
|
||||
printf("Input vertex %d: %f %f %f\n",
|
||||
j, p[0], p[1], p[2]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,7 +226,7 @@ run_vertex_program(struct draw_context *draw,
|
||||
/* store machine results */
|
||||
assert(sp->vs.outputs_written & (1 << VERT_RESULT_HPOS));
|
||||
for (j = 0; j < count; j++) {
|
||||
unsigned attr;
|
||||
unsigned attr, slot;
|
||||
float x, y, z, w;
|
||||
|
||||
/* Handle attr[0] (position) specially: */
|
||||
@@ -183,7 +236,7 @@ run_vertex_program(struct draw_context *draw,
|
||||
w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j];
|
||||
|
||||
vOut[j]->clipmask = compute_clipmask(x, y, z, w);
|
||||
vOut[j]->edgeflag = 0;
|
||||
vOut[j]->edgeflag = 1;
|
||||
|
||||
/* divide by w */
|
||||
w = 1.0 / w;
|
||||
@@ -204,12 +257,16 @@ run_vertex_program(struct draw_context *draw,
|
||||
#endif
|
||||
|
||||
/* remaining attributes: */
|
||||
/* pack into sequential post-transform attrib slots */
|
||||
slot = 1;
|
||||
for (attr = 1; attr < VERT_RESULT_MAX; attr++) {
|
||||
if (sp->vs.outputs_written & (1 << attr)) {
|
||||
vOut[j]->data[attr][0] = outputs[attr].xyzw[0].f[j];
|
||||
vOut[j]->data[attr][1] = outputs[attr].xyzw[1].f[j];
|
||||
vOut[j]->data[attr][2] = outputs[attr].xyzw[2].f[j];
|
||||
vOut[j]->data[attr][3] = outputs[attr].xyzw[3].f[j];
|
||||
assert(slot < sp->nr_attrs);
|
||||
vOut[j]->data[slot][0] = outputs[attr].xyzw[0].f[j];
|
||||
vOut[j]->data[slot][1] = outputs[attr].xyzw[1].f[j];
|
||||
vOut[j]->data[slot][2] = outputs[attr].xyzw[2].f[j];
|
||||
vOut[j]->data[slot][3] = outputs[attr].xyzw[3].f[j];
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,115 +280,17 @@ run_vertex_program(struct draw_context *draw,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stand-in for actual vertex program execution
|
||||
* XXX this will probably live in a new file, like "sp_vs.c"
|
||||
* \param draw the drawing context
|
||||
* \param vbuffer the mapped vertex buffer pointer
|
||||
* \param elem which element of the vertex buffer to use as input
|
||||
* \param vOut the output vertex
|
||||
*/
|
||||
#if 0
|
||||
static void
|
||||
run_vertex_program(struct draw_context *draw,
|
||||
const void *vbuffer, unsigned elem,
|
||||
struct vertex_header *vOut)
|
||||
{
|
||||
const float *vIn, *cIn;
|
||||
const float *scale = draw->viewport.scale;
|
||||
const float *trans = draw->viewport.translate;
|
||||
const void *mapped = vbuffer;
|
||||
|
||||
/* XXX temporary hack: */
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
const float *m = ctx->_ModelProjectMatrix.m;
|
||||
|
||||
vIn = (const float *) ((const ubyte *) mapped
|
||||
+ draw->vertex_buffer[0].buffer_offset
|
||||
+ draw->vertex_element[0].src_offset
|
||||
+ elem * draw->vertex_buffer[0].pitch);
|
||||
|
||||
cIn = (const float *) ((const ubyte *) mapped
|
||||
+ draw->vertex_buffer[3].buffer_offset
|
||||
+ draw->vertex_element[3].src_offset
|
||||
+ elem * draw->vertex_buffer[3].pitch);
|
||||
|
||||
{
|
||||
float x = vIn[0];
|
||||
float y = vIn[1];
|
||||
float z = vIn[2];
|
||||
float w = 1.0;
|
||||
|
||||
vOut->clipmask = 0x0;
|
||||
vOut->edgeflag = 0;
|
||||
/* MVP */
|
||||
vOut->clip[0] = m[0] * x + m[4] * y + m[ 8] * z + m[12] * w;
|
||||
vOut->clip[1] = m[1] * x + m[5] * y + m[ 9] * z + m[13] * w;
|
||||
vOut->clip[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
||||
vOut->clip[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
||||
|
||||
/* divide by w */
|
||||
x = vOut->clip[0] / vOut->clip[3];
|
||||
y = vOut->clip[1] / vOut->clip[3];
|
||||
z = vOut->clip[2] / vOut->clip[3];
|
||||
w = 1.0 / vOut->clip[3];
|
||||
|
||||
/* Viewport */
|
||||
vOut->data[0][0] = scale[0] * x + trans[0];
|
||||
vOut->data[0][1] = scale[1] * y + trans[1];
|
||||
vOut->data[0][2] = scale[2] * z + trans[2];
|
||||
vOut->data[0][3] = w;
|
||||
|
||||
/* color */
|
||||
vOut->data[1][0] = cIn[0];
|
||||
vOut->data[1][1] = cIn[1];
|
||||
vOut->data[1][2] = cIn[2];
|
||||
vOut->data[1][3] = 1.0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Called by the draw module when the vertx cache needs to be flushed.
|
||||
* This involves running the vertex shader.
|
||||
*/
|
||||
static void vs_flush( struct draw_context *draw )
|
||||
{
|
||||
struct softpipe_context *sp = (struct softpipe_context *) draw->pipe;
|
||||
unsigned i, j;
|
||||
|
||||
/* We're not really running a vertex shader yet, so flushing the vs
|
||||
* queue is just a matter of building the vertices and returning.
|
||||
*/
|
||||
/* Actually, I'm cheating even more and pre-building them still
|
||||
* with the mesa/vf module. So it's very easy...
|
||||
*/
|
||||
#if 0
|
||||
for (i = 0; i < draw->vs.queue_nr; i++) {
|
||||
#else
|
||||
for (i = 0; i < draw->vs.queue_nr; i+=4) {
|
||||
#endif
|
||||
/* Would do the following steps here:
|
||||
*
|
||||
* 1) Loop over vertex element descriptors, fetch data from each
|
||||
* to build the pre-tnl vertex. This might require a new struct
|
||||
* to represent the pre-tnl vertex.
|
||||
*
|
||||
* 2) Bundle groups of upto 4 pre-tnl vertices together and pass
|
||||
* to vertex shader.
|
||||
*
|
||||
* 3) Do any necessary unswizzling, make sure vertex headers are
|
||||
* correctly populated, store resulting post-transformed
|
||||
* vertices in vcache.
|
||||
*
|
||||
* In this version, just do the last step:
|
||||
*/
|
||||
#if 0
|
||||
const unsigned elt = draw->vs.queue[i].elt;
|
||||
struct vertex_header *dest = draw->vs.queue[i].dest;
|
||||
|
||||
run_vertex_program(draw, draw->mapped_vbuffer, elt, dest);
|
||||
#else
|
||||
/* run vertex shader on vertex cache entries, four per invokation */
|
||||
for (i = 0; i < draw->vs.queue_nr; i += 4) {
|
||||
struct vertex_header *dests[4];
|
||||
unsigned elts[4];
|
||||
int n;
|
||||
@@ -345,9 +304,9 @@ static void vs_flush( struct draw_context *draw )
|
||||
assert(n > 0);
|
||||
assert(n <= 4);
|
||||
|
||||
run_vertex_program(draw, draw->mapped_vbuffer, elts, n, dests);
|
||||
#endif
|
||||
run_vertex_program(sp, elts, n, dests);
|
||||
}
|
||||
|
||||
draw->vs.queue_nr = 0;
|
||||
}
|
||||
|
||||
@@ -359,17 +318,24 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||
{
|
||||
struct softpipe_context *sp = softpipe_context(pipe);
|
||||
struct draw_context *draw = sp->draw;
|
||||
struct pipe_buffer_handle *buf;
|
||||
unsigned int i;
|
||||
|
||||
if (sp->dirty)
|
||||
softpipe_update_derived( sp );
|
||||
|
||||
softpipe_map_surfaces(sp);
|
||||
|
||||
/*
|
||||
* Map vertex buffers
|
||||
*/
|
||||
buf = sp->vertex_buffer[0].buffer;
|
||||
draw->mapped_vbuffer
|
||||
= pipe->winsys->buffer_map(pipe->winsys, buf, PIPE_BUFFER_FLAG_READ);
|
||||
|
||||
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
|
||||
if (sp->vertex_buffer[i].buffer) {
|
||||
sp->mapped_vbuffer[i]
|
||||
= pipe->winsys->buffer_map(pipe->winsys,
|
||||
sp->vertex_buffer[i].buffer,
|
||||
PIPE_BUFFER_FLAG_READ);
|
||||
}
|
||||
}
|
||||
|
||||
/* tell drawing pipeline we're beginning drawing */
|
||||
draw->pipeline.first->begin( draw->pipeline.first );
|
||||
@@ -392,9 +358,13 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||
draw->pipeline.first->end( draw->pipeline.first );
|
||||
|
||||
/*
|
||||
* unmap vertex buffer
|
||||
* unmap vertex buffers
|
||||
*/
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, buf);
|
||||
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
|
||||
if (sp->vertex_buffer[i].buffer) {
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
|
||||
}
|
||||
}
|
||||
|
||||
softpipe_unmap_surfaces(sp);
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
|
||||
if (attr_mask != softpipe->attr_mask) {
|
||||
softpipe->attr_mask = attr_mask;
|
||||
|
||||
#define USE_NEW_DRAW 0
|
||||
#define USE_NEW_DRAW 01
|
||||
#if USE_NEW_DRAW
|
||||
draw_set_vertex_attributes2( softpipe->draw,
|
||||
slot_to_vf_attr,
|
||||
|
||||
@@ -46,6 +46,7 @@ static const struct st_tracked_state *atoms[] =
|
||||
&st_update_clear_color,
|
||||
&st_update_depth,
|
||||
&st_update_clip,
|
||||
&st_update_tnl,
|
||||
&st_update_vs,
|
||||
&st_update_fs,
|
||||
&st_update_setup,
|
||||
|
||||
@@ -48,6 +48,7 @@ const struct st_tracked_state st_update_framebuffer;
|
||||
const struct st_tracked_state st_update_clip;
|
||||
const struct st_tracked_state st_update_clear_color;
|
||||
const struct st_tracked_state st_update_depth;
|
||||
const struct st_tracked_state st_update_tnl;
|
||||
const struct st_tracked_state st_update_fs;
|
||||
const struct st_tracked_state st_update_vs;
|
||||
const struct st_tracked_state st_update_setup;
|
||||
|
||||
@@ -74,6 +74,9 @@ static void update_fs( struct st_context *st )
|
||||
|
||||
if (fp && params) {
|
||||
/* load program's constants array */
|
||||
|
||||
_mesa_load_state_parameters(st->ctx, params);
|
||||
|
||||
fp->constants.nr_constants = params->NumParameters;
|
||||
memcpy(fp->constants.constant,
|
||||
params->ParameterValues,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -27,9 +27,11 @@
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "tnl/t_vp_build.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/tgsi/mesa/mesa_to_tgsi.h"
|
||||
@@ -39,6 +41,7 @@
|
||||
#include "st_atom.h"
|
||||
#include "st_program.h"
|
||||
|
||||
|
||||
#define TGSI_DEBUG 0
|
||||
|
||||
static void compile_vs( struct st_context *st,
|
||||
@@ -59,8 +62,10 @@ static void update_vs( struct st_context *st )
|
||||
struct st_vertex_program *vp = NULL;
|
||||
struct gl_program_parameter_list *params = NULL;
|
||||
|
||||
#if 0
|
||||
if (st->ctx->VertexProgram._MaintainTnlProgram)
|
||||
_tnl_UpdateFixedFunctionProgram( st->ctx );
|
||||
#endif
|
||||
|
||||
if (st->ctx->Shader.CurrentProgram &&
|
||||
st->ctx->Shader.CurrentProgram->LinkStatus &&
|
||||
@@ -83,6 +88,7 @@ static void update_vs( struct st_context *st )
|
||||
if (vp && params) {
|
||||
/* load program's constants array */
|
||||
|
||||
/* XXX this should probably be done elsewhere/separately */
|
||||
_mesa_load_state_parameters(st->ctx, params);
|
||||
|
||||
vp->constants.nr_constants = params->NumParameters;
|
||||
@@ -117,3 +123,26 @@ const struct st_tracked_state st_update_vs = {
|
||||
},
|
||||
.update = update_vs
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* When TnL state has changed, need to generate new vertex program.
|
||||
* This should be done before updating the vertes shader (vs) state.
|
||||
*/
|
||||
static void update_tnl( struct st_context *st )
|
||||
{
|
||||
if (st->ctx->VertexProgram._MaintainTnlProgram)
|
||||
_tnl_UpdateFixedFunctionProgram( st->ctx );
|
||||
}
|
||||
|
||||
|
||||
const struct st_tracked_state st_update_tnl = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_PROGRAM | _NEW_LIGHT | _NEW_TEXTURE, /* XXX more? */
|
||||
.st = ST_NEW_MESA, /* XXX correct? */
|
||||
},
|
||||
.update = update_tnl
|
||||
};
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "imports.h"
|
||||
#include "main/imports.h"
|
||||
#include "vbo/vbo.h"
|
||||
#include "st_public.h"
|
||||
#include "st_context.h"
|
||||
#include "st_cb_bufferobjects.h"
|
||||
@@ -68,6 +69,9 @@ struct st_context *st_create_context( GLcontext *ctx,
|
||||
st_init_atoms( st );
|
||||
st_init_draw( st );
|
||||
|
||||
/* we want all vertex data to be placed in buffer objects */
|
||||
vbo_use_buffer_objects(ctx);
|
||||
|
||||
/* Need these flags:
|
||||
*/
|
||||
st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
|
||||
|
||||
@@ -104,6 +104,8 @@ struct st_context
|
||||
struct st_state_flags dirty;
|
||||
|
||||
GLfloat polygon_offset_scale; /* ?? */
|
||||
|
||||
struct pipe_buffer_handle *default_attrib_buffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "st_cb_bufferobjects.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
#include "vbo/vbo_context.h"
|
||||
|
||||
@@ -52,7 +53,7 @@
|
||||
* bypassing the T&L module. This only works with VBO-based demos,
|
||||
* such as progs/test/bufferobj.c
|
||||
*/
|
||||
#define USE_NEW_DRAW 0
|
||||
#define USE_NEW_DRAW 01
|
||||
|
||||
|
||||
/*
|
||||
@@ -134,6 +135,38 @@ pipe_vertex_format(GLenum format, GLuint size)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The default attribute buffer is basically a copy of the
|
||||
* ctx->Current.Attrib[] array. It's used when the vertex program
|
||||
* references an attribute for which we don't have a VBO/array.
|
||||
*/
|
||||
static void
|
||||
create_default_attribs_buffer(struct st_context *st)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
st->default_attrib_buffer = pipe->winsys->buffer_create( pipe->winsys, 32 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
destroy_default_attribs_buffer(struct st_context *st)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
pipe->winsys->buffer_unreference(pipe->winsys, &st->default_attrib_buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_default_attribs_buffer(GLcontext *ctx)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct pipe_buffer_handle *buf = ctx->st->default_attrib_buffer;
|
||||
const unsigned size = sizeof(ctx->Current.Attrib);
|
||||
const void *data = ctx->Current.Attrib;
|
||||
pipe->winsys->buffer_data(pipe->winsys, buf, size, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function gets plugged into the VBO module and is called when
|
||||
* we have something to render.
|
||||
@@ -150,41 +183,66 @@ draw_vbo(GLcontext *ctx,
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
GLuint attr, i;
|
||||
GLbitfield attrsNeeded;
|
||||
const unsigned attr0_offset = (unsigned) arrays[0]->Ptr;
|
||||
|
||||
st_validate_state(ctx->st);
|
||||
update_default_attribs_buffer(ctx);
|
||||
|
||||
/* this must be after state validation */
|
||||
attrsNeeded = ctx->st->state.vs.inputs_read;
|
||||
|
||||
/* tell pipe about the vertex array element/attributes */
|
||||
for (attr = 0; attr < 16; attr++) {
|
||||
struct gl_buffer_object *bufobj = arrays[attr]->BufferObj;
|
||||
struct pipe_vertex_buffer vbuffer;
|
||||
struct pipe_vertex_element velement;
|
||||
|
||||
if (bufobj && bufobj->Name) {
|
||||
struct st_buffer_object *stobj = st_buffer_object(bufobj);
|
||||
vbuffer.buffer = NULL;
|
||||
vbuffer.pitch = 0;
|
||||
velement.src_offset = 0;
|
||||
velement.vertex_buffer_index = 0;
|
||||
velement.src_format = 0;
|
||||
|
||||
assert(stobj->buffer);
|
||||
if (attrsNeeded & (1 << attr)) {
|
||||
struct gl_buffer_object *bufobj = arrays[attr]->BufferObj;
|
||||
|
||||
vbuffer.pitch = arrays[attr]->StrideB; /* in bytes */
|
||||
vbuffer.max_index = 0;
|
||||
vbuffer.buffer = stobj->buffer;
|
||||
vbuffer.buffer_offset = 0;
|
||||
if (bufobj && bufobj->Name) {
|
||||
struct st_buffer_object *stobj = st_buffer_object(bufobj);
|
||||
/* Recall that for VBOs, the gl_client_array->Ptr field is
|
||||
* really an offset from the start of the VBO, not a pointer.
|
||||
*/
|
||||
unsigned offset = (unsigned) arrays[attr]->Ptr;
|
||||
|
||||
/* Recall that for VBOs, the gl_client_array->Ptr field is
|
||||
* really an offset from the start of the VBO, not a pointer.
|
||||
*/
|
||||
velement.src_offset = (unsigned) arrays[attr]->Ptr;
|
||||
velement.vertex_buffer_index = attr;
|
||||
velement.dst_offset = 0;
|
||||
velement.src_format = pipe_vertex_format(arrays[attr]->Type,
|
||||
arrays[attr]->Size);
|
||||
assert(stobj->buffer);
|
||||
|
||||
vbuffer.buffer = stobj->buffer;
|
||||
vbuffer.buffer_offset = attr0_offset; /* in bytes */
|
||||
vbuffer.pitch = arrays[attr]->StrideB; /* in bytes */
|
||||
vbuffer.max_index = 0; /* need this? */
|
||||
|
||||
velement.src_offset = offset - attr0_offset; /* bytes */
|
||||
velement.vertex_buffer_index = attr;
|
||||
velement.dst_offset = 0; /* need this? */
|
||||
velement.src_format = pipe_vertex_format(arrays[attr]->Type,
|
||||
arrays[attr]->Size);
|
||||
assert(velement.src_format);
|
||||
}
|
||||
else {
|
||||
/* use the default attribute buffer */
|
||||
vbuffer.buffer = ctx->st->default_attrib_buffer;
|
||||
vbuffer.buffer_offset = 0;
|
||||
vbuffer.pitch = 0; /* must be zero! */
|
||||
vbuffer.max_index = 1;
|
||||
|
||||
velement.src_offset = attr * 4 * sizeof(GLfloat);
|
||||
velement.vertex_buffer_index = attr;
|
||||
velement.dst_offset = 0;
|
||||
velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* vertex attribute data is not an a real buffer! */
|
||||
/* XXX we'll want to handle that someday... */
|
||||
|
||||
vbuffer.buffer = NULL;
|
||||
}
|
||||
if (attr == 0)
|
||||
assert(vbuffer.buffer);
|
||||
|
||||
pipe->set_vertex_buffer(pipe, attr, &vbuffer);
|
||||
pipe->set_vertex_element(pipe, attr, &velement);
|
||||
@@ -209,6 +267,8 @@ void st_init_draw( struct st_context *st )
|
||||
#if USE_NEW_DRAW
|
||||
struct vbo_context *vbo = (struct vbo_context *) ctx->swtnl_im;
|
||||
|
||||
create_default_attribs_buffer(st);
|
||||
|
||||
assert(vbo);
|
||||
assert(vbo->draw_prims);
|
||||
vbo->draw_prims = draw_vbo;
|
||||
@@ -224,8 +284,7 @@ void st_init_draw( struct st_context *st )
|
||||
|
||||
void st_destroy_draw( struct st_context *st )
|
||||
{
|
||||
/* Nothing to do.
|
||||
*/
|
||||
destroy_default_attribs_buffer(st);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ static struct state_key *make_state_key( GLcontext *ctx )
|
||||
}
|
||||
|
||||
for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++)
|
||||
if (VB->AttribPtr[i]->stride)
|
||||
if (VB->AttribPtr[i] && VB->AttribPtr[i]->stride)
|
||||
key->light_material_mask |= 1<<(i-_TNL_ATTRIB_MAT_FRONT_AMBIENT);
|
||||
|
||||
for (i = 0; i < MAX_LIGHTS; i++) {
|
||||
|
||||
@@ -114,4 +114,7 @@ void vbo_rebase_prims( GLcontext *ctx,
|
||||
vbo_draw_func draw );
|
||||
|
||||
|
||||
void vbo_use_buffer_objects(GLcontext *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -631,6 +631,41 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tell the VBO module to use a real OpenGL vertex buffer object to
|
||||
* store accumulated immediate-mode vertex data.
|
||||
* This replaces the malloced buffer which was created in
|
||||
* vb_exec_vtx_init() below.
|
||||
*/
|
||||
void vbo_use_buffer_objects(GLcontext *ctx)
|
||||
{
|
||||
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
|
||||
/* Any buffer name but 0 can be used here since this bufferobj won't
|
||||
* go into the bufferobj hashtable.
|
||||
*/
|
||||
GLuint bufName = 0xaabbccdd;
|
||||
GLenum target = GL_ARRAY_BUFFER_ARB;
|
||||
GLenum access = GL_READ_WRITE_ARB;
|
||||
GLenum usage = GL_STREAM_DRAW_ARB;
|
||||
GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat);
|
||||
|
||||
/* Make sure this func is only used once */
|
||||
assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);
|
||||
if (exec->vtx.buffer_map) {
|
||||
_mesa_align_free(exec->vtx.buffer_map);
|
||||
}
|
||||
|
||||
/* Allocate a real buffer object now */
|
||||
exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
|
||||
ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
|
||||
|
||||
/* and map it */
|
||||
exec->vtx.buffer_map
|
||||
= ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void vbo_exec_vtx_init( struct vbo_exec_context *exec )
|
||||
{
|
||||
GLcontext *ctx = exec->ctx;
|
||||
|
||||
@@ -175,16 +175,27 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
|
||||
* arrays of floats.
|
||||
*/
|
||||
for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) {
|
||||
GLuint src = map[attr];
|
||||
const GLuint src = map[attr];
|
||||
|
||||
if (exec->vtx.attrsz[src]) {
|
||||
arrays[attr].Ptr = (void *)data;
|
||||
if (exec->vtx.bufferobj->Name) {
|
||||
/* a real buffer obj: Ptr is an offset, not a pointer*/
|
||||
int offset;
|
||||
assert(exec->vtx.bufferobj->Pointer); /* buf should be mapped */
|
||||
offset = (GLbyte *) data - (GLbyte *) exec->vtx.bufferobj->Pointer;
|
||||
assert(offset >= 0);
|
||||
arrays[attr].Ptr = (void *) offset;
|
||||
}
|
||||
else {
|
||||
/* Ptr into ordinary app memory */
|
||||
arrays[attr].Ptr = (void *) data;
|
||||
}
|
||||
arrays[attr].Size = exec->vtx.attrsz[src];
|
||||
arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat);
|
||||
arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat);
|
||||
arrays[attr].Type = GL_FLOAT;
|
||||
arrays[attr].Enabled = 1;
|
||||
arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */
|
||||
arrays[attr].BufferObj = exec->vtx.bufferobj;
|
||||
arrays[attr]._MaxElement = count; /* ??? */
|
||||
|
||||
data += exec->vtx.attrsz[attr] * sizeof(GLfloat);
|
||||
|
||||
Reference in New Issue
Block a user