diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/shader/slang/slang_preprocess.c | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_framebuffer.c | 23 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 8 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_flush.c | 107 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_readpixels.c | 35 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_readpixels.h | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 15 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_extensions.c | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_framebuffer.c | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 6 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec.h | 3 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec_api.c | 31 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec_array.c | 15 | ||||
-rw-r--r-- | src/mesa/x86/rtasm/x86sse.c | 9 |
16 files changed, 176 insertions, 93 deletions
diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c index 076e982f8f..1645afcc18 100644 --- a/src/mesa/shader/slang/slang_preprocess.c +++ b/src/mesa/shader/slang/slang_preprocess.c @@ -483,6 +483,7 @@ pp_cond_stack_reevaluate (pp_cond_stack *self) typedef struct { GLboolean MESA_shader_debug; /* GL_MESA_shader_debug enable */ + GLboolean ARB_texture_rectangle; /* GL_ARB_texture_rectangle enable */ } pp_ext; /* @@ -498,6 +499,7 @@ static GLvoid pp_ext_init (pp_ext *self) { pp_ext_disable_all (self); + self->ARB_texture_rectangle = GL_TRUE; /* Other initialization code goes here. */ } @@ -506,6 +508,8 @@ pp_ext_set (pp_ext *self, const char *name, GLboolean enable) { if (_mesa_strcmp (name, "MESA_shader_debug") == 0) self->MESA_shader_debug = enable; + else if (_mesa_strcmp (name, "GL_ARB_texture_rectangle") == 0) + self->ARB_texture_rectangle = enable; /* Next extension name tests go here. */ else return GL_FALSE; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 02573af8f0..14eeb58cc1 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -48,7 +48,7 @@ update_framebuffer_state( struct st_context *st ) struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer; struct gl_framebuffer *fb = st->ctx->DrawBuffer; struct st_renderbuffer *strb; - GLuint i; + GLuint i, j; memset(framebuffer, 0, sizeof(*framebuffer)); @@ -58,11 +58,14 @@ update_framebuffer_state( struct st_context *st ) /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state * to determine which surfaces to draw to */ - framebuffer->num_cbufs = fb->_NumColorDrawBuffers[0]; - for (i = 0; i < framebuffer->num_cbufs; i++) { - strb = st_renderbuffer(fb->_ColorDrawBuffers[0][i]); - assert(strb->surface); - framebuffer->cbufs[i] = strb->surface; + framebuffer->num_cbufs = 0; + for (j = 0; j < MAX_DRAW_BUFFERS; j++) { + for (i = 0; i < fb->_NumColorDrawBuffers[j]; i++) { + strb = st_renderbuffer(fb->_ColorDrawBuffers[j][i]); + assert(strb->surface); + framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface; + framebuffer->num_cbufs++; + } } strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); @@ -81,6 +84,14 @@ update_framebuffer_state( struct st_context *st ) } cso_set_framebuffer(st->cso_context, framebuffer); + + if (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT) { + if (st->frontbuffer_status == FRONT_STATUS_COPY_OF_BACK) { + /* XXX copy back buf to front? */ + } + /* we're assuming we'll really draw to the front buffer */ + st->frontbuffer_status = FRONT_STATUS_DIRTY; + } } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c57e05312a..5f8c90cbba 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -961,7 +961,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (type == GL_COLOR) { - rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + rbRead = st_get_color_read_renderbuffer(ctx); color = NULL; stfp = combined_drawpix_fragment_program(ctx); stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE); @@ -1017,11 +1017,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, srcy = ctx->DrawBuffer->Height - srcy - height; } - /* For some drivers (like Xlib) it's not possible to treat the - * front/back color buffers as surfaces (they're XImages and Pixmaps). - * So, this var tells us if we can use surface_copy here... - */ - if (st->haveFramebufferSurfaces && srcFormat == texFormat) { + if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ pipe->surface_copy(pipe, FALSE, diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index c7efa40e38..1b3402cee2 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -44,76 +44,47 @@ #include "pipe/p_winsys.h" -void st_flush( struct st_context *st, uint pipeFlushFlags, - struct pipe_fence_handle **fence ) +static INLINE GLboolean +is_front_buffer_dirty(struct st_context *st) { - FLUSH_VERTICES(st->ctx, 0); - - st_flush_bitmap_cache(st); - - st->pipe->flush( st->pipe, pipeFlushFlags, fence ); + return st->frontbuffer_status == FRONT_STATUS_DIRTY; } -static void st_gl_flush( struct st_context *st, uint pipeFlushFlags, - struct pipe_fence_handle **fence ) +/** + * Tell the winsys to display the front color buffer on-screen. + */ +static void +display_front_buffer(struct st_context *st) { GLframebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + struct pipe_surface *front_surf = strb->surface; - st_flush_bitmap_cache(st); - - FLUSH_VERTICES(st->ctx, 0); - - if (!fb) - return; - - /* XXX: temporary hack. This flag should only be set if we do any - * rendering to the front buffer. - * - * Further more, the scissor rectangle could be tracked to - * construct a dirty region of the front buffer, to avoid - * situations where it must be copied repeatedly. - * - * In the extreme case, some kind of timer could be set up to allow - * coalescing of multiple flushes to the frontbuffer, which can be - * quite a performance drain if there are a sufficient number of - * them. + /* Hook for copying "fake" frontbuffer if necessary: */ - st->flags.frontbuffer_dirty - = (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT); - - if (st->flags.frontbuffer_dirty) { - struct st_renderbuffer *strb - = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); - struct pipe_surface *front_surf = strb->surface; - - /* If we aren't rendering to the frontbuffer, this is a noop. - * This should be uncontroversial for glFlush, though people may - * feel more strongly about glFinish. - * - * Additionally, need to make sure that the frontbuffer_dirty - * flag really gets set on frontbuffer rendering. - */ - st->pipe->flush( st->pipe, pipeFlushFlags, fence ); - - /* Hook for copying "fake" frontbuffer if necessary: - */ - st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, - st->pipe->priv ); - st->flags.frontbuffer_dirty = 0; - } + st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, + st->pipe->priv ); + + st->frontbuffer_status = FRONT_STATUS_UNDEFINED; } -/** - * Called via ctx->Driver.Flush() - */ -static void st_glFlush(GLcontext *ctx) +void st_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ) { - st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + FLUSH_VERTICES(st->ctx, 0); + + st_flush_bitmap_cache(st); + + st->pipe->flush( st->pipe, pipeFlushFlags, fence ); } +/** + * Flush, and wait for completion. + */ void st_finish( struct st_context *st ) { struct pipe_fence_handle *fence = NULL; @@ -125,12 +96,36 @@ void st_finish( struct st_context *st ) } + +/** + * Called via ctx->Driver.Flush() + */ +static void st_glFlush(GLcontext *ctx) +{ + struct st_context *st = ctx->st; + + if (is_front_buffer_dirty(st)) { + st_finish(st); + display_front_buffer(st); + } + else { + st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); + } +} + + /** * Called via ctx->Driver.Finish() */ static void st_glFinish(GLcontext *ctx) { - st_finish( ctx->st ); + struct st_context *st = ctx->st; + + st_finish(st); + + if (is_front_buffer_dirty(st)) { + display_front_buffer(st); + } } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 2bcc8c99fb..1fef55b844 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -129,6 +129,34 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /** + * Return renderbuffer to use for reading color pixels for glRead/CopyPixel + * commands. + * Special care is needed for the front buffer. + */ +struct st_renderbuffer * +st_get_color_read_renderbuffer(GLcontext *ctx) +{ + struct gl_framebuffer *fb = ctx->ReadBuffer; + struct st_renderbuffer *strb = + st_renderbuffer(fb->_ColorReadBuffer); + struct st_renderbuffer *front = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + + if (strb == front + && ctx->st->frontbuffer_status == FRONT_STATUS_COPY_OF_BACK) { + /* reading from front color buffer, which is a logical copy of the + * back color buffer. + */ + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + strb = back; + } + + return strb; +} + + +/** * Do glReadPixels by getting rows from the framebuffer surface with * get_tile(). Convert to requested format/type with Mesa image routines. * Image transfer ops are done in software too. @@ -173,12 +201,13 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, strb = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); } else { - strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + /* Read color buffer */ + strb = st_get_color_read_renderbuffer(ctx); } + if (!strb) return; - if (format == GL_RGBA && type == GL_FLOAT) { /* write tile(row) directly into user's buffer */ df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width, @@ -240,7 +269,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) { for (i = 0; i < height; i++) { - GLshort ztemp[MAX_WIDTH], j; + GLushort ztemp[MAX_WIDTH], j; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffff; pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0); diff --git a/src/mesa/state_tracker/st_cb_readpixels.h b/src/mesa/state_tracker/st_cb_readpixels.h index 79acdad88e..9e151be51f 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.h +++ b/src/mesa/state_tracker/st_cb_readpixels.h @@ -29,6 +29,9 @@ #ifndef ST_CB_READPIXELS_H #define ST_CB_READPIXELS_H +extern struct st_renderbuffer * +st_get_color_read_renderbuffer(GLcontext *ctx); + extern void st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 43b43ec14c..3db2790267 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -41,6 +41,7 @@ #include "state_tracker/st_cb_fbo.h" #include "state_tracker/st_cb_texture.h" #include "state_tracker/st_format.h" +#include "state_tracker/st_public.h" #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" @@ -1033,6 +1034,8 @@ fallback_copy_texsubimage(GLcontext *ctx, GLfloat *data; GLint row, yStep; + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* determine bottom-to-top vs. top-to-bottom order */ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { destY = height - 1 - destY; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 7511c28074..154327239d 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -128,8 +128,6 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - st->haveFramebufferSurfaces = GL_TRUE; - st->pixel_xfer.cache = _mesa_new_program_cache(); /* GL limits and extensions */ diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index bcebbd4943..d89e54c43c 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -45,6 +45,11 @@ struct blit_state; struct bitmap_cache; +#define FRONT_STATUS_UNDEFINED 0 +#define FRONT_STATUS_DIRTY 1 +#define FRONT_STATUS_COPY_OF_BACK 2 + + #define ST_NEW_MESA 0x1 /* Mesa state has changed */ #define ST_NEW_FRAGMENT_PROGRAM 0x2 #define ST_NEW_VERTEX_PROGRAM 0x4 @@ -104,19 +109,11 @@ struct st_context struct gl_fragment_program *fragment_program; } cb; - struct { - GLuint frontbuffer_dirty:1; - } flags; + GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */ char vendor[100]; char renderer[100]; - /** Can we access the front/back color buffers as pipe_surfaces? - * We can't with the Xlib driver... - * This is a hack that should be fixed someday. - */ - GLboolean haveFramebufferSurfaces; - /* State to be validated: */ struct st_tracked_state **atoms; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 47a50d40ca..2f7ac074da 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -111,6 +111,10 @@ void st_init_limits(struct st_context *st) st->bitmap_texcoord_bias = screen->get_paramf(screen, PIPE_CAP_BITMAP_TEXCOORD_BIAS); + + c->MaxDrawBuffers + = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), + 1, MAX_DRAW_BUFFERS); } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index ea09d9234c..47466c97d8 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -188,6 +188,7 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) st_flush( ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS, NULL ); + ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK; } } diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 578fd2ecb0..524b5af50b 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -767,12 +767,14 @@ tgsi_translate_mesa_program( switch (outputSemanticName[i]) { case TGSI_SEMANTIC_POSITION: fulldecl = make_output_decl(i, - TGSI_SEMANTIC_POSITION, 0, /* Z / Depth */ + TGSI_SEMANTIC_POSITION, /* Z / Depth */ + outputSemanticIndex[i], TGSI_WRITEMASK_Z ); break; case TGSI_SEMANTIC_COLOR: fulldecl = make_output_decl(i, - TGSI_SEMANTIC_COLOR, 0, + TGSI_SEMANTIC_COLOR, + outputSemanticIndex[i], TGSI_WRITEMASK_XYZW ); break; default: diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index b7e8c9fe79..ddbcbe1181 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -162,4 +162,7 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec, void vbo_exec_do_EvalCoord1f( struct vbo_exec_context *exec, GLfloat u); +extern GLboolean +vbo_validate_shaders(GLcontext *ctx); + #endif diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index b7f4d8a307..98580170e3 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -477,6 +477,23 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j ) } +/** + * Check if programs/shaders are enabled and valid at glBegin time. + */ +GLboolean +vbo_validate_shaders(GLcontext *ctx) +{ + if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || + (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { + return GL_FALSE; + } + if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) { + return GL_FALSE; + } + return GL_TRUE; +} + + /* Build a list of primitives on the fly. Keep * ctx->Driver.CurrentExecPrimitive uptodate as well. */ @@ -491,18 +508,16 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) if (ctx->NewState) { _mesa_update_state( ctx ); - /* XXX also need to check if shader enabled, but invalid */ - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - CALL_Begin(ctx->Exec, (mode)); return; } + if (!vbo_validate_shaders(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBegin (invalid vertex/fragment program)"); + return; + } + /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 77f3cf1455..a52521db64 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -245,6 +245,11 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) if (ctx->NewState) _mesa_update_state( ctx ); + if (!vbo_validate_shaders(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArrays(bad shader)"); + return; + } + bind_arrays( ctx ); prim[0].begin = 1; @@ -280,6 +285,11 @@ vbo_exec_DrawRangeElements(GLenum mode, if (ctx->NewState) _mesa_update_state( ctx ); + if (!vbo_validate_shaders(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements(bad shader)"); + return; + } + bind_arrays( ctx ); ib.count = count; @@ -340,6 +350,11 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; + if (!vbo_validate_shaders(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawElements(bad shader)"); + return; + } + if (ctx->Array.ElementArrayBufferObj->Name) { const GLvoid *map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c index 39c0e9b851..7a91364ed8 100644 --- a/src/mesa/x86/rtasm/x86sse.c +++ b/src/mesa/x86/rtasm/x86sse.c @@ -1,3 +1,4 @@ +#ifdef USE_X86_ASM #if defined(__i386__) || defined(__386__) #include "imports.h" @@ -290,7 +291,7 @@ void x86_call( struct x86_function *p, void (*label)()) void x86_call( struct x86_function *p, struct x86_reg reg) { emit_1ub(p, 0xff); - emit_modrm(p, reg, reg); + emit_modrm_noreg(p, 2, reg); } #endif @@ -1191,3 +1192,9 @@ void x86sse_dummy( void ) } #endif + +#else /* USE_X86_ASM */ + +int x86sse_c_dummy_var; /* silence warning */ + +#endif /* USE_X86_ASM */ |