summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c48
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c1
-rw-r--r--src/mesa/state_tracker/st_atom_rasterizer.c3
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c77
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.h12
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c133
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h1
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c11
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c3
-rw-r--r--src/mesa/state_tracker/st_context.h3
-rw-r--r--src/mesa/state_tracker/st_draw.c17
-rw-r--r--src/mesa/state_tracker/st_draw.h3
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c1
-rw-r--r--src/mesa/state_tracker/st_extensions.c23
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c125
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c6
-rw-r--r--src/mesa/state_tracker/st_program.c25
-rw-r--r--src/mesa/state_tracker/st_public.h4
18 files changed, 431 insertions, 65 deletions
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 3ba7b269285..5d4d8eee02f 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -24,11 +24,12 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <[email protected]>
- * Brian Paul
- */
+
+/*
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ * Brian Paul
+ */
#include "main/imports.h"
#include "shader/prog_parameter.h"
@@ -44,19 +45,21 @@
#include "st_program.h"
#include "st_inlines.h"
+
/**
* Pass the given program parameters to the graphics pipe as a
* constant buffer.
- * \param id either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
+ * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
*/
void st_upload_constants( struct st_context *st,
struct gl_program_parameter_list *params,
- unsigned id)
+ unsigned shader_type)
{
struct pipe_context *pipe = st->pipe;
- struct pipe_constant_buffer *cbuf = &st->state.constants[id];
+ struct pipe_constant_buffer *cbuf = &st->state.constants[shader_type];
- assert(id == PIPE_SHADER_VERTEX || id == PIPE_SHADER_FRAGMENT);
+ assert(shader_type == PIPE_SHADER_VERTEX ||
+ shader_type == PIPE_SHADER_FRAGMENT);
/* update constants */
if (params && params->NumParameters) {
@@ -68,13 +71,14 @@ void st_upload_constants( struct st_context *st,
* avoid gratuitous rendering synchronization.
*/
pipe_buffer_reference(&cbuf->buffer, NULL );
- cbuf->buffer = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT,
+ cbuf->buffer = pipe_buffer_create(pipe->screen, 16,
+ PIPE_BUFFER_USAGE_CONSTANT,
paramBytes );
- if (0)
- {
- printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
- __FUNCTION__, id, params->NumParameters, params->StateFlags);
+ if (0) {
+ debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
+ __FUNCTION__, shader_type, params->NumParameters,
+ params->StateFlags);
_mesa_print_parameter_list(params);
}
@@ -84,15 +88,16 @@ void st_upload_constants( struct st_context *st,
0, paramBytes,
params->ParameterValues);
- st->pipe->set_constant_buffer(st->pipe, id, 0, cbuf);
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
}
else {
- st->constants.tracked_state[id].dirty.mesa = 0;
- // st->pipe->set_constant_buffer(st->pipe, id, 0, NULL);
+ st->constants.tracked_state[shader_type].dirty.mesa = 0x0;
}
}
-/* Vertex shader:
+
+/**
+ * Vertex shader:
*/
static void update_vs_constants(struct st_context *st )
{
@@ -102,6 +107,7 @@ static void update_vs_constants(struct st_context *st )
st_upload_constants( st, params, PIPE_SHADER_VERTEX );
}
+
const struct st_tracked_state st_update_vs_constants = {
"st_update_vs_constants", /* name */
{ /* dirty */
@@ -111,7 +117,10 @@ const struct st_tracked_state st_update_vs_constants = {
update_vs_constants /* update */
};
-/* Fragment shader:
+
+
+/**
+ * Fragment shader:
*/
static void update_fs_constants(struct st_context *st )
{
@@ -121,6 +130,7 @@ static void update_fs_constants(struct st_context *st )
st_upload_constants( st, params, PIPE_SHADER_FRAGMENT );
}
+
const struct st_tracked_state st_update_fs_constants = {
"st_update_fs_constants", /* name */
{ /* dirty */
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 3ef919a45e9..5209a6a0c9c 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -122,6 +122,7 @@ update_framebuffer_state( struct st_context *st )
strb->surface);
framebuffer->nr_cbufs++;
}
+ strb->defined = GL_TRUE; /* we'll be drawing something */
}
}
for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index 5c7206409cf..36b28cb4df9 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -102,6 +102,9 @@ static void update_raster_state( struct st_context *st )
if (ctx->Light.ShadeModel == GL_FLAT)
raster->flatshade = 1;
+ if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT)
+ raster->flatshade_first = 1;
+
/* _NEW_LIGHT | _NEW_PROGRAM
*
* Back-face colors can come from traditional lighting (when
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index a627c0374ad..8c1fd5ce025 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -26,8 +26,14 @@
**************************************************************************/
+/**
+ * Functions for pixel buffer objects and vertex/element buffer objects.
+ */
+
+
#include "main/imports.h"
#include "main/mtypes.h"
+#include "main/arrayobj.h"
#include "main/bufferobj.h"
#include "st_inlines.h"
@@ -39,14 +45,6 @@
#include "pipe/p_inlines.h"
-
-/* Pixel buffers and Vertex/index buffers are handled through these
- * mesa callbacks. Framebuffer/Renderbuffer objects are
- * created/managed elsewhere.
- */
-
-
-
/**
* There is some duplication between mesa's bufferobjects and our
* bufmgr buffers. Both have an integer handle and a hashtable to
@@ -100,8 +98,10 @@ st_bufferobj_subdata(GLcontext *ctx,
{
struct st_buffer_object *st_obj = st_buffer_object(obj);
- if (offset >= st_obj->size || size > (st_obj->size - offset))
- return;
+ /* we may be called from VBO code, so double-check params here */
+ ASSERT(offset >= 0);
+ ASSERT(size >= 0);
+ ASSERT(offset + size <= obj->Size);
st_cond_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer,
offset, size, data);
@@ -120,8 +120,10 @@ st_bufferobj_get_subdata(GLcontext *ctx,
{
struct st_buffer_object *st_obj = st_buffer_object(obj);
- if (offset >= st_obj->size || size > (st_obj->size - offset))
- return;
+ /* we may be called from VBO code, so double-check params here */
+ ASSERT(offset >= 0);
+ ASSERT(size >= 0);
+ ASSERT(offset + size <= obj->Size);
st_cond_flush_pipe_buffer_read(st_context(ctx), st_obj->buffer,
offset, size, data);
@@ -174,8 +176,6 @@ st_bufferobj_data(GLcontext *ctx,
return;
}
- st_obj->size = size;
-
if (data)
st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
size, data);
@@ -190,7 +190,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
struct gl_buffer_object *obj)
{
struct st_buffer_object *st_obj = st_buffer_object(obj);
- GLuint flags;
+ uint flags;
switch (access) {
case GL_WRITE_ONLY:
@@ -209,7 +209,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
obj->Pointer = st_cond_flush_pipe_buffer_map(st_context(ctx),
st_obj->buffer,
flags);
- if(obj->Pointer) {
+ if (obj->Pointer) {
obj->Offset = 0;
obj->Length = obj->Size;
}
@@ -217,7 +217,6 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
}
-
/**
* Called via glMapBufferRange().
*/
@@ -228,7 +227,7 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
{
struct pipe_context *pipe = st_context(ctx)->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
- GLuint flags = 0;
+ uint flags = 0x0;
char *map;
if (access & GL_MAP_WRITE_BIT)
@@ -297,6 +296,43 @@ st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
}
+/**
+ * Called via glCopyBufferSubData().
+ */
+static void
+st_copy_buffer_subdata(GLcontext *ctx,
+ struct gl_buffer_object *src,
+ struct gl_buffer_object *dst,
+ GLintptr readOffset, GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct st_buffer_object *srcObj = st_buffer_object(src);
+ struct st_buffer_object *dstObj = st_buffer_object(dst);
+ ubyte *srcPtr, *dstPtr;
+
+ /* buffer should not already be mapped */
+ assert(!src->Pointer);
+ assert(!dst->Pointer);
+
+ srcPtr = (ubyte *) pipe_buffer_map_range(pipe->screen,
+ srcObj->buffer,
+ readOffset, size,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ dstPtr = (ubyte *) pipe_buffer_map_range(pipe->screen,
+ dstObj->buffer,
+ writeOffset, size,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ if (srcPtr && dstPtr)
+ _mesa_memcpy(dstPtr + writeOffset, srcPtr + readOffset, size);
+
+ pipe_buffer_unmap(pipe->screen, srcObj->buffer);
+ pipe_buffer_unmap(pipe->screen, dstObj->buffer);
+}
+
+
void
st_init_bufferobject_functions(struct dd_function_table *functions)
{
@@ -309,4 +345,9 @@ st_init_bufferobject_functions(struct dd_function_table *functions)
functions->MapBufferRange = st_bufferobj_map_range;
functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range;
functions->UnmapBuffer = st_bufferobj_unmap;
+ functions->CopyBufferSubData = st_copy_buffer_subdata;
+
+ /* For GL_APPLE_vertex_array_object */
+ functions->NewArrayObject = _mesa_new_array_object;
+ functions->DeleteArrayObject = _mesa_delete_array_object;
}
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.h b/src/mesa/state_tracker/st_cb_bufferobjects.h
index dcbb5a52336..fda6d05dd34 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.h
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.h
@@ -40,22 +40,14 @@ struct st_buffer_object
{
struct gl_buffer_object Base;
struct pipe_buffer *buffer;
- GLsizeiptrARB size;
};
-/* Are the obj->Name tests necessary? Unfortunately yes, mesa
- * allocates a couple of gl_buffer_object structs statically, and the
- * Name == 0 test is the only way to identify them and avoid casting
- * them erroneously to our structs.
- */
+/** cast wrapper */
static INLINE struct st_buffer_object *
st_buffer_object(struct gl_buffer_object *obj)
{
- if (obj->Name)
- return (struct st_buffer_object *) obj;
- else
- return NULL;
+ return (struct st_buffer_object *) obj;
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 21ddf2fc7a2..ecdb988033c 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -100,6 +100,8 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
strb->Base.Height = height;
init_renderbuffer_bits(strb, format);
+ strb->defined = GL_FALSE; /* undefined contents now */
+
if(strb->software) {
struct pipe_format_block block;
size_t size;
@@ -463,6 +465,134 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
}
+/**
+ * Copy back color buffer to front color buffer.
+ */
+static void
+copy_back_to_front(struct st_context *st,
+ struct gl_framebuffer *fb,
+ gl_buffer_index frontIndex,
+ gl_buffer_index backIndex)
+
+{
+ struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
+ struct pipe_surface *surf_front, *surf_back;
+
+ (void) st_get_framebuffer_surface(stfb, frontIndex, &surf_front);
+ (void) st_get_framebuffer_surface(stfb, backIndex, &surf_back);
+
+ if (surf_front && surf_back) {
+ st->pipe->surface_copy(st->pipe,
+ surf_front, 0, 0, /* dest */
+ surf_back, 0, 0, /* src */
+ fb->Width, fb->Height);
+ }
+}
+
+
+/**
+ * Check if we're drawing into, or read from, a front color buffer. If the
+ * front buffer is missing, create it now.
+ *
+ * The back color buffer must exist since we'll use its format/samples info
+ * for creating the front buffer.
+ *
+ * \param frontIndex either BUFFER_FRONT_LEFT or BUFFER_FRONT_RIGHT
+ * \param backIndex either BUFFER_BACK_LEFT or BUFFER_BACK_RIGHT
+ */
+static void
+check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ gl_buffer_index frontIndex,
+ gl_buffer_index backIndex)
+{
+ if (fb->Attachment[frontIndex].Renderbuffer == NULL) {
+ GLboolean create = GL_FALSE;
+
+ /* check if drawing to or reading from front buffer */
+ if (fb->_ColorReadBufferIndex == frontIndex) {
+ create = GL_TRUE;
+ }
+ else {
+ GLuint b;
+ for (b = 0; b < fb->_NumColorDrawBuffers; b++) {
+ if (fb->_ColorDrawBufferIndexes[b] == frontIndex) {
+ create = GL_TRUE;
+ break;
+ }
+ }
+ }
+
+ if (create) {
+ struct st_renderbuffer *back;
+ struct gl_renderbuffer *front;
+ enum pipe_format colorFormat;
+ uint samples;
+
+ if (0)
+ _mesa_debug(ctx, "Allocate new front buffer\n");
+
+ /* get back renderbuffer info */
+ back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer);
+ colorFormat = back->format;
+ samples = back->Base.NumSamples;
+
+ /* create front renderbuffer */
+ front = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
+ _mesa_add_renderbuffer(fb, frontIndex, front);
+
+ /* alloc texture/surface for new front buffer */
+ front->AllocStorage(ctx, front, front->InternalFormat,
+ fb->Width, fb->Height);
+
+ /* initialize the front color buffer contents by copying
+ * the back buffer.
+ */
+ copy_back_to_front(ctx->st, fb, frontIndex, backIndex);
+ }
+ }
+}
+
+
+/**
+ * If front left/right color buffers are missing, create them now.
+ */
+static void
+check_create_front_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ /* check if we need to create the front left buffer now */
+ check_create_front_buffer(ctx, fb, BUFFER_FRONT_LEFT, BUFFER_BACK_LEFT);
+
+ if (fb->Visual.stereoMode) {
+ check_create_front_buffer(ctx, fb, BUFFER_FRONT_RIGHT, BUFFER_BACK_RIGHT);
+ }
+
+ st_invalidate_state(ctx, _NEW_BUFFERS);
+}
+
+
+/**
+ * Called via glDrawBuffer.
+ */
+static void
+st_DrawBuffers(GLcontext *ctx, GLsizei count, const GLenum *buffers)
+{
+ (void) count;
+ (void) buffers;
+ check_create_front_buffers(ctx, ctx->DrawBuffer);
+}
+
+
+/**
+ * Called via glReadBuffer.
+ */
+static void
+st_ReadBuffer(GLcontext *ctx, GLenum buffer)
+{
+ (void) buffer;
+ check_create_front_buffers(ctx, ctx->ReadBuffer);
+}
+
+
void st_init_fbo_functions(struct dd_function_table *functions)
{
functions->NewFramebuffer = st_new_framebuffer;
@@ -475,4 +605,7 @@ void st_init_fbo_functions(struct dd_function_table *functions)
/* no longer needed by core Mesa, drivers handle resizes...
functions->ResizeBuffers = st_resize_buffers;
*/
+
+ functions->DrawBuffers = st_DrawBuffers;
+ functions->ReadBuffer = st_ReadBuffer;
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index 9a199550d9f..bea6eb89c3e 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -40,6 +40,7 @@ struct st_renderbuffer
struct pipe_texture *texture;
struct pipe_surface *surface; /* temporary view into texture */
enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
+ GLboolean defined; /**< defined contents? */
/**
* Used only when hardware accumulation buffers are not supported.
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index fbaffd154f9..8ceeeabcd37 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -47,10 +47,19 @@
#include "util/u_blit.h"
+/** Check if we have a front color buffer and if it's been drawn to. */
static INLINE GLboolean
is_front_buffer_dirty(struct st_context *st)
{
- return st->frontbuffer_status == FRONT_STATUS_DIRTY;
+ if (st->frontbuffer_status == FRONT_STATUS_DIRTY) {
+ return GL_TRUE;
+ }
+ else {
+ GLframebuffer *fb = st->ctx->DrawBuffer;
+ struct st_renderbuffer *strb
+ = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ return strb && strb->defined;
+ }
}
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 7dd23527399..3bcccd0df46 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -194,9 +194,10 @@ new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw)
rs->stage.destroy = rastpos_destroy;
rs->ctx = ctx;
- for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ for (i = 0; i < Elements(rs->array); i++) {
rs->array[i].Size = 4;
rs->array[i].Type = GL_FLOAT;
+ rs->array[i].Format = GL_RGBA;
rs->array[i].Stride = 0;
rs->array[i].StrideB = 0;
rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 6ffed56d9a0..18adb35e872 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -45,6 +45,7 @@ struct blit_state;
struct bitmap_cache;
+/** XXX we'd like to get rid of these */
#define FRONT_STATUS_UNDEFINED 0
#define FRONT_STATUS_DIRTY 1
#define FRONT_STATUS_COPY_OF_BACK 2
@@ -111,7 +112,7 @@ struct st_context
struct gl_fragment_program *fragment_program;
} cb;
- GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */
+ GLuint frontbuffer_status; /**< one of FRONT_STATUS_ (XXX to be removed) */
char vendor[100];
char renderer[100];
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 225541a30ba..914a507bef6 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -159,12 +159,21 @@ static GLuint fixed_types[4] = {
* Return a PIPE_FORMAT_x for the given GL datatype and size.
*/
GLuint
-st_pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized)
+st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
+ GLboolean normalized)
{
assert((type >= GL_BYTE && type <= GL_DOUBLE) ||
type == GL_FIXED);
assert(size >= 1);
assert(size <= 4);
+ assert(format == GL_RGBA || format == GL_BGRA);
+
+ if (format == GL_BGRA) {
+ /* this is an odd-ball case */
+ assert(type == GL_UNSIGNED_BYTE);
+ assert(normalized);
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ }
if (normalized) {
switch (type) {
@@ -220,8 +229,10 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
struct st_buffer_object *stobj = st_buffer_object(array->BufferObj);
ubyte *map;
- if (!stobj)
+ 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)
@@ -392,6 +403,7 @@ setup_interleaved_attribs(GLcontext *ctx,
velements[attr].src_format =
st_pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Format,
arrays[mesaAttr]->Normalized);
assert(velements[attr].src_format);
}
@@ -479,6 +491,7 @@ setup_non_interleaved_attribs(GLcontext *ctx,
velements[attr].src_format
= st_pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Format,
arrays[mesaAttr]->Normalized);
assert(velements[attr].src_format);
}
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index da04fce8e24..dcfe7e15361 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -62,7 +62,8 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* Internal function:
*/
extern GLuint
-st_pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized);
+st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
+ GLboolean normalized);
/**
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 32502a9cda4..2712c131c0d 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -178,6 +178,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
velements[attr].src_format =
st_pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Format,
arrays[mesaAttr]->Normalized);
assert(velements[attr].src_format);
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index e6728ae8955..8a958e8bd88 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -143,19 +143,21 @@ void st_init_extensions(struct st_context *st)
/*
* Extensions that are supported by all Gallium drivers:
*/
- ctx->Extensions.ARB_multisample = GL_TRUE;
+ ctx->Extensions.ARB_copy_buffer = GL_TRUE;
ctx->Extensions.ARB_fragment_program = GL_TRUE;
+ ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
+ ctx->Extensions.ARB_multisample = GL_TRUE;
ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */
ctx->Extensions.ARB_texture_compression = GL_TRUE;
ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
- ctx->Extensions.ARB_vertex_program = GL_TRUE;
+ ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
+ ctx->Extensions.ARB_vertex_program = GL_TRUE;
ctx->Extensions.EXT_blend_color = GL_TRUE;
- ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
ctx->Extensions.EXT_blend_minmax = GL_TRUE;
@@ -166,15 +168,20 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
ctx->Extensions.EXT_point_parameters = GL_TRUE;
+ ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
ctx->Extensions.EXT_secondary_color = GL_TRUE;
ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
ctx->Extensions.EXT_texture_env_add = GL_TRUE;
ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
+ ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
+
+ ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
ctx->Extensions.NV_blend_square = GL_TRUE;
ctx->Extensions.NV_texgen_reflection = GL_TRUE;
+ ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
ctx->Extensions.SGI_color_matrix = GL_TRUE;
ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
@@ -198,6 +205,10 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
}
+ if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) {
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
+ }
+
if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_CLAMP) > 0) {
ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
}
@@ -282,4 +293,10 @@ void st_init_extensions(struct st_context *st)
PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
}
+
+ /* GL_ARB_framebuffer_object */
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ /* we support always support GL_EXT_framebuffer_blit */
+ ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
+ }
}
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index fe99fc08926..ca32b2e573c 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -58,19 +58,19 @@ st_create_framebuffer( const __GLcontextModes *visual,
_mesa_initialize_framebuffer(&stfb->Base, visual);
- {
- /* fake frontbuffer */
- /* XXX allocation should only happen in the unusual case
- it's actually needed */
+ if (visual->doubleBufferMode) {
struct gl_renderbuffer *rb
= st_new_renderbuffer_fb(colorFormat, samples, FALSE);
- _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
+ _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
}
-
- if (visual->doubleBufferMode) {
+ else {
+ /* Only allocate front buffer right now if we're single buffered.
+ * If double-buffered, allocate front buffer on demand later.
+ * See check_create_front_buffers().
+ */
struct gl_renderbuffer *rb
= st_new_renderbuffer_fb(colorFormat, samples, FALSE);
- _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
+ _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
}
if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {
@@ -286,6 +286,115 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
}
+/**
+ * Swap the front/back color buffers. Exchange the front/back pointers
+ * and update some derived state.
+ * No need to call st_notify_swapbuffers() first.
+ *
+ * For a single-buffered framebuffer, no swap occurs, but we still return
+ * the pointer(s) to the front color buffer(s).
+ *
+ * \param front_left returns pointer to front-left renderbuffer after swap
+ * \param front_right returns pointer to front-right renderbuffer after swap
+ */
+void
+st_swapbuffers(struct st_framebuffer *stfb,
+ struct pipe_surface **front_left,
+ struct pipe_surface **front_right)
+{
+ struct gl_framebuffer *fb = &stfb->Base;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (ctx && ctx->DrawBuffer == &stfb->Base) {
+ st_flush( ctx->st,
+ PIPE_FLUSH_RENDER_CACHE |
+ PIPE_FLUSH_SWAPBUFFERS |
+ PIPE_FLUSH_FRAME,
+ NULL );
+ }
+
+ if (!fb->Visual.doubleBufferMode) {
+ /* single buffer mode - return pointers to front surfaces */
+ if (front_left) {
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ *front_left = strb->surface;
+ }
+ if (front_right) {
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer);
+ *front_right = strb ? strb->surface : NULL;
+ }
+ return;
+ }
+
+ /* swap left buffers */
+ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) {
+ struct gl_renderbuffer *rbTemp;
+ rbTemp = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer =
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer = rbTemp;
+ if (front_left) {
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ *front_left = strb->surface;
+ }
+ /* mark back buffer contents as undefined */
+ {
+ struct st_renderbuffer *back =
+ st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+ back->defined = GL_FALSE;
+ }
+ }
+ else {
+ /* no front buffer, display the back buffer */
+ if (front_left) {
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+ *front_left = strb->surface;
+ }
+ }
+
+ /* swap right buffers (for stereo) */
+ if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) {
+ struct gl_renderbuffer *rbTemp;
+ rbTemp = fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer;
+ fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer =
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer;
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer = rbTemp;
+ if (front_right) {
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer);
+ *front_right = strb->surface;
+ }
+ /* mark back buffer contents as undefined */
+ {
+ struct st_renderbuffer *back =
+ st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
+ back->defined = GL_FALSE;
+ }
+ }
+ else {
+ /* no front right buffer, display back right buffer (if exists) */
+ if (front_right) {
+ struct st_renderbuffer *strb =
+ st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
+ *front_right = strb ? strb->surface : NULL;
+ }
+ }
+
+ /* Update the _ColorDrawBuffers[] array and _ColorReadBuffer pointer */
+ _mesa_update_framebuffer(ctx);
+
+ /* Make sure we draw into the new back surface */
+ st_invalidate_state(ctx, _NEW_BUFFERS);
+}
+
+
void *st_framebuffer_private( struct st_framebuffer *stfb )
{
return stfb->Private;
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index e150dff9bbc..6380cd6b2a8 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -225,11 +225,15 @@ static struct tgsi_full_immediate
make_immediate(const float *value, uint size)
{
struct tgsi_full_immediate imm;
+ unsigned i;
imm = tgsi_default_full_immediate();
imm.Immediate.NrTokens += size;
imm.Immediate.DataType = TGSI_IMM_FLOAT32;
- imm.u.Pointer = value;
+
+ for (i = 0; i < size; i++)
+ imm.u[i].Float = value[i];
+
return imm;
}
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 18d10468317..806e0ca8f65 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -151,6 +151,7 @@ st_translate_vertex_program(struct st_context *st,
case VERT_ATTRIB_TEX5:
case VERT_ATTRIB_TEX6:
case VERT_ATTRIB_TEX7:
+ assert(slot < Elements(vs_input_semantic_name));
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
vs_input_semantic_index[slot] = num_generic++;
break;
@@ -171,6 +172,7 @@ st_translate_vertex_program(struct st_context *st,
case VERT_ATTRIB_GENERIC14:
case VERT_ATTRIB_GENERIC15:
assert(attr < VERT_ATTRIB_MAX);
+ assert(slot < Elements(vs_input_semantic_name));
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
vs_input_semantic_index[slot] = num_generic++;
break;
@@ -198,6 +200,7 @@ st_translate_vertex_program(struct st_context *st,
/* initialize output semantics to defaults */
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
+ assert(i < Elements(vs_output_semantic_name));
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
vs_output_semantic_index[i] = 0;
output_flags[i] = 0x0;
@@ -273,6 +276,7 @@ st_translate_vertex_program(struct st_context *st,
case VERT_RESULT_VAR0:
/* fall-through */
default:
+ assert(slot < Elements(vs_output_semantic_name));
if (outputSemanticName) {
/* use provided semantic into */
assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
@@ -286,6 +290,7 @@ st_translate_vertex_program(struct st_context *st,
}
}
+ assert(slot < Elements(output_flags));
output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
}
}
@@ -303,6 +308,26 @@ st_translate_vertex_program(struct st_context *st,
outputMapping = defaultOutputMapping;
}
+#if 0 /* debug */
+ {
+ GLuint i;
+ printf("outputMapping? %d\n", outputMapping ? 1 : 0);
+ if (outputMapping) {
+ printf("attr -> slot\n");
+ for (i = 0; i < 16; i++) {
+ printf(" %2d %3d\n", i, outputMapping[i]);
+ }
+ }
+ printf("slot sem_name sem_index\n");
+ for (i = 0; i < vs_num_outputs; i++) {
+ printf(" %2d %d %d\n",
+ i,
+ vs_output_semantic_name[i],
+ vs_output_semantic_index[i]);
+ }
+ }
+#endif
+
/* free old shader state, if any */
if (stvp->state.tokens) {
_mesa_free((void *) stvp->state.tokens);
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index c411687bb64..04d3a3d7c2c 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -103,6 +103,10 @@ void st_finish( struct st_context *st );
void st_notify_swapbuffers(struct st_framebuffer *stfb);
+void st_swapbuffers(struct st_framebuffer *stfb,
+ struct pipe_surface **front_left,
+ struct pipe_surface **front_right);
+
int st_set_teximage(struct pipe_texture *pt, int target);
/** Redirect rendering into stfb's surface to a texture image */