diff options
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_atom_constbuf.c | 48 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_framebuffer.c | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_rasterizer.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.c | 77 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.h | 12 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_fbo.c | 133 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_fbo.h | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_flush.c | 11 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_rasterpos.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 17 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.h | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw_feedback.c | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_extensions.c | 23 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_framebuffer.c | 125 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 6 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 25 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_public.h | 4 |
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 */ |