summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/ffvertex_prog.c54
-rw-r--r--src/mesa/shader/arbprogparse.c4
-rw-r--r--src/mesa/shader/prog_parameter.c4
-rw-r--r--src/mesa/shader/prog_print.c4
-rw-r--r--src/mesa/shader/prog_statevars.c2
-rw-r--r--src/mesa/shader/prog_statevars.h2
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c8
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c5
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c8
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c18
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c11
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c8
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h4
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c7
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_draw.c283
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c2
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c8
-rw-r--r--src/mesa/state_tracker/st_public.h13
-rw-r--r--src/mesa/state_tracker/st_texture.c96
-rw-r--r--src/mesa/state_tracker/st_texture.h6
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c14
22 files changed, 450 insertions, 113 deletions
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index 5f3def257de..787672be9f1 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -319,7 +319,6 @@ static struct state_key *make_state_key( GLcontext *ctx )
*/
#define PREFER_DP4 0
-#define MAX_INSN 256
/* Use uregs to represent registers internally, translate to Mesa's
* expected formats on emit.
@@ -335,16 +334,18 @@ static struct state_key *make_state_key( GLcontext *ctx )
*/
struct ureg {
GLuint file:4;
- GLint idx:8; /* relative addressing may be negative */
+ GLint idx:9; /* relative addressing may be negative */
+ /* sizeof(idx) should == sizeof(prog_src_reg::Index) */
GLuint negate:1;
GLuint swz:12;
- GLuint pad:7;
+ GLuint pad:6;
};
struct tnl_program {
const struct state_key *state;
struct gl_vertex_program *program;
+ GLint max_inst; /** number of instructions allocated for program */
GLuint temp_in_use;
GLuint temp_reserved;
@@ -362,7 +363,7 @@ struct tnl_program {
static const struct ureg undef = {
PROGRAM_UNDEFINED,
- ~0,
+ 0,
0,
0,
0
@@ -558,6 +559,8 @@ static void emit_arg( struct prog_src_register *src,
src->Abs = 0;
src->NegateAbs = 0;
src->RelAddr = 0;
+ /* Check that bitfield sizes aren't exceeded */
+ ASSERT(src->Index == reg.idx);
}
static void emit_dst( struct prog_dst_register *dst,
@@ -571,6 +574,8 @@ static void emit_dst( struct prog_dst_register *dst,
dst->CondSwizzle = SWIZZLE_NOOP;
dst->CondSrc = 0;
dst->pad = 0;
+ /* Check that bitfield sizes aren't exceeded */
+ ASSERT(dst->Index == reg.idx);
}
static void debug_insn( struct prog_instruction *inst, const char *fn,
@@ -600,14 +605,37 @@ static void emit_op3fn(struct tnl_program *p,
const char *fn,
GLuint line)
{
- GLuint nr = p->program->Base.NumInstructions++;
- struct prog_instruction *inst = &p->program->Base.Instructions[nr];
+ GLuint nr;
+ struct prog_instruction *inst;
- if (p->program->Base.NumInstructions > MAX_INSN) {
- _mesa_problem(0, "Out of instructions in emit_op3fn\n");
- return;
+ assert((GLint) p->program->Base.NumInstructions <= p->max_inst);
+
+ if (p->program->Base.NumInstructions == p->max_inst) {
+ /* need to extend the program's instruction array */
+ struct prog_instruction *newInst;
+
+ /* double the size */
+ p->max_inst *= 2;
+
+ newInst = _mesa_alloc_instructions(p->max_inst);
+ if (!newInst) {
+ _mesa_error(NULL, GL_OUT_OF_MEMORY, "vertex program build");
+ return;
+ }
+
+ _mesa_copy_instructions(newInst,
+ p->program->Base.Instructions,
+ p->program->Base.NumInstructions);
+
+ _mesa_free_instructions(p->program->Base.Instructions,
+ p->program->Base.NumInstructions);
+
+ p->program->Base.Instructions = newInst;
}
+ nr = p->program->Base.NumInstructions++;
+
+ inst = &p->program->Base.Instructions[nr];
inst->Opcode = (enum prog_opcode) op;
inst->StringPos = 0;
inst->Data = 0;
@@ -1621,6 +1649,8 @@ static void build_tnl_program( struct tnl_program *p )
#if 0
else
build_constant_pointsize(p);
+#else
+ (void) build_constant_pointsize;
#endif
/* Finish up:
@@ -1657,7 +1687,11 @@ create_new_program( const struct state_key *key,
else
p.temp_reserved = ~((1<<max_temps)-1);
- p.program->Base.Instructions = _mesa_alloc_instructions(MAX_INSN);
+ /* Start by allocating 32 instructions.
+ * If we need more, we'll grow the instruction array as needed.
+ */
+ p.max_inst = 32;
+ p.program->Base.Instructions = _mesa_alloc_instructions(p.max_inst);
p.program->Base.String = NULL;
p.program->Base.NumInstructions =
p.program->Base.NumTemporaries =
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 78cc6aa9cc0..26ccdc7395a 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -3354,11 +3354,11 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head,
fprintf (stderr, "%s\n",
Program->Base.Parameters->Parameters[a + b].Name);
if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) {
- const char *s;
+ char *s;
s = _mesa_program_state_string(Program->Base.Parameters->Parameters
[a + b].StateIndexes);
fprintf(stderr, "%s\n", s);
- _mesa_free((char *) s);
+ _mesa_free(s);
}
else
fprintf (stderr, "%f %f %f %f\n",
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index 2dfd923a0f3..bfe27d2f638 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -420,7 +420,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
const gl_state_index stateTokens[STATE_LENGTH])
{
const GLuint size = 4; /* XXX fix */
- const char *name;
+ char *name;
GLint index;
/* Check if the state reference is already in the list */
@@ -447,7 +447,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
paramList->StateFlags |= _mesa_program_state_flags(stateTokens);
/* free name string here since we duplicated it in add_parameter() */
- _mesa_free((void *) name);
+ _mesa_free(name);
return index;
}
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 10c5afec189..ec260f18a9f 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -250,7 +250,9 @@ reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
{
struct gl_program_parameter *param
= prog->Parameters->Parameters + index;
- sprintf(str, _mesa_program_state_string(param->StateIndexes));
+ char *state = _mesa_program_state_string(param->StateIndexes);
+ sprintf(str, state);
+ _mesa_free(state);
}
break;
case PROGRAM_ADDRESS:
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
index 971eb25a491..d4e31207e84 100644
--- a/src/mesa/shader/prog_statevars.c
+++ b/src/mesa/shader/prog_statevars.c
@@ -784,7 +784,7 @@ append_index(char *dst, GLint index)
* For example, return "state.matrix.texture[2].inverse".
* Use _mesa_free() to deallocate the string.
*/
-const char *
+char *
_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
{
char str[1000] = "";
diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h
index d3091147f82..20643ca7947 100644
--- a/src/mesa/shader/prog_statevars.h
+++ b/src/mesa/shader/prog_statevars.h
@@ -130,7 +130,7 @@ extern GLbitfield
_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]);
-extern const char *
+extern char *
_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]);
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index d3aadf5074d..d02e51cb9a5 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -73,8 +73,8 @@ void st_upload_constants( struct st_context *st,
/* We always need to get a new buffer, to keep the drivers simple and
* avoid gratuitous rendering synchronization.
*/
- pipe_reference_buffer(pipe, &cbuf->buffer, NULL );
- cbuf->buffer = pipe_buffer_create(pipe, 16, PIPE_BUFFER_USAGE_CONSTANT,
+ pipe_buffer_reference(pipe->screen, &cbuf->buffer, NULL );
+ cbuf->buffer = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT,
paramBytes );
if (0)
@@ -86,10 +86,10 @@ void st_upload_constants( struct st_context *st,
/* load Mesa constants into the constant buffer */
if (cbuf->buffer) {
- void *map = pipe_buffer_map(pipe, cbuf->buffer,
+ void *map = pipe_buffer_map(pipe->screen, cbuf->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(map, params->ParameterValues, paramBytes);
- pipe_buffer_unmap(pipe, cbuf->buffer);
+ pipe_buffer_unmap(pipe->screen, cbuf->buffer);
}
cbuf->size = paramBytes;
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 6594e59e94b..cbd414e2d3b 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -266,17 +266,12 @@ find_translated_vp(struct st_context *st,
xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
xvp->output_to_semantic_index[outAttr] = maxGeneric + 1;
}
-
- assert(xvp->output_to_semantic_name[outAttr] != TGSI_SEMANTIC_COUNT);
- assert(xvp->output_to_semantic_index[outAttr] != 99);
}
-
#if 0 /*debug*/
printf("vp output_to_slot[%d] = %d\n", outAttr,
xvp->output_to_slot[outAttr]);
#endif
-
}
assert(stvp->Base.Base.NumInstructions > 1);
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index a0c305d66ff..694104f9cfb 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -378,7 +378,7 @@ setup_bitmap_vertex_data(struct st_context *st,
void *buf;
if (!st->bitmap.vbuf) {
- st->bitmap.vbuf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
+ st->bitmap.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
sizeof(st->bitmap.vertices));
}
@@ -418,9 +418,9 @@ setup_bitmap_vertex_data(struct st_context *st,
}
/* put vertex data into vbuf */
- buf = pipe_buffer_map(pipe, st->bitmap.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ buf = pipe_buffer_map(pipe->screen, st->bitmap.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(buf, st->bitmap.vertices, sizeof(st->bitmap.vertices));
- pipe_buffer_unmap(pipe, st->bitmap.vbuf);
+ pipe_buffer_unmap(pipe->screen, st->bitmap.vbuf);
}
@@ -779,7 +779,7 @@ st_destroy_bitmap(struct st_context *st)
}
if (st->bitmap.vbuf) {
- pipe_buffer_destroy(pipe, st->bitmap.vbuf);
+ pipe_buffer_destroy(pipe->screen, st->bitmap.vbuf);
st->bitmap.vbuf = NULL;
}
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index af79aefa968..07fa2afce05 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -78,7 +78,7 @@ st_bufferobj_free(GLcontext *ctx, struct gl_buffer_object *obj)
struct st_buffer_object *st_obj = st_buffer_object(obj);
if (st_obj->buffer)
- pipe_reference_buffer(pipe, &st_obj->buffer, NULL);
+ pipe_buffer_reference(pipe->screen, &st_obj->buffer, NULL);
free(st_obj);
}
@@ -105,9 +105,9 @@ st_bufferobj_subdata(GLcontext *ctx,
if (offset >= st_obj->size || size > (st_obj->size - offset))
return;
- map = pipe_buffer_map(pipe, st_obj->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = pipe_buffer_map(pipe->screen, st_obj->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(map + offset, data, size);
- pipe_buffer_unmap(pipe, st_obj->buffer);
+ pipe_buffer_unmap(pipe->screen, st_obj->buffer);
}
@@ -128,9 +128,9 @@ st_bufferobj_get_subdata(GLcontext *ctx,
if (offset >= st_obj->size || size > (st_obj->size - offset))
return;
- map = pipe_buffer_map(pipe, st_obj->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe->screen, st_obj->buffer, PIPE_BUFFER_USAGE_CPU_READ);
memcpy(data, map + offset, size);
- pipe_buffer_unmap(pipe, st_obj->buffer);
+ pipe_buffer_unmap(pipe->screen, st_obj->buffer);
}
@@ -171,9 +171,9 @@ st_bufferobj_data(GLcontext *ctx,
buffer_usage = 0;
}
- pipe_reference_buffer( pipe, &st_obj->buffer, NULL );
+ pipe_buffer_reference( pipe->screen, &st_obj->buffer, NULL );
- st_obj->buffer = pipe_buffer_create( pipe, 32, buffer_usage, size );
+ st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size );
st_obj->size = size;
@@ -207,7 +207,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
break;
}
- obj->Pointer = pipe_buffer_map(pipe, st_obj->buffer, flags);
+ obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags);
return obj->Pointer;
}
@@ -221,7 +221,7 @@ st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
struct pipe_context *pipe = st_context(ctx)->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
- pipe_buffer_unmap(pipe, st_obj->buffer);
+ pipe_buffer_unmap(pipe->screen, st_obj->buffer);
obj->Pointer = NULL;
return GL_TRUE;
}
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index e475f022d34..47ad3c2bc12 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -116,7 +116,7 @@ st_destroy_clear(struct st_context *st)
st->clear.vs = NULL;
}
if (st->clear.vbuf) {
- pipe_buffer_destroy(pipe, st->clear.vbuf);
+ pipe_buffer_destroy(pipe->screen, st->clear.vbuf);
st->clear.vbuf = NULL;
}
}
@@ -152,7 +152,7 @@ draw_quad(GLcontext *ctx,
void *buf;
if (!st->clear.vbuf) {
- st->clear.vbuf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
+ st->clear.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
sizeof(st->clear.vertices));
}
@@ -180,9 +180,9 @@ draw_quad(GLcontext *ctx,
}
/* put vertex data into vbuf */
- buf = pipe_buffer_map(pipe, st->clear.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ buf = pipe_buffer_map(pipe->screen, st->clear.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(buf, st->clear.vertices, sizeof(st->clear.vertices));
- pipe_buffer_unmap(pipe, st->clear.vbuf);
+ pipe_buffer_unmap(pipe->screen, st->clear.vbuf);
/* draw */
util_draw_vertex_buffer(pipe, st->clear.vbuf,
@@ -414,6 +414,9 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
/* clear whole buffer w/out masking */
struct st_renderbuffer *strb = st_renderbuffer(rb);
uint clearValue;
+ /* NOTE: we always pass the clear color as PIPE_FORMAT_A8R8G8B8_UNORM
+ * at this time!
+ */
util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue);
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
}
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 4ec7c752dfe..00bbcae32ae 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -487,17 +487,17 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
ubyte *map;
/* allocate/load buffer object with vertex data */
- buf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
+ buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
sizeof(verts));
- map = pipe_buffer_map(pipe, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(map, verts, sizeof(verts));
- pipe_buffer_unmap(pipe, buf);
+ pipe_buffer_unmap(pipe->screen, buf);
util_draw_vertex_buffer(pipe, buf,
PIPE_PRIM_QUADS,
4, /* verts */
3); /* attribs/vert */
- pipe_buffer_reference(pipe->winsys, &buf, NULL);
+ pipe_buffer_reference(pipe->screen, &buf, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index ff56001a4e1..44fa9fe9a4f 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -47,6 +47,10 @@ struct st_renderbuffer
struct st_texture_object *rtt; /**< GL render to texture's texture */
int rtt_level, rtt_face, rtt_slice;
+
+ /** Render to texture state */
+ struct pipe_texture *texture_save;
+ struct pipe_surface *surface_save;
};
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 16bbf3d80f2..a3e8fc992d9 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -58,13 +58,6 @@
#define DBG if (0) printf
-static INLINE struct st_texture_image *
-st_texture_image(struct gl_texture_image *img)
-{
- return (struct st_texture_image *) img;
-}
-
-
static enum pipe_texture_target
gl_target_to_pipe(GLenum target)
{
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 83b0be06daa..08d4db7f7f4 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -196,7 +196,7 @@ static void st_destroy_context_priv( struct st_context *st )
for (i = 0; i < Elements(st->state.constants); i++) {
if (st->state.constants[i].buffer) {
- pipe_reference_buffer(st->pipe, &st->state.constants[i].buffer, NULL);
+ pipe_buffer_reference(st->pipe->screen, &st->state.constants[i].buffer, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index e1bc108eae2..bdf8648ef7c 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -32,6 +32,7 @@
#include "main/imports.h"
#include "main/image.h"
+#include "main/macros.h"
#include "vbo/vbo.h"
@@ -228,7 +229,7 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
if (!vec)
return NULL;
- map = pipe_buffer_map(pipe, stobj->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ 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++) {
@@ -238,7 +239,7 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
map += array->StrideB;
}
- pipe_buffer_unmap(pipe, stobj->buffer);
+ pipe_buffer_unmap(pipe->screen, stobj->buffer);
pipe->set_edgeflags(pipe, vec);
@@ -252,40 +253,170 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
}
+/**
+ * Examine the active arrays to determine if we have interleaved
+ * vertex arrays all living in one VBO, or all living in user space.
+ * \param userSpace returns whether the arrays are in user space.
+ */
+static GLboolean
+is_interleaved_arrays(const struct st_vertex_program *vp,
+ const struct gl_client_array **arrays,
+ GLboolean *userSpace)
+{
+ GLuint attr;
+ const struct gl_buffer_object *firstBufObj = NULL;
+ GLint firstStride = -1;
+ GLuint num_client_arrays = 0;
+ const GLubyte *client_addr = NULL;
+
+ for (attr = 0; attr < vp->num_inputs; attr++) {
+ const GLuint mesaAttr = vp->index_to_input[attr];
+ const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj;
+ const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */
+
+ if (firstStride < 0) {
+ firstStride = stride;
+ }
+ else if (firstStride != stride) {
+ return GL_FALSE;
+ }
+
+ if (!bufObj || !bufObj->Name) {
+ num_client_arrays++;
+ /* Try to detect if the client-space arrays are
+ * "close" to each other.
+ */
+ if (!client_addr) {
+ client_addr = arrays[mesaAttr]->Ptr;
+ }
+ else if (abs(arrays[mesaAttr]->Ptr - client_addr) > firstStride) {
+ /* arrays start too far apart */
+ return GL_FALSE;
+ }
+ }
+ else if (!firstBufObj) {
+ firstBufObj = bufObj;
+ }
+ else if (bufObj != firstBufObj) {
+ return GL_FALSE;
+ }
+ }
+
+ *userSpace = (num_client_arrays == vp->num_inputs);
+ /*printf("user space: %d\n", (int) *userSpace);*/
+
+ return GL_TRUE;
+}
+
/**
- * This function gets plugged into the VBO module and is called when
- * we have something to render.
- * Basically, translate the information into the format expected by pipe.
+ * Once we know all the arrays are in user space, this function
+ * computes the memory range occupied by the arrays.
*/
-void
-st_draw_vbo(GLcontext *ctx,
- const struct gl_client_array **arrays,
- const struct _mesa_prim *prims,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLuint min_index,
- GLuint max_index)
+static void
+get_user_arrays_bounds(const struct st_vertex_program *vp,
+ const struct gl_client_array **arrays,
+ GLuint max_index,
+ const GLubyte **low, const GLubyte **high)
+{
+ const GLubyte *low_addr = NULL;
+ GLuint attr;
+ GLint stride;
+
+ for (attr = 0; attr < vp->num_inputs; attr++) {
+ const GLuint mesaAttr = vp->index_to_input[attr];
+ const GLubyte *start = arrays[mesaAttr]->Ptr;
+ stride = arrays[mesaAttr]->StrideB;
+ if (attr == 0) {
+ low_addr = start;
+ }
+ else {
+ low_addr = MIN2(low_addr, start);
+ }
+ }
+
+ *low = low_addr;
+ *high = low_addr + (max_index + 1) * stride;
+}
+
+
+/**
+ * Set up for drawing interleaved arrays that all live in one VBO
+ * or all live in user space.
+ * \param vbuffer returns vertex buffer info
+ * \param velements returns vertex element info
+ */
+static void
+setup_interleaved_attribs(GLcontext *ctx,
+ const struct st_vertex_program *vp,
+ const struct gl_client_array **arrays,
+ GLuint max_index,
+ GLboolean userSpace,
+ struct pipe_vertex_buffer *vbuffer,
+ struct pipe_vertex_element velements[])
{
struct pipe_context *pipe = ctx->st->pipe;
- const struct st_vertex_program *vp;
- const struct pipe_shader_state *vs;
- struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
GLuint attr;
- struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
+ const GLubyte *offset0;
- /* sanity check for pointer arithmetic below */
- assert(sizeof(arrays[0]->Ptr[0]) == 1);
+ for (attr = 0; attr < vp->num_inputs; attr++) {
+ const GLuint mesaAttr = vp->index_to_input[attr];
+ struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
+ struct st_buffer_object *stobj = st_buffer_object(bufobj);
+ GLsizei stride = arrays[mesaAttr]->StrideB;
- st_validate_state(ctx->st);
+ /*printf("stobj %u = %p\n", attr, (void*)stobj);*/
+
+ if (attr == 0) {
+ if (userSpace) {
+ const GLubyte *low, *high;
+ get_user_arrays_bounds(vp, arrays, max_index, &low, &high);
+ /*printf("user buffer range: %p %p %d\n", low, high, high-low);*/
+ vbuffer->buffer =
+ pipe_user_buffer_create(pipe->screen, (void *) low, high - low);
+ vbuffer->buffer_offset = 0;
+ offset0 = low;
+ }
+ else {
+ vbuffer->buffer = NULL;
+ pipe_buffer_reference(pipe->screen, &vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer_offset = (unsigned) arrays[mesaAttr]->Ptr;
+ offset0 = arrays[mesaAttr]->Ptr;
+ }
+ vbuffer->pitch = stride; /* in bytes */
+ vbuffer->max_index = max_index;
+ }
- /* must get these after state validation! */
- vp = ctx->st->vp;
- vs = &ctx->st->vp->state;
+ velements[attr].src_offset =
+ (unsigned) (arrays[mesaAttr]->Ptr - offset0);
+ velements[attr].vertex_buffer_index = 0;
+ velements[attr].nr_components = arrays[mesaAttr]->Size;
+ velements[attr].src_format =
+ pipe_vertex_format(arrays[mesaAttr]->Type,
+ arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Normalized);
+ assert(velements[attr].src_format);
+ }
+}
+
+
+/**
+ * Set up a separate pipe_vertex_buffer and pipe_vertex_element for each
+ * vertex attribute.
+ * \param vbuffer returns vertex buffer info
+ * \param velements returns vertex element info
+ */
+static void
+setup_non_interleaved_attribs(GLcontext *ctx,
+ const struct st_vertex_program *vp,
+ const struct gl_client_array **arrays,
+ GLuint max_index,
+ struct pipe_vertex_buffer vbuffer[],
+ struct pipe_vertex_element velements[])
+{
+ struct pipe_context *pipe = ctx->st->pipe;
+ GLuint attr;
- /* loop over TGSI shader inputs to determine vertex buffer
- * and attribute info
- */
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
@@ -298,15 +429,17 @@ st_draw_vbo(GLcontext *ctx,
*/
struct st_buffer_object *stobj = st_buffer_object(bufobj);
assert(stobj->buffer);
+ /*printf("stobj %u = %p\n", attr, (void*) stobj);*/
vbuffer[attr].buffer = NULL;
- pipe_reference_buffer(pipe, &vbuffer[attr].buffer, stobj->buffer);
+ pipe_buffer_reference(pipe->screen, &vbuffer[attr].buffer, stobj->buffer);
vbuffer[attr].buffer_offset = (unsigned) arrays[mesaAttr]->Ptr;
velements[attr].src_offset = 0;
}
else {
/* attribute data is in user-space memory, not a VBO */
uint bytes;
+ /*printf("user-space array %d stride %d\n", attr, stride);*/
/* wrap user data */
if (arrays[mesaAttr]->Ptr) {
@@ -318,13 +451,13 @@ st_draw_vbo(GLcontext *ctx,
bytes = arrays[mesaAttr]->Size
* _mesa_sizeof_type(arrays[mesaAttr]->Type);
}
- vbuffer[attr].buffer = pipe_user_buffer_create(pipe,
+ vbuffer[attr].buffer = pipe_user_buffer_create(pipe->screen,
(void *) arrays[mesaAttr]->Ptr, bytes);
}
else {
/* no array, use ctx->Current.Attrib[] value */
bytes = sizeof(ctx->Current.Attrib[0]);
- vbuffer[attr].buffer = pipe_user_buffer_create(pipe,
+ vbuffer[attr].buffer = pipe_user_buffer_create(pipe->screen,
(void *) ctx->Current.Attrib[mesaAttr], bytes);
stride = 0;
}
@@ -346,27 +479,81 @@ st_draw_vbo(GLcontext *ctx,
arrays[mesaAttr]->Normalized);
assert(velements[attr].src_format);
}
+}
+
+
+
+
+/**
+ * This function gets plugged into the VBO module and is called when
+ * we have something to render.
+ * Basically, translate the information into the format expected by gallium.
+ */
+void
+st_draw_vbo(GLcontext *ctx,
+ const struct gl_client_array **arrays,
+ const struct _mesa_prim *prims,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index)
+{
+ struct pipe_context *pipe = ctx->st->pipe;
+ const struct st_vertex_program *vp;
+ const struct pipe_shader_state *vs;
+ struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
+ GLuint attr;
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
+ unsigned num_vbuffers, num_velements;
+ GLboolean userSpace;
+
+ /* sanity check for pointer arithmetic below */
+ assert(sizeof(arrays[0]->Ptr[0]) == 1);
+
+ st_validate_state(ctx->st);
+
+ /* must get these after state validation! */
+ vp = ctx->st->vp;
+ vs = &ctx->st->vp->state;
+
+ /*
+ * Setup the vbuffer[] and velements[] arrays.
+ */
+ if (is_interleaved_arrays(vp, arrays, &userSpace)) {
+ /*printf("Draw interleaved\n");*/
+ setup_interleaved_attribs(ctx, vp, arrays, max_index, userSpace,
+ vbuffer, velements);
+ num_vbuffers = 1;
+ num_velements = vp->num_inputs;
+ }
+ else {
+ /*printf("Draw non-interleaved\n");*/
+ setup_non_interleaved_attribs(ctx, vp, arrays, max_index,
+ vbuffer, velements);
+ num_vbuffers = vp->num_inputs;
+ num_velements = vp->num_inputs;
+ }
#if 0
{
GLuint i;
- for (i = 0; i < vp->num_inputs; i++) {
+ for (i = 0; i < num_vbuffers; i++) {
printf("buffers[%d].pitch = %u\n", i, vbuffer[i].pitch);
printf("buffers[%d].max_index = %u\n", i, vbuffer[i].max_index);
printf("buffers[%d].buffer_offset = %u\n", i, vbuffer[i].buffer_offset);
printf("buffers[%d].buffer = %p\n", i, (void*) vbuffer[i].buffer);
}
- for (i = 0; i < vp->num_inputs; i++) {
- printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset);
+ for (i = 0; i < num_velements; i++) {
printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index);
+ printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset);
printf("vlements[%d].nr_comps = %u\n", i, velements[i].nr_components);
printf("vlements[%d].format = %s\n", i, pf_name(velements[i].src_format));
}
}
#endif
- pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer);
- pipe->set_vertex_elements(pipe, vp->num_inputs, velements);
+ pipe->set_vertex_buffers(pipe, num_vbuffers, vbuffer);
+ pipe->set_vertex_elements(pipe, num_velements, velements);
/* do actual drawing */
if (ib) {
@@ -394,12 +581,12 @@ st_draw_vbo(GLcontext *ctx,
if (bufobj && bufobj->Name) {
/* elements/indexes are in a real VBO */
struct st_buffer_object *stobj = st_buffer_object(bufobj);
- pipe_reference_buffer(pipe, &indexBuf, stobj->buffer);
+ pipe_buffer_reference(pipe->screen, &indexBuf, stobj->buffer);
indexOffset = (unsigned) ib->ptr / indexSize;
}
else {
/* element/indicies are in user space memory */
- indexBuf = pipe_user_buffer_create(pipe, (void *) ib->ptr,
+ indexBuf = pipe_user_buffer_create(pipe->screen, (void *) ib->ptr,
ib->count * indexSize);
indexOffset = 0;
}
@@ -434,7 +621,7 @@ st_draw_vbo(GLcontext *ctx,
}
}
- pipe_reference_buffer(pipe, &indexBuf, NULL);
+ pipe_buffer_reference(pipe->screen, &indexBuf, NULL);
}
else {
/* non-indexed */
@@ -449,8 +636,8 @@ st_draw_vbo(GLcontext *ctx,
}
/* unreference buffers (frees wrapped user-space buffer objects) */
- for (attr = 0; attr < vp->num_inputs; attr++) {
- pipe_reference_buffer(pipe, &vbuffer[attr].buffer, NULL);
+ for (attr = 0; attr < num_vbuffers; attr++) {
+ pipe_buffer_reference(pipe->screen, &vbuffer[attr].buffer, NULL);
assert(!vbuffer[attr].buffer);
}
pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer);
@@ -563,7 +750,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
assert(stobj->buffer);
vbuffers[attr].buffer = NULL;
- pipe_reference_buffer(pipe, &vbuffers[attr].buffer, stobj->buffer);
+ pipe_buffer_reference(pipe->screen, &vbuffers[attr].buffer, stobj->buffer);
vbuffers[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
}
@@ -575,7 +762,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* wrap user data */
vbuffers[attr].buffer
- = pipe_user_buffer_create(pipe, (void *) arrays[mesaAttr]->Ptr,
+ = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr,
bytes);
vbuffers[attr].buffer_offset = 0;
velements[attr].src_offset = 0;
@@ -597,7 +784,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
#endif
/* map the attrib buffer */
- map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
+ map = pipe_buffer_map(pipe->screen, vbuffers[attr].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, attr, map);
}
@@ -625,7 +812,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
return;
}
- map = pipe_buffer_map(pipe, index_buffer_handle,
+ map = pipe_buffer_map(pipe->screen, index_buffer_handle,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, map);
}
@@ -636,7 +823,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* map constant buffers */
- mapped_constants = pipe_buffer_map(pipe,
+ mapped_constants = pipe_buffer_map(pipe->screen,
st->state.constants[PIPE_SHADER_VERTEX].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_constant_buffer(st->draw, mapped_constants,
@@ -650,20 +837,20 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* unmap constant buffers */
- pipe_buffer_unmap(pipe, st->state.constants[PIPE_SHADER_VERTEX].buffer);
+ pipe_buffer_unmap(pipe->screen, st->state.constants[PIPE_SHADER_VERTEX].buffer);
/*
* unmap vertex/index buffers
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (draw->pt.vertex_buffer[i].buffer) {
- pipe_buffer_unmap(pipe, draw->pt.vertex_buffer[i].buffer);
- pipe_reference_buffer(pipe, &draw->pt.vertex_buffer[i].buffer, NULL);
+ pipe_buffer_unmap(pipe->screen, draw->pt.vertex_buffer[i].buffer);
+ pipe_buffer_reference(pipe->screen, &draw->pt.vertex_buffer[i].buffer, NULL);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
if (ib) {
- pipe_buffer_unmap(pipe, index_buffer_handle);
+ pipe_buffer_unmap(pipe->screen, index_buffer_handle);
draw_set_mapped_element_buffer(draw, 0, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index 4012cf73e57..0f4a03fa484 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -74,7 +74,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
_mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
}
- if (visual->depthBits == 24 && visual->stencilBits == 8) {
+ if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {
/* combined depth/stencil buffer */
struct gl_renderbuffer *depthStencilRb
= st_new_renderbuffer_fb(depthFormat, samples);
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 6db9bc0dd58..b9d114b1c97 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -128,10 +128,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
PIPE_BUFFER_USAGE_CPU_WRITE);
- srcData = (ubyte *) pipe_buffer_map(pipe, srcSurf->buffer,
+ srcData = (ubyte *) pipe_buffer_map(pipe->screen, srcSurf->buffer,
PIPE_BUFFER_USAGE_CPU_READ)
+ srcSurf->offset;
- dstData = (ubyte *) pipe_buffer_map(pipe, dstSurf->buffer,
+ dstData = (ubyte *) pipe_buffer_map(pipe->screen, dstSurf->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE)
+ dstSurf->offset;
@@ -144,8 +144,8 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
dstSurf->stride, /* stride in bytes */
dstData);
- pipe_buffer_unmap(pipe, srcSurf->buffer);
- pipe_buffer_unmap(pipe, dstSurf->buffer);
+ pipe_buffer_unmap(pipe->screen, srcSurf->buffer);
+ pipe_buffer_unmap(pipe->screen, dstSurf->buffer);
pipe_surface_reference(&srcSurf, NULL);
pipe_surface_reference(&dstSurf, NULL);
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index ca4e9577b1b..5cfb2e41f24 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -41,6 +41,10 @@
#define ST_SURFACE_BACK_RIGHT 3
#define ST_SURFACE_DEPTH 8
+#define ST_TEXTURE_2D 0x2
+#define ST_TEXTURE_RGB 0x1
+#define ST_TEXTURE_RGBA 0x2
+
struct st_context;
struct st_framebuffer;
@@ -93,6 +97,15 @@ void st_notify_swapbuffers(struct st_framebuffer *stfb);
void st_notify_swapbuffers_complete(struct st_framebuffer *stfb);
+/** Redirect rendering into stfb's surface to a texture image */
+int st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
+ int target, int format, int level);
+
+/** Undo surface-to-texture binding */
+int st_release_teximage(struct st_framebuffer *stfb, uint surfIndex,
+ int target, int format, int level);
+
+
/** Generic function type */
typedef void (*st_proc)();
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 73cebff33f7..29b16347625 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -27,8 +27,11 @@
#include "st_context.h"
#include "st_format.h"
+#include "st_public.h"
#include "st_texture.h"
+#include "st_cb_fbo.h"
#include "main/enums.h"
+#include "main/teximage.h"
#undef Elements /* fix re-defined macro warning */
@@ -301,9 +304,6 @@ st_texture_image_copy(struct pipe_context *pipe,
struct pipe_surface *dst_surface;
GLuint i;
- /* XXX this is a hack */
- const GLuint copyHeight = dst->compressed ? height / 4 : height;
-
for (i = 0; i < depth; i++) {
GLuint srcLevel;
@@ -345,9 +345,97 @@ st_texture_image_copy(struct pipe_context *pipe,
0, 0, /* destX, Y */
src_surface,
0, 0, /* srcX, Y */
- width, copyHeight);
+ width, height);
screen->tex_surface_release(screen, &src_surface);
screen->tex_surface_release(screen, &dst_surface);
}
}
+
+
+/** Redirect rendering into stfb's surface to a texture image */
+int
+st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
+ int target, int format, int level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct st_context *st = ctx->st;
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ const GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ struct st_texture_image *stImage;
+ struct st_renderbuffer *strb;
+ GLint face = 0, slice = 0;
+
+ assert(surfIndex <= ST_SURFACE_DEPTH);
+
+ strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
+
+ if (strb->texture_save || strb->surface_save) {
+ /* Error! */
+ return 0;
+ }
+
+ if (target == ST_TEXTURE_2D) {
+ texObj = texUnit->Current2D;
+ texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, level);
+ stImage = st_texture_image(texImage);
+ }
+ else {
+ /* unsupported target */
+ return 0;
+ }
+
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ /* save the renderbuffer's surface/texture info */
+ pipe_texture_reference(&strb->texture_save, strb->texture);
+ pipe_surface_reference(&strb->surface_save, strb->surface);
+
+ /* plug in new surface/texture info */
+ pipe_texture_reference(&strb->texture, stImage->pt);
+ strb->surface = screen->get_tex_surface(screen, strb->texture,
+ face, level, slice,
+ (PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE));
+
+ st->dirty.st |= ST_NEW_FRAMEBUFFER;
+
+ return 1;
+}
+
+
+/** Undo surface-to-texture binding */
+int
+st_release_teximage(struct st_framebuffer *stfb, uint surfIndex,
+ int target, int format, int level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct st_context *st = ctx->st;
+ struct st_renderbuffer *strb;
+
+ assert(surfIndex <= ST_SURFACE_DEPTH);
+
+ strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
+
+ if (!strb->texture_save || !strb->surface_save) {
+ /* Error! */
+ return 0;
+ }
+
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ /* free tex surface, restore original */
+ pipe_surface_reference(&strb->surface, strb->surface_save);
+ pipe_texture_reference(&strb->texture, strb->texture_save);
+
+ pipe_surface_reference(&strb->surface_save, NULL);
+ pipe_texture_reference(&strb->texture_save, NULL);
+
+ st->dirty.st |= ST_NEW_FRAMEBUFFER;
+
+ return 1;
+}
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 3febe6a7cb0..31f66ad52cf 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -72,6 +72,12 @@ struct st_texture_object
};
+static INLINE struct st_texture_image *
+st_texture_image(struct gl_texture_image *img)
+{
+ return (struct st_texture_image *) img;
+}
+
static INLINE struct st_texture_object *
st_texture_object(struct gl_texture_object *obj)
{
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 1d095c772f9..7ec431a2376 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -188,7 +188,19 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
/* override the default array set above */
exec->vtx.inputs[attr] = &arrays[attr];
- 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);