From b939adfa155f2b3ca5c5226e86da85629654d79b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 May 2007 10:44:53 +0100 Subject: Use the x11 driver as a test harness for the softpipe/state_tracker code. This has some limitations as we currently require a mapped framebuffer, so it only really works with double-buffered ximage rgba8888 windows. --- src/mesa/main/mtypes.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 71215d5470..2a8556388c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -126,6 +126,7 @@ struct gl_pixelstore_attrib; struct gl_texture_format; struct gl_texture_image; struct gl_texture_object; +struct st_context; typedef struct __GLcontextRec GLcontext; typedef struct __GLcontextModesRec GLvisual; typedef struct gl_framebuffer GLframebuffer; @@ -3069,7 +3070,7 @@ struct __GLcontextRec void *swsetup_context; void *swtnl_context; void *swtnl_im; - void *acache_context; + struct st_context *st; void *aelt_context; /*@}*/ }; -- cgit v1.2.3 From 4576d754c98e3fb5d413e294d48fb70a893defcf Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 30 Jul 2007 17:17:44 -0600 Subject: Lots of improvements to the surface-related code. Z testing now works with i915 driver. Add gl_renderbuffer::surface pointer (and reverse pointer). Remove intel_surface and xmesa_surface types - no longer used. --- src/mesa/drivers/dri/i915tex/intel_fbo.c | 18 ++ src/mesa/drivers/dri/i915tex/intel_fbo.h | 14 +- src/mesa/drivers/dri/i915tex/intel_surface.c | 231 ++++++++++++++------- src/mesa/drivers/x11/xm_buffer.c | 8 + src/mesa/drivers/x11/xm_surface.c | 288 +++++---------------------- src/mesa/drivers/x11/xmesaP.h | 14 +- src/mesa/main/mtypes.h | 3 + src/mesa/main/renderbuffer.c | 22 +- src/mesa/pipe/p_state.h | 16 +- src/mesa/pipe/softpipe/sp_context.c | 13 ++ src/mesa/pipe/softpipe/sp_z_surface.c | 118 +++++++++++ src/mesa/pipe/softpipe/sp_z_surface.h | 37 ++++ src/mesa/sources | 1 + src/mesa/state_tracker/st_atom_framebuffer.c | 19 +- 14 files changed, 449 insertions(+), 353 deletions(-) create mode 100644 src/mesa/pipe/softpipe/sp_z_surface.c create mode 100644 src/mesa/pipe/softpipe/sp_z_surface.h (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c index a09db46163..5a93eb7ad1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.c +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -289,6 +289,12 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->Width = width; rb->Height = height; +#if 1 + /* update the surface's size too */ + rb->surface->width = width; + rb->surface->height = height; +#endif + /* This sets the Get/PutRow/Value functions */ intel_set_span_functions(&irb->Base); @@ -451,6 +457,12 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, return irb; } + +/** + * Create a new renderbuffer which corresponds to an X window buffer + * (color, depth, stencil, etc) - not a user-created GL renderbuffer. + * The internal format is set at creation time and does not change. + */ struct gl_renderbuffer * intel_new_renderbuffer_fb(GLcontext * ctx, GLuint intFormat) { @@ -472,6 +484,9 @@ intel_new_renderbuffer_fb(GLcontext * ctx, GLuint intFormat) irb->Base.GetPointer = intel_get_pointer; /* span routines set in alloc_storage function */ + irb->Base.surface = intel_new_surface(intFormat); + irb->Base.surface->rb = irb; + return &irb->Base; } @@ -500,6 +515,9 @@ intel_new_renderbuffer(GLcontext * ctx, GLuint name) irb->Base.GetPointer = intel_get_pointer; /* span routines set in alloc_storage function */ + irb->Base.surface = intel_new_surface(0 /*unknown format*/); + irb->Base.surface->rb = irb; + return &irb->Base; } diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.h b/src/mesa/drivers/dri/i915tex/intel_fbo.h index 1642ce774f..86c8106084 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.h +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.h @@ -37,17 +37,6 @@ struct intel_context; struct intel_region; -/** - * Intel "pipe" surface. This is kind of a temporary thing as - * renderbuffers and surfaces should eventually become one. - */ -struct intel_surface -{ - struct softpipe_surface surface; /**< base class */ - struct intel_renderbuffer *rb; /**< ptr back to matching renderbuffer */ -}; - - /** * Intel framebuffer, derived from gl_framebuffer. */ @@ -129,5 +118,8 @@ extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb, +extern struct pipe_surface * +intel_new_surface(GLuint intFormat); + #endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_surface.c b/src/mesa/drivers/dri/i915tex/intel_surface.c index 3be902cf9c..043c5aa5fe 100644 --- a/src/mesa/drivers/dri/i915tex/intel_surface.c +++ b/src/mesa/drivers/dri/i915tex/intel_surface.c @@ -23,27 +23,33 @@ * XXX a lof of this is a temporary kludge */ +/** + * Note: the arithmetic/addressing in these functions is a little + * tricky since we need to invert the Y axis. + */ static void read_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y, GLfloat (*rrrr)[QUAD_SIZE]) { - struct intel_surface *is = (struct intel_surface *) sps; - struct intel_renderbuffer *irb = is->rb; - const GLubyte *src = (const GLubyte *) irb->region->map - + (y * irb->region->pitch + x) * irb->region->cpp; + const GLint bytesPerRow = sps->surface.stride * sps->surface.cpp; + const GLint invY = sps->surface.height - y - 1; + const GLubyte *src = sps->surface.ptr + invY * bytesPerRow + x * sps->surface.cpp; GLfloat *dst = (GLfloat *) rrrr; GLubyte temp[16]; - GLuint i, j; + GLuint j; + + assert(sps->surface.format == PIPE_FORMAT_U_A8_R8_G8_B8); - memcpy(temp, src, 8); - memcpy(temp + 8, src + irb->region->pitch * irb->region->cpp, 8); + memcpy(temp + 8, src, 8); + memcpy(temp + 0, src + bytesPerRow, 8); - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - dst[j * 4 + i] = UBYTE_TO_FLOAT(temp[i * 4 + j]); - } + for (j = 0; j < 4; j++) { + dst[0 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 2]); /*R*/ + dst[1 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 1]); /*G*/ + dst[2 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 0]); /*B*/ + dst[3 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 3]); /*A*/ } } @@ -52,45 +58,128 @@ static void write_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y, GLfloat (*rrrr)[QUAD_SIZE]) { - struct intel_surface *is = (struct intel_surface *) sps; - struct intel_renderbuffer *irb = is->rb; const GLfloat *src = (const GLfloat *) rrrr; - GLubyte *dst = (GLubyte *) irb->region->map - + (y * irb->region->pitch + x) * irb->region->cpp; + const GLint bytesPerRow = sps->surface.stride * sps->surface.cpp; + const GLint invY = sps->surface.height - y - 1; + GLubyte *dst = sps->surface.ptr + invY * bytesPerRow + x * sps->surface.cpp; GLubyte temp[16]; - GLuint i, j; + GLuint j; + + assert(sps->surface.format == PIPE_FORMAT_U_A8_R8_G8_B8); - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + i], src[i * 4 + j]); - } + for (j = 0; j < 4; j++) { + UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 2], src[0 * 4 + j]); /*R*/ + UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 1], src[1 * 4 + j]); /*G*/ + UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 0], src[2 * 4 + j]); /*B*/ + UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 3], src[3 * 4 + j]); /*A*/ } - memcpy(dst, temp, 8); - memcpy(dst + irb->region->pitch * irb->region->cpp, temp + 8, 8); + memcpy(dst, temp + 8, 8); + memcpy(dst + bytesPerRow, temp + 0, 8); } +static void +read_quad_z24(struct softpipe_surface *sps, + GLint x, GLint y, GLuint zzzz[QUAD_SIZE]) +{ + static const GLuint mask = 0xffffff; + const GLint invY = sps->surface.height - y - 1; + const GLuint *src + = (GLuint *) (sps->surface.ptr + + (invY * sps->surface.stride + x) * sps->surface.cpp); + + assert(sps->surface.format == PIPE_FORMAT_Z24_S8); + + /* extract lower three bytes */ + zzzz[0] = src[0] & mask; + zzzz[1] = src[1] & mask; + zzzz[2] = src[-sps->surface.stride] & mask; + zzzz[3] = src[-sps->surface.stride + 1] & mask; +} + +static void +write_quad_z24(struct softpipe_surface *sps, + GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]) +{ + static const GLuint mask = 0xff000000; + const GLint invY = sps->surface.height - y - 1; + GLuint *dst + = (GLuint *) (sps->surface.ptr + + (invY * sps->surface.stride + x) * sps->surface.cpp); + + assert(sps->surface.format == PIPE_FORMAT_Z24_S8); + + /* write lower three bytes */ + dst[0] = (dst[0] & mask) | zzzz[0]; + dst[1] = (dst[1] & mask) | zzzz[1]; + dst -= sps->surface.stride; + dst[0] = (dst[0] & mask) | zzzz[2]; + dst[1] = (dst[1] & mask) | zzzz[3]; +} + + +static void +read_quad_stencil(struct softpipe_surface *sps, + GLint x, GLint y, GLubyte ssss[QUAD_SIZE]) +{ + const GLint invY = sps->surface.height - y - 1; + const GLuint *src = (const GLuint *) (sps->surface.ptr + + (invY * sps->surface.stride + x) * sps->surface.cpp); + + assert(sps->surface.format == PIPE_FORMAT_Z24_S8); + + /* extract high byte */ + ssss[0] = src[0] >> 24; + ssss[1] = src[1] >> 24; + ssss[2] = src[-sps->surface.width] >> 24; + ssss[3] = src[-sps->surface.width + 1] >> 24; +} + +static void +write_quad_stencil(struct softpipe_surface *sps, + GLint x, GLint y, const GLubyte ssss[QUAD_SIZE]) +{ + static const GLuint mask = 0x00ffffff; + const GLint invY = sps->surface.height - y - 1; + GLuint *dst = (GLuint *) (sps->surface.ptr + + (invY * sps->surface.stride + x) * sps->surface.cpp); + + assert(sps->surface.format == PIPE_FORMAT_Z24_S8); + + /* write high byte */ + dst[0] = (dst[0] & mask) | (ssss[0] << 24); + dst[1] = (dst[1] & mask) | (ssss[1] << 24); + dst -= sps->surface.stride; + dst[0] = (dst[0] & mask) | (ssss[2] << 24); + dst[1] = (dst[1] & mask) | (ssss[3] << 24); +} + + static void * map_surface_buffer(struct pipe_buffer *pb, GLuint access_mode) { - struct intel_surface *is = (struct intel_surface *) pb; - struct intel_renderbuffer *irb = is->rb; - GET_CURRENT_CONTEXT(ctx); - struct intel_context *intel = intel_context(ctx); - + struct softpipe_surface *sps = (struct softpipe_surface *) pb; + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) sps->surface.rb; assert(access_mode == PIPE_MAP_READ_WRITE); - intelFinish(&intel->ctx); - /*LOCK_HARDWARE(intel);*/ if (irb->region) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); +#if 0 + intelFinish(&intel->ctx); /* XXX need this? */ +#endif intel_region_map(intel->intelScreen, irb->region); } pb->ptr = irb->region->map; + sps->surface.stride = irb->region->pitch; + sps->surface.cpp = irb->region->cpp; + sps->surface.ptr = irb->region->map; + return pb->ptr; } @@ -98,69 +187,67 @@ map_surface_buffer(struct pipe_buffer *pb, GLuint access_mode) static void unmap_surface_buffer(struct pipe_buffer *pb) { - struct intel_surface *is = (struct intel_surface *) pb; - struct intel_renderbuffer *irb = is->rb; - GET_CURRENT_CONTEXT(ctx); - struct intel_context *intel = intel_context(ctx); + struct softpipe_surface *sps = (struct softpipe_surface *) pb; + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) sps->surface.rb; if (irb->region) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); intel_region_unmap(intel->intelScreen, irb->region); } pb->ptr = NULL; + sps->surface.stride = 0; + sps->surface.cpp = 0; + sps->surface.ptr = NULL; + /*UNLOCK_HARDWARE(intel);*/ } struct pipe_surface * -xmesa_get_color_surface(GLcontext *ctx, GLuint i) +intel_new_surface(GLuint intFormat) { - struct intel_context *intel = intel_context(ctx); - struct intel_framebuffer *intel_fb; - struct intel_renderbuffer *intel_rb; - - intel_fb = (struct intel_framebuffer *) ctx->DrawBuffer; - intel_rb = intel_fb->color_rb[1]; - - if (!intel_rb->surface) { - /* create surface and attach to intel_rb */ - struct intel_surface *is; - is = CALLOC_STRUCT(intel_surface); - if (is) { - is->surface.surface.width = intel_rb->Base.Width; - is->surface.surface.height = intel_rb->Base.Height; - - is->surface.read_quad_f_swz = read_quad_f_swz; - is->surface.write_quad_f_swz = write_quad_f_swz; - - is->surface.surface.buffer.map = map_surface_buffer; - is->surface.surface.buffer.unmap = unmap_surface_buffer; - - is->rb = intel_rb; - } - intel_rb->surface = is; + struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface); + if (!sps) + return NULL; + + sps->surface.width = 0; /* set in intel_alloc_renderbuffer_storage() */ + sps->surface.height = 0; + + if (intFormat == GL_RGBA8) { + sps->surface.format = PIPE_FORMAT_U_A8_R8_G8_B8; + sps->read_quad_f_swz = read_quad_f_swz; + sps->write_quad_f_swz = write_quad_f_swz; } - else { - /* update surface size */ - struct intel_surface *is = intel_rb->surface; - is->surface.surface.width = intel_rb->Base.Width; - is->surface.surface.height = intel_rb->Base.Height; - /* sanity check */ - assert(is->surface.surface.buffer.map == map_surface_buffer); + else if (intFormat == GL_RGB5) { + sps->surface.format = PIPE_FORMAT_U_R5_G6_B5; + } + else if (intFormat == GL_DEPTH_COMPONENT16) { + sps->surface.format = PIPE_FORMAT_U_Z16; - return &intel_rb->surface->surface.surface; -} + } + else if (intFormat == GL_DEPTH24_STENCIL8_EXT) { + sps->surface.format = PIPE_FORMAT_Z24_S8; + sps->read_quad_z = read_quad_z24; + sps->write_quad_z = write_quad_z24; + sps->read_quad_stencil = read_quad_stencil; + sps->write_quad_stencil = write_quad_stencil; + } + else { + /* TBD / unknown */ + } -struct pipe_surface * -xmesa_get_z_surface(GLcontext *ctx) -{ - /* XXX fix */ - return NULL; + sps->surface.buffer.map = map_surface_buffer; + sps->surface.buffer.unmap = unmap_surface_buffer; + + return &sps->surface; } + struct pipe_surface * xmesa_get_stencil_surface(GLcontext *ctx) { diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index 51d183bb43..8fbd9a783b 100644 --- a/src/mesa/drivers/x11/xm_buffer.c +++ b/src/mesa/drivers/x11/xm_buffer.c @@ -35,6 +35,7 @@ #include "imports.h" #include "framebuffer.h" #include "renderbuffer.h" +#include "pipe/p_state.h" #if defined(USE_XSHM) && !defined(XFree86Server) @@ -268,6 +269,8 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->Height = height; rb->InternalFormat = internalFormat; + rb->surface->resize(rb->surface, width, height); + return GL_TRUE; } @@ -317,6 +320,8 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, xrb->origin4 = NULL; } + rb->surface->resize(rb->surface, width, height); + return GL_TRUE; } @@ -352,6 +357,9 @@ xmesa_new_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual, xrb->Base.IndexBits = visual->indexBits; } /* only need to set Red/Green/EtcBits fields for user-created RBs */ + + xrb->Base.surface = xmesa_new_surface(xrb); + } return xrb; } diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c index 9d6db2b5ce..17f5f28a9d 100644 --- a/src/mesa/drivers/x11/xm_surface.c +++ b/src/mesa/drivers/x11/xm_surface.c @@ -24,7 +24,7 @@ /** - * \file xm_surface.h + * \file xm_surface.c * Code to allow the softpipe code to write to X windows/buffers. * This is a bit of a hack for now. We've basically got two different * abstractions for color buffers: gl_renderbuffer and softpipe_surface. @@ -48,31 +48,11 @@ #include "pipe/softpipe/sp_surface.h" -/** - * An xm_surface is derived from a softpipe_surface - */ -struct xmesa_surface -{ - struct softpipe_surface sps; - struct xmesa_renderbuffer *xrb; /** ptr back to matching xmesa_renderbuffer */ - struct gl_renderbuffer *rb; /* ptr to matching gl_renderbuffer */ -}; - - -/** - * Cast wrapper - */ -static INLINE struct xmesa_surface * -xmesa_surface(struct softpipe_surface *sps) -{ - return (struct xmesa_surface *) sps; -} - - static void * map_surface_buffer(struct pipe_buffer *pb, GLuint access_mode) { /* no-op */ + return NULL; } @@ -83,6 +63,13 @@ unmap_surface_buffer(struct pipe_buffer *pb) } +static INLINE struct xmesa_renderbuffer * +xmesa_rb(struct softpipe_surface *sps) +{ + return (struct xmesa_renderbuffer *) sps->surface.rb; +} + + /** * quad reading/writing * These functions are just wrappers around the existing renderbuffer @@ -90,11 +77,10 @@ unmap_surface_buffer(struct pipe_buffer *pb) */ static void -read_quad_f(struct softpipe_surface *gs, GLint x, GLint y, +read_quad_f(struct softpipe_surface *sps, GLint x, GLint y, GLfloat (*rgba)[NUM_CHANNELS]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GLubyte temp[16]; GLfloat *dst = (GLfloat *) rgba; GLuint i; @@ -107,11 +93,10 @@ read_quad_f(struct softpipe_surface *gs, GLint x, GLint y, } static void -read_quad_f_swz(struct softpipe_surface *gs, GLint x, GLint y, +read_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y, GLfloat (*rrrr)[QUAD_SIZE]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GLubyte temp[16]; GLfloat *dst = (GLfloat *) rrrr; GLuint i, j; @@ -126,11 +111,10 @@ read_quad_f_swz(struct softpipe_surface *gs, GLint x, GLint y, } static void -write_quad_f(struct softpipe_surface *gs, GLint x, GLint y, +write_quad_f(struct softpipe_surface *sps, GLint x, GLint y, GLfloat (*rgba)[NUM_CHANNELS]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GLubyte temp[16]; const GLfloat *src = (const GLfloat *) rgba; GLuint i; @@ -143,11 +127,10 @@ write_quad_f(struct softpipe_surface *gs, GLint x, GLint y, } static void -write_quad_f_swz(struct softpipe_surface *gs, GLint x, GLint y, +write_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y, GLfloat (*rrrr)[QUAD_SIZE]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GLubyte temp[16]; const GLfloat *src = (const GLfloat *) rrrr; GLuint i, j; @@ -162,251 +145,70 @@ write_quad_f_swz(struct softpipe_surface *gs, GLint x, GLint y, } static void -read_quad_ub(struct softpipe_surface *gs, GLint x, GLint y, +read_quad_ub(struct softpipe_surface *sps, GLint x, GLint y, GLubyte (*rgba)[NUM_CHANNELS]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GET_CURRENT_CONTEXT(ctx); xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y, rgba); xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y + 1, rgba + 2); } static void -write_quad_ub(struct softpipe_surface *gs, GLint x, GLint y, +write_quad_ub(struct softpipe_surface *sps, GLint x, GLint y, GLubyte (*rgba)[NUM_CHANNELS]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GET_CURRENT_CONTEXT(ctx); xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y, rgba); xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y + 1, rgba + 2); } static void -write_mono_row_ub(struct softpipe_surface *gs, GLuint count, GLint x, GLint y, +write_mono_row_ub(struct softpipe_surface *sps, GLuint count, GLint x, GLint y, GLubyte rgba[NUM_CHANNELS]) { - struct xmesa_surface *xmsurf = xmesa_surface(gs); - struct xmesa_renderbuffer *xrb = xmsurf->xrb; + struct xmesa_renderbuffer *xrb = xmesa_rb(sps); GET_CURRENT_CONTEXT(ctx); xrb->Base.PutMonoRow(ctx, &xrb->Base, count, x, y, rgba, NULL); } -static struct xmesa_surface * -create_surface(XMesaContext xmctx, struct xmesa_renderbuffer *xrb) -{ - struct xmesa_surface *xmsurf; - - xmsurf = CALLOC_STRUCT(xmesa_surface); - if (xmsurf) { - xmsurf->xrb = xrb; - xmsurf->sps.surface.width = xrb->Base.Width; - xmsurf->sps.surface.height = xrb->Base.Height; - - xmsurf->sps.read_quad_f = read_quad_f; - xmsurf->sps.read_quad_f_swz = read_quad_f_swz; - xmsurf->sps.read_quad_ub = read_quad_ub; - xmsurf->sps.write_quad_f = write_quad_f; - xmsurf->sps.write_quad_f_swz = write_quad_f_swz; - xmsurf->sps.write_quad_ub = write_quad_ub; - xmsurf->sps.write_mono_row_ub = write_mono_row_ub; - - xmsurf->sps.surface.buffer.map = map_surface_buffer; - xmsurf->sps.surface.buffer.unmap = unmap_surface_buffer; - -#if 0 - if (xrb->ximage) { - xmsurf->sps.surface.ptr = (GLubyte *) xrb->ximage->data; - xmsurf->sps.surface.stride = xrb->ximage->bytes_per_line; - xmsurf->sps.surface.cpp = xrb->ximage->depth; - - } -#endif - } - return xmsurf; -} - - -static void -free_surface(struct softpipe_surface *sps) -{ - /* XXX may need to do more in the future */ - free(sps); -} - - -/** - * Return generic surface pointer corresponding to the current color buffer. - */ -struct pipe_surface * -xmesa_get_color_surface(GLcontext *ctx, GLuint buf) -{ - XMesaContext xmctx = XMESA_CONTEXT(ctx); - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][buf]; - struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); - struct softpipe_surface *sps = (struct softpipe_surface *) xrb->pSurface; - - if (!sps) { - xrb->pSurface = create_surface(xmctx, xrb); - } - else if (sps->surface.width != rb->Width || - sps->surface.height != rb->Height) { - free_surface(sps); - xrb->pSurface = create_surface(xmctx, xrb); - } - - return (struct pipe_surface *) xrb->pSurface; -} - - - - -static void -read_quad_z(struct softpipe_surface *sps, - GLint x, GLint y, GLuint zzzz[QUAD_SIZE]) -{ - struct xmesa_surface *xmsurf = xmesa_surface(sps); - struct gl_renderbuffer *rb = xmsurf->rb; - GLushort temp[4]; - GLuint i; - GET_CURRENT_CONTEXT(ctx); - rb->GetRow(ctx, rb, 2, x, y, temp); - rb->GetRow(ctx, rb, 2, x, y + 1, temp + 2); - /* convert from GLushort to GLuint */ - for (i = 0; i < 4; i++) { - zzzz[i] = temp[i]; - } -} - -static void -write_quad_z(struct softpipe_surface *sps, - GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]) -{ - struct xmesa_surface *xmsurf = xmesa_surface(sps); - struct gl_renderbuffer *rb = xmsurf->rb; - GLushort temp[4]; - GLuint i; - GET_CURRENT_CONTEXT(ctx); - /* convert from GLuint to GLushort */ - for (i = 0; i < 4; i++) { - temp[i] = zzzz[i]; - } - rb->PutRow(ctx, rb, 2, x, y, temp, NULL); - rb->PutRow(ctx, rb, 2, x, y + 1, temp + 2, NULL); -} - - -static struct xmesa_surface * -create_z_surface(XMesaContext xmctx, struct gl_renderbuffer *rb) -{ - struct xmesa_surface *xmsurf; - - xmsurf = CALLOC_STRUCT(xmesa_surface); - if (xmsurf) { - xmsurf->sps.surface.format = PIPE_FORMAT_U_Z16; - xmsurf->sps.surface.width = rb->Width; - xmsurf->sps.surface.height = rb->Height; - xmsurf->sps.read_quad_z = read_quad_z; - xmsurf->sps.write_quad_z = write_quad_z; - xmsurf->rb = rb; - } - return xmsurf; -} - - - - static void -read_quad_stencil(struct softpipe_surface *sps, - GLint x, GLint y, GLubyte ssss[QUAD_SIZE]) +resize_surface(struct pipe_surface *ps, GLuint width, GLuint height) { - struct xmesa_surface *xmsurf = xmesa_surface(sps); - struct gl_renderbuffer *rb = xmsurf->rb; - GET_CURRENT_CONTEXT(ctx); - rb->GetRow(ctx, rb, 2, x, y, ssss); - rb->GetRow(ctx, rb, 2, x, y + 1, ssss + 2); -} - -static void -write_quad_stencil(struct softpipe_surface *sps, - GLint x, GLint y, const GLubyte ssss[QUAD_SIZE]) -{ - struct xmesa_surface *xmsurf = xmesa_surface(sps); - struct gl_renderbuffer *rb = xmsurf->rb; - GET_CURRENT_CONTEXT(ctx); - rb->PutRow(ctx, rb, 2, x, y, ssss, NULL); - rb->PutRow(ctx, rb, 2, x, y + 1, ssss + 2, NULL); -} - -static struct xmesa_surface * -create_stencil_surface(XMesaContext xmctx, struct gl_renderbuffer *rb) -{ - struct xmesa_surface *xmsurf; - - xmsurf = CALLOC_STRUCT(xmesa_surface); - if (xmsurf) { - xmsurf->sps.surface.format = PIPE_FORMAT_U_S8; - xmsurf->sps.surface.width = rb->Width; - xmsurf->sps.surface.height = rb->Height; - xmsurf->sps.read_quad_stencil = read_quad_stencil; - xmsurf->sps.write_quad_stencil = write_quad_stencil; - xmsurf->rb = rb; - } - return xmsurf; + ps->width = width; + ps->height = height; } - - /** - * Return a pipe_surface that wraps the current Z/depth buffer. - * XXX this is pretty much a total hack until gl_renderbuffers and - * pipe_surfaces are merged... + * Called to create a pipe_surface for each X renderbuffer. */ struct pipe_surface * -xmesa_get_z_surface(GLcontext *ctx) +xmesa_new_surface(struct xmesa_renderbuffer *xrb) { - XMesaContext xmctx = XMESA_CONTEXT(ctx); - struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer; - static struct xmesa_surface *xms = NULL; + struct softpipe_surface *sps; - if (!rb) + sps = CALLOC_STRUCT(softpipe_surface); + if (!sps) return NULL; - if (!xms) { - xms = create_z_surface(xmctx, rb); - } - else if (xms->sps.surface.width != rb->Width || - xms->sps.surface.height != rb->Height) { - free_surface(&xms->sps); - xms = create_z_surface(xmctx, rb); - } - - return (struct pipe_surface *) &xms->sps.surface; -} + sps->surface.rb = xrb; + sps->surface.width = xrb->Base.Width; + sps->surface.height = xrb->Base.Height; + sps->read_quad_f = read_quad_f; + sps->read_quad_f_swz = read_quad_f_swz; + sps->read_quad_ub = read_quad_ub; + sps->write_quad_f = write_quad_f; + sps->write_quad_f_swz = write_quad_f_swz; + sps->write_quad_ub = write_quad_ub; + sps->write_mono_row_ub = write_mono_row_ub; -struct pipe_surface * -xmesa_get_stencil_surface(GLcontext *ctx) -{ - XMesaContext xmctx = XMESA_CONTEXT(ctx); - struct gl_renderbuffer *rb = ctx->DrawBuffer->_StencilBuffer; - static struct xmesa_surface *xms = NULL; + sps->surface.buffer.map = map_surface_buffer; + sps->surface.buffer.unmap = unmap_surface_buffer; + sps->surface.resize = resize_surface; - if (!rb) - return NULL; - - if (!xms) { - xms = create_stencil_surface(xmctx, rb); - } - else if (xms->sps.surface.width != rb->Width || - xms->sps.surface.height != rb->Height) { - free_surface(&xms->sps); - xms = create_stencil_surface(xmctx, rb); - } - - return (struct pipe_surface *) &xms->sps.surface; + return &sps->surface; } - diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h index 8648b19939..daf6a3f942 100644 --- a/src/mesa/drivers/x11/xmesaP.h +++ b/src/mesa/drivers/x11/xmesaP.h @@ -585,23 +585,11 @@ extern void xmesa_register_swrast_functions( GLcontext *ctx ); #define ENABLE_EXT_timer_query 0 /* may not have 64-bit GLuint64EXT */ #endif -#if 0 -GLboolean xmesa_get_cbuf_details( GLcontext *ctx, - void **ptr, - GLuint *cpp, - GLint *stride, - GLuint *format ); -#endif struct pipe_surface; -struct pipe_surface * -xmesa_get_color_surface(GLcontext *ctx, GLuint buf); - -struct pipe_surface * -xmesa_get_z_surface(GLcontext *ctx); struct pipe_surface * -xmesa_get_stencil_surface(GLcontext *ctx); +xmesa_new_surface(struct xmesa_renderbuffer *xrb); #endif diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 52448ee04e..d70df5d945 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -127,6 +127,7 @@ struct gl_texture_format; struct gl_texture_image; struct gl_texture_object; struct st_context; +struct pipe_surface; typedef struct __GLcontextRec GLcontext; typedef struct __GLcontextModesRec GLvisual; typedef struct gl_framebuffer GLframebuffer; @@ -2268,6 +2269,8 @@ struct gl_renderbuffer GLubyte StencilBits; GLvoid *Data; /**< This may not be used by some kinds of RBs */ + struct pipe_surface *surface; + /* Used to wrap one renderbuffer around another: */ struct gl_renderbuffer *Wrapped; diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index 6f1d7c3960..a1412ef007 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -49,6 +49,9 @@ #include "rbadaptors.h" +#include "pipe/softpipe/sp_z_surface.h" +#include "pipe/p_state.h" + /* 32-bit color index format. Not a public format. */ #define COLOR_INDEX32 0x424243 @@ -1091,6 +1094,7 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutValues = put_values_ushort; rb->PutMonoValues = put_mono_values_ushort; rb->DepthBits = 8 * sizeof(GLushort); + rb->surface = (struct pipe_surface *) softpipe_new_z_surface(16); pixelSize = sizeof(GLushort); break; case GL_DEPTH_COMPONENT24: @@ -1193,13 +1197,27 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, /* free old buffer storage */ if (rb->Data) { - _mesa_free(rb->Data); + if (rb->surface) { + /* pipe surface */ + } + else { + /* legacy renderbuffer */ + _mesa_free(rb->Data); + } rb->Data = NULL; } if (width > 0 && height > 0) { /* allocate new buffer storage */ - rb->Data = _mesa_malloc(width * height * pixelSize); + if (rb->surface) { + /* pipe surface */ + rb->surface->resize(rb->surface, width, height); + rb->Data = rb->surface->buffer.ptr; + } + else { + /* legacy renderbuffer */ + rb->Data = _mesa_malloc(width * height * pixelSize); + } if (rb->Data == NULL) { rb->Width = 0; rb->Height = 0; diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 4ae8928018..9973a7b8dd 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -239,6 +239,7 @@ struct pipe_sampler_state /** * A mappable buffer (vertex data, pixel data, etc) + * XXX replace with "intel_region". */ struct pipe_buffer { @@ -247,7 +248,7 @@ struct pipe_buffer const void *src); void *(*map)(struct pipe_buffer *pb, GLuint access_mode); void (*unmap)(struct pipe_buffer *pb); - void *ptr; /**< address, only valid while mapped */ + GLubyte *ptr; /**< address, only valid while mapped */ GLuint mode; /**< PIPE_MAP_x, only valid while mapped */ }; @@ -261,12 +262,13 @@ struct pipe_surface struct pipe_buffer buffer; /**< surfaces can be mapped */ GLuint format:5; /**< PIPE_FORMAT_x */ GLuint width, height; -#if 0 - GLubyte *ptr; - GLint stride; - GLuint cpp; - GLuint format; -#endif + + GLint stride, cpp; + GLubyte *ptr; /**< only valid while mapped, may not equal buffer->ptr */ + + void *rb; /**< Ptr back to renderbuffer (temporary?) */ + + void (*resize)(struct pipe_surface *ps, GLuint width, GLuint height); }; diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 6b44fabfa4..8655aa83fd 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -49,6 +49,13 @@ static void map_surfaces(struct softpipe_context *sp) struct pipe_buffer *buf = &sps->surface.buffer; buf->map(buf, PIPE_MAP_READ_WRITE); } + + if (sp->framebuffer.zbuf) { + struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf); + struct pipe_buffer *buf = &sps->surface.buffer; + buf->map(buf, PIPE_MAP_READ_WRITE); + } + /* XXX depth & stencil bufs */ } @@ -62,6 +69,12 @@ static void unmap_surfaces(struct softpipe_context *sp) struct pipe_buffer *buf = &sps->surface.buffer; buf->unmap(buf); } + + if (sp->framebuffer.zbuf) { + struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf); + struct pipe_buffer *buf = &sps->surface.buffer; + buf->unmap(buf); + } /* XXX depth & stencil bufs */ } diff --git a/src/mesa/pipe/softpipe/sp_z_surface.c b/src/mesa/pipe/softpipe/sp_z_surface.c new file mode 100644 index 0000000000..662a4a15ee --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_z_surface.c @@ -0,0 +1,118 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Software Z buffer/surface. + * + * \author Brian Paul + */ + + +#include "main/imports.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "sp_surface.h" +#include "sp_z_surface.h" + +static void* +z16_map(struct pipe_buffer *pb, GLuint access_mode) +{ + struct softpipe_surface *sps = (struct softpipe_surface *) pb; + sps->surface.ptr = pb->ptr; + return pb->ptr; +} + +static void +z16_unmap(struct pipe_buffer *pb) +{ + struct softpipe_surface *sps = (struct softpipe_surface *) pb; + sps->surface.ptr = NULL; +} + +static void +z16_resize(struct pipe_surface *ps, GLuint width, GLuint height) +{ + struct softpipe_surface *sps = (struct softpipe_surface *) ps; + + if (sps->surface.buffer.ptr) + free(sps->surface.buffer.ptr); + + ps->buffer.ptr = (GLubyte *) malloc(width * height * sizeof(GLushort)); + ps->width = width; + ps->height = height; + + sps->surface.stride = sps->surface.width; + sps->surface.cpp = 2; +} + +static void +z16_read_quad_z(struct softpipe_surface *sps, + GLint x, GLint y, GLuint zzzz[QUAD_SIZE]) +{ + const GLushort *src + = (GLushort *) sps->surface.ptr + y * sps->surface.stride + x; + + /* converting GLushort to GLuint: */ + zzzz[0] = src[0]; + zzzz[1] = src[1]; + zzzz[2] = src[sps->surface.width]; + zzzz[3] = src[sps->surface.width + 1]; +} + +static void +z16_write_quad_z(struct softpipe_surface *sps, + GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]) +{ + GLushort *dst = (GLushort *) sps->surface.ptr + y * sps->surface.stride + x; + + /* converting GLuint to GLushort: */ + dst[0] = zzzz[0]; + dst[1] = zzzz[1]; + dst[sps->surface.width] = zzzz[2]; + dst[sps->surface.width + 1] = zzzz[3]; +} + +struct softpipe_surface * +softpipe_new_z_surface(GLuint depth) +{ + struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface); + if (!sps) + return NULL; + + /* XXX ignoring depth param for now */ + + sps->surface.format = PIPE_FORMAT_U_Z16; + + sps->surface.resize = z16_resize; + sps->surface.buffer.map = z16_map; + sps->surface.buffer.unmap = z16_unmap; + sps->read_quad_z = z16_read_quad_z; + sps->write_quad_z = z16_write_quad_z; + + return sps; +} diff --git a/src/mesa/pipe/softpipe/sp_z_surface.h b/src/mesa/pipe/softpipe/sp_z_surface.h new file mode 100644 index 0000000000..9c3c43ca57 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_z_surface.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SP_Z_SURFACE_H +#define SP_Z_SURFACE_H + + +extern struct softpipe_surface * +softpipe_new_z_surface(GLuint depth); + + +#endif /* SP_Z_SURFACE_H */ diff --git a/src/mesa/sources b/src/mesa/sources index a589ae4373..32c2ff2350 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -176,6 +176,7 @@ SOFTPIPE_SOURCES = \ pipe/softpipe/sp_state_sampler.c \ pipe/softpipe/sp_state_setup.c \ pipe/softpipe/sp_state_surface.c \ + pipe/softpipe/sp_z_surface.c \ pipe/softpipe/sp_prim_setup.c DRAW_SOURCES = \ diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 595f390b28..f5e3ce8b67 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -54,22 +54,31 @@ static void update_framebuffer_state( struct st_context *st ) { struct pipe_framebuffer_state framebuffer; + struct gl_renderbuffer *rb; GLuint i; + memset(&framebuffer, 0, sizeof(framebuffer)); + /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state * to determine which surfaces to draw to */ framebuffer.num_cbufs = st->ctx->DrawBuffer->_NumColorDrawBuffers[0]; for (i = 0; i < framebuffer.num_cbufs; i++) { - framebuffer.cbufs[i] = xmesa_get_color_surface(st->ctx, i); + rb = st->ctx->DrawBuffer->_ColorDrawBuffers[0][i]; + assert(rb->surface); + framebuffer.cbufs[i] = rb->surface; } - if (st->ctx->DrawBuffer->_DepthBuffer/*Attachment[BUFFER_DEPTH].Renderbuffer*/) { - framebuffer.zbuf = xmesa_get_z_surface(st->ctx); + rb = st->ctx->DrawBuffer->_DepthBuffer; + if (rb) { + assert(rb->surface); + framebuffer.zbuf = rb->Wrapped->surface; } - if (st->ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) { - framebuffer.sbuf = xmesa_get_stencil_surface(st->ctx); + rb = st->ctx->DrawBuffer->_StencilBuffer; + if (rb) { + assert(rb->surface); + framebuffer.sbuf = rb->Wrapped->surface; } if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) { -- cgit v1.2.3 From f5713c7d2e7ba8e1170fd9b1dd95379662ab6117 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 9 Aug 2007 12:59:11 -0600 Subject: Checkpoint intel_renderbuffer removal. Remove surface ptr from gl_renderbuffer. Use st_renderbuffer in most places. More clean-up. --- src/mesa/drivers/dri/intel_winsys/intel_blit.c | 14 +++-- src/mesa/main/mtypes.h | 2 - src/mesa/main/renderbuffer.c | 14 ++++- src/mesa/pipe/p_state.h | 2 - src/mesa/state_tracker/st_atom_framebuffer.c | 27 +++++---- src/mesa/state_tracker/st_cb_clear.c | 35 +++++++---- src/mesa/state_tracker/st_cb_fbo.c | 82 +++++++++----------------- src/mesa/state_tracker/st_cb_fbo.h | 23 ++++++-- 8 files changed, 107 insertions(+), 92 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_blit.c b/src/mesa/drivers/dri/intel_winsys/intel_blit.c index 48bbbbeac9..aa4135ed2d 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_blit.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_blit.c @@ -38,6 +38,7 @@ #include "vblank.h" #include "pipe/p_context.h" +#include "state_tracker/st_cb_fbo.h" #define FILE_DEBUG_FLAG DEBUG_BLIT @@ -106,12 +107,17 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv, const struct pipe_surface *backSurf; const struct pipe_region *backRegion; int srcpitch; + struct st_renderbuffer *strb; /* blit from back color buffer if it exists, else front buffer */ - if (intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer) - backSurf = intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer->surface; - else - backSurf = intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer->surface; + strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + if (strb) { + backSurf = strb->surface; + } + else { + strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + backSurf = strb->surface; + } backRegion = backSurf->region; srcpitch = backRegion->pitch; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index d70df5d945..0a64e0c58c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2269,8 +2269,6 @@ struct gl_renderbuffer GLubyte StencilBits; GLvoid *Data; /**< This may not be used by some kinds of RBs */ - struct pipe_surface *surface; - /* Used to wrap one renderbuffer around another: */ struct gl_renderbuffer *Wrapped; diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index d89704196a..e7aeea8e3e 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -1067,9 +1067,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutMonoValues = put_mono_values_ubyte; rb->StencilBits = 8 * sizeof(GLubyte); pixelSize = sizeof(GLubyte); +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_U_S8); +#endif break; case GL_STENCIL_INDEX16_EXT: rb->_ActualFormat = GL_STENCIL_INDEX16_EXT; @@ -1100,9 +1102,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutValues = put_values_ushort; rb->PutMonoValues = put_mono_values_ushort; rb->DepthBits = 8 * sizeof(GLushort); +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_U_Z16); +#endif pixelSize = sizeof(GLushort); break; case GL_DEPTH_COMPONENT24: @@ -1125,9 +1129,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->_ActualFormat = GL_DEPTH_COMPONENT32; rb->DepthBits = 32; } +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_U_Z32); +#endif pixelSize = sizeof(GLuint); break; case GL_DEPTH_STENCIL_EXT: @@ -1145,9 +1151,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutMonoValues = put_mono_values_uint; rb->DepthBits = 24; rb->StencilBits = 8; +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_S8_Z24); +#endif pixelSize = sizeof(GLuint); break; case GL_COLOR_INDEX8_EXT: @@ -1210,7 +1218,7 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, ASSERT(rb->PutMonoValues); /* free old buffer storage */ - if (rb->surface) { + if (0/**rb->surface**/) { /* pipe_surface/region */ } else if (rb->Data) { @@ -1221,8 +1229,9 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, if (width > 0 && height > 0) { /* allocate new buffer storage */ - if (rb->surface) { + if (0/**rb->surface**/) { /* pipe_surface/region */ +#if 0 if (rb->surface->region) { pipe->region_unmap(pipe, rb->surface->region); pipe->region_release(pipe, &rb->surface->region); @@ -1231,6 +1240,7 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, /* XXX probably don't want to really map here */ pipe->region_map(pipe, rb->surface->region); rb->Data = rb->surface->region->map; +#endif } else { /* legacy renderbuffer (this will go away) */ diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 2dcd2db868..ee29e38a48 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -260,8 +260,6 @@ struct pipe_surface GLuint offset; /**< offset from start of region, in bytes */ GLint refcount; - void *rb; /**< Ptr back to renderbuffer (temporary?) */ - /** get block/tile of pixels from surface */ void (*get_tile)(struct pipe_surface *ps, GLuint x, GLuint y, GLuint w, GLuint h, GLfloat *p); diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 7edd044ad9..f054eb8f21 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -33,6 +33,7 @@ #include "st_context.h" #include "st_atom.h" +#include "st_cb_fbo.h" #include "pipe/p_context.h" @@ -44,7 +45,7 @@ static void update_framebuffer_state( struct st_context *st ) { struct pipe_framebuffer_state framebuffer; - struct gl_renderbuffer *rb; + struct st_renderbuffer *strb; GLuint i; memset(&framebuffer, 0, sizeof(framebuffer)); @@ -54,21 +55,23 @@ update_framebuffer_state( struct st_context *st ) */ framebuffer.num_cbufs = st->ctx->DrawBuffer->_NumColorDrawBuffers[0]; for (i = 0; i < framebuffer.num_cbufs; i++) { - rb = st->ctx->DrawBuffer->_ColorDrawBuffers[0][i]; - assert(rb->surface); - framebuffer.cbufs[i] = rb->surface; + strb = st_renderbuffer(st->ctx->DrawBuffer->_ColorDrawBuffers[0][i]); + assert(strb->surface); + framebuffer.cbufs[i] = strb->surface; } - rb = st->ctx->DrawBuffer->_DepthBuffer; - if (rb) { - assert(rb->Wrapped->surface); - framebuffer.zbuf = rb->Wrapped->surface; + strb = st_renderbuffer(st->ctx->DrawBuffer->_DepthBuffer); + if (strb) { + strb = st_renderbuffer(strb->Base.Wrapped); + assert(strb->surface); + framebuffer.zbuf = strb->surface; } - rb = st->ctx->DrawBuffer->_StencilBuffer; - if (rb) { - assert(rb->Wrapped->surface); - framebuffer.sbuf = rb->Wrapped->surface; + strb = st_renderbuffer(st->ctx->DrawBuffer->_StencilBuffer); + if (strb) { + strb = st_renderbuffer(strb->Base.Wrapped); + assert(strb->surface); + framebuffer.sbuf = strb->surface; } if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) { diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index d862f7ba46..4da3a2500d 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -37,6 +37,7 @@ #include "st_atom.h" #include "st_context.h" #include "st_cb_clear.h" +#include "st_cb_fbo.h" #include "st_program.h" #include "st_public.h" #include "pipe/p_context.h" @@ -288,6 +289,8 @@ clear_with_quad(GLcontext *ctx, GLuint x0, GLuint y0, static void clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + if (ctx->Color.ColorMask[0] && ctx->Color.ColorMask[1] && ctx->Color.ColorMask[2] && @@ -296,8 +299,8 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { /* clear whole buffer w/out masking */ GLuint clearValue - = color_value(rb->surface->format, ctx->Color.ClearColor); - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + = color_value(strb->surface->format, ctx->Color.ClearColor); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring */ @@ -314,14 +317,16 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + if (!ctx->Scissor.Enabled) { /* clear whole buffer w/out masking */ GLuint clearValue - = color_value(rb->surface->format, ctx->Accum.ClearColor); + = color_value(strb->surface->format, ctx->Accum.ClearColor); /* Note that clearValue is 32 bits but the accum buffer will * typically be 64bpp... */ - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* scissoring */ @@ -339,11 +344,13 @@ clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + if (!ctx->Scissor.Enabled && - !is_depth_stencil_format(rb->surface->format)) { + !is_depth_stencil_format(strb->surface->format)) { /* clear whole depth buffer w/out masking */ - GLuint clearValue = depth_value(rb->surface->format, ctx->Depth.Clear); - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + GLuint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring or combined z/stencil buffer */ @@ -360,14 +367,15 @@ clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); const GLuint stencilMax = (1 << rb->StencilBits) - 1; GLboolean maskStencil = ctx->Stencil.WriteMask[0] != stencilMax; if (!maskStencil && !ctx->Scissor.Enabled && - !is_depth_stencil_format(rb->surface->format)) { + !is_depth_stencil_format(strb->surface->format)) { /* clear whole stencil buffer w/out masking */ GLuint clearValue = ctx->Stencil.Clear; - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring */ @@ -384,16 +392,17 @@ clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); const GLuint stencilMax = 1 << rb->StencilBits; GLboolean maskStencil = ctx->Stencil.WriteMask[0] != stencilMax; - assert(is_depth_stencil_format(rb->surface->format)); + assert(is_depth_stencil_format(strb->surface->format)); if (!maskStencil && !ctx->Scissor.Enabled) { /* clear whole buffer w/out masking */ - GLuint clearValue = depth_value(rb->surface->format, ctx->Depth.Clear); + GLuint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear); - switch (rb->surface->format) { + switch (strb->surface->format) { case PIPE_FORMAT_S8_Z24: clearValue |= ctx->Stencil.Clear << 24; break; @@ -406,7 +415,7 @@ clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) assert(0); } - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 3cd1fbe851..02bdb5aba5 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -46,29 +46,6 @@ #include "st_cb_teximage.h" -/** - * Derived renderbuffer class. Just need to add a pointer to the - * pipe surface. - */ -struct st_renderbuffer -{ - struct gl_renderbuffer Base; -#if 0 - struct pipe_surface *surface; -#endif -}; - - -/** - * Cast wrapper. - */ -static INLINE struct st_renderbuffer * -st_renderbuffer(struct gl_renderbuffer *rb) -{ - return (struct st_renderbuffer *) rb; -} - - struct pipe_format_info { GLuint format; @@ -168,29 +145,29 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, cpp = info->size; - if (!strb->Base.surface) { - strb->Base.surface = pipe->surface_alloc(pipe, pipeFormat); - if (!strb->Base.surface) + if (!strb->surface) { + strb->surface = pipe->surface_alloc(pipe, pipeFormat); + if (!strb->surface) return GL_FALSE; } /* free old region */ - if (strb->Base.surface->region) { - pipe->region_release(pipe, &strb->Base.surface->region); + if (strb->surface->region) { + pipe->region_release(pipe, &strb->surface->region); } /* Choose a pitch to match hardware requirements: */ pitch = ((cpp * width + 63) & ~63) / cpp; /* XXX fix: device-specific */ - strb->Base.surface->region = pipe->region_alloc(pipe, cpp, pitch, height); - if (!strb->Base.surface->region) + strb->surface->region = pipe->region_alloc(pipe, cpp, pitch, height); + if (!strb->surface->region) return GL_FALSE; /* out of memory, try s/w buffer? */ - ASSERT(strb->Base.surface->region->buffer); + ASSERT(strb->surface->region->buffer); - strb->Base.Width = strb->Base.surface->width = width; - strb->Base.Height = strb->Base.surface->height = height; + strb->Base.Width = strb->surface->width = width; + strb->Base.Height = strb->surface->height = height; return GL_TRUE; } @@ -206,11 +183,11 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); ASSERT(strb); - if (strb && strb->Base.surface) { - if (rb->surface->region) { - pipe->region_release(pipe, &strb->Base.surface->region); + if (strb && strb->surface) { + if (strb->surface->region) { + pipe->region_release(pipe, &strb->surface->region); } - free(strb->Base.surface); + free(strb->surface); } free(strb); } @@ -285,28 +262,28 @@ st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height) struct gl_renderbuffer * st_new_renderbuffer_fb(GLuint intFormat) { - struct st_renderbuffer *irb; + struct st_renderbuffer *strb; - irb = CALLOC_STRUCT(st_renderbuffer); - if (!irb) { + strb = CALLOC_STRUCT(st_renderbuffer); + if (!strb) { _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer"); return NULL; } - _mesa_init_renderbuffer(&irb->Base, 0); - irb->Base.ClassID = 0x42; /* XXX temp */ - irb->Base.InternalFormat = intFormat; + _mesa_init_renderbuffer(&strb->Base, 0); + strb->Base.ClassID = 0x42; /* XXX temp */ + strb->Base.InternalFormat = intFormat; switch (intFormat) { case GL_RGB5: case GL_RGBA8: - irb->Base._BaseFormat = GL_RGBA; + strb->Base._BaseFormat = GL_RGBA; break; case GL_DEPTH_COMPONENT16: - irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + strb->Base._BaseFormat = GL_DEPTH_COMPONENT; break; case GL_DEPTH24_STENCIL8_EXT: - irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; break; default: _mesa_problem(NULL, @@ -315,15 +292,14 @@ st_new_renderbuffer_fb(GLuint intFormat) } /* st-specific methods */ - irb->Base.Delete = st_renderbuffer_delete; - irb->Base.AllocStorage = st_renderbuffer_alloc_storage; - irb->Base.GetPointer = null_get_pointer; - /* span routines set in alloc_storage function */ + strb->Base.Delete = st_renderbuffer_delete; + strb->Base.AllocStorage = st_renderbuffer_alloc_storage; + strb->Base.GetPointer = null_get_pointer; - irb->Base.surface = NULL;/*intel_new_surface(intFormat);*/ - /*irb->Base.surface->rb = irb;*/ + /* surface is allocate in alloc_renderbuffer_storage() */ + strb->surface = NULL; - return &irb->Base; + return &strb->Base; } #endif diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 7f52ab10d7..b2e7ba810c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -30,10 +30,25 @@ #define ST_CB_FBO_H -/* -extern struct gl_renderbuffer * -st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height); -*/ + +/** + * Derived renderbuffer class. Just need to add a pointer to the + * pipe surface. + */ +struct st_renderbuffer +{ + struct gl_renderbuffer Base; + struct pipe_surface *surface; +}; + + +static INLINE struct st_renderbuffer * +st_renderbuffer(struct gl_renderbuffer *rb) +{ + return (struct st_renderbuffer *) rb; +} + + extern struct gl_renderbuffer * st_new_renderbuffer_fb(GLuint intFormat); -- cgit v1.2.3 From 09fbb3837b6aa5dfc6c94f41ab5443820177c569 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Sep 2007 16:01:17 -0600 Subject: Implement query object interface. This replaces the temporary occlusion counter functions we had before. Added new ctx->Driver.WaitQuery() function which should block until the result is ready. Sketch out some code for vertex transformation feedback counters. --- src/mesa/drivers/common/driverfuncs.c | 5 +- src/mesa/main/dd.h | 6 +- src/mesa/main/mtypes.h | 9 +-- src/mesa/main/queryobj.c | 95 ++++++++++++++++-------------- src/mesa/main/queryobj.h | 14 ++++- src/mesa/pipe/failover/fo_context.c | 4 +- src/mesa/pipe/i915simple/i915_context.c | 21 ++++++- src/mesa/pipe/p_context.h | 9 +-- src/mesa/pipe/p_defines.h | 8 +++ src/mesa/pipe/p_state.h | 10 ++++ src/mesa/pipe/softpipe/sp_context.c | 35 ++++++++--- src/mesa/pipe/softpipe/sp_context.h | 7 ++- src/mesa/pipe/softpipe/sp_quad_occlusion.c | 10 ++-- src/mesa/state_tracker/st_cb_queryobj.c | 83 +++++++++++++++++++++++--- 14 files changed, 232 insertions(+), 84 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 500dbb2545..96e5037fa5 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -224,8 +224,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver) /* query objects */ driver->NewQueryObject = _mesa_new_query_object; - driver->BeginQuery = NULL; - driver->EndQuery = NULL; + driver->BeginQuery = _mesa_begin_query; + driver->EndQuery = _mesa_end_query; + driver->WaitQuery = _mesa_wait_query; /* APPLE_vertex_array_object */ driver->NewArrayObject = _mesa_new_array_object; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 582e0c334d..f089fcb48f 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -811,9 +811,9 @@ struct dd_function_table { */ /*@{*/ struct gl_query_object * (*NewQueryObject)(GLcontext *ctx, GLuint id); - void (*BeginQuery)(GLcontext *ctx, GLenum target, - struct gl_query_object *q); - void (*EndQuery)(GLcontext *ctx, GLenum target, struct gl_query_object *q); + void (*BeginQuery)(GLcontext *ctx, struct gl_query_object *q); + void (*EndQuery)(GLcontext *ctx, struct gl_query_object *q); + void (*WaitQuery)(GLcontext *ctx, struct gl_query_object *q); /*@}*/ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 0a64e0c58c..514170dbcf 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2085,10 +2085,11 @@ struct gl_ati_fragment_shader_state */ struct gl_query_object { - GLuint Id; - GLuint64EXT Result; /* the counter */ - GLboolean Active; /* inside Begin/EndQuery */ - GLboolean Ready; /* result is ready */ + GLenum Target; /**< The query target, when active */ + GLuint Id; /**< hash table ID/name */ + GLuint64EXT Result; /**< the counter */ + GLboolean Active; /**< inside Begin/EndQuery */ + GLboolean Ready; /**< result is ready? */ }; diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c index 0e59ba615a..688d0fc7bc 100644 --- a/src/mesa/main/queryobj.c +++ b/src/mesa/main/queryobj.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -53,6 +53,42 @@ _mesa_new_query_object(GLcontext *ctx, GLuint id) } +/** + * Begin a query. Software driver fallback. + * Called via ctx->Driver.BeginQuery(). + */ +void +_mesa_begin_query(GLcontext *ctx, struct gl_query_object *q) +{ + /* no-op */ +} + + +/** + * End a query. Software driver fallback. + * Called via ctx->Driver.EndQuery(). + */ +void +_mesa_end_query(GLcontext *ctx, struct gl_query_object *q) +{ + q->Ready = GL_TRUE; +} + + +/** + * Wait for query to complete. Software driver fallback. + * Called via ctx->Driver.WaitQuery(). + */ +void +_mesa_wait_query(GLcontext *ctx, struct gl_query_object *q) +{ + /* For software drivers, _mesa_end_query() should have completed the query. + * For real hardware, implement a proper WaitQuery() driver function. + */ + assert(q->Ready); +} + + /** * Delete an occlusion query object. * Not removed from hash table here. @@ -61,7 +97,7 @@ _mesa_new_query_object(GLcontext *ctx, GLuint id) static void delete_query_object(struct gl_query_object *q) { - FREE(q); + _mesa_free(q); } @@ -216,6 +252,7 @@ _mesa_BeginQueryARB(GLenum target, GLuint id) } } + q->Target = target; q->Active = GL_TRUE; q->Result = 0; q->Ready = GL_FALSE; @@ -229,9 +266,7 @@ _mesa_BeginQueryARB(GLenum target, GLuint id) } #endif - if (ctx->Driver.BeginQuery) { - ctx->Driver.BeginQuery(ctx, target, q); - } + ctx->Driver.BeginQuery(ctx, q); } @@ -275,13 +310,7 @@ _mesa_EndQueryARB(GLenum target) } q->Active = GL_FALSE; - if (ctx->Driver.EndQuery) { - ctx->Driver.EndQuery(ctx, target, q); - } - else { - /* if we're using software rendering/querying */ - q->Ready = GL_TRUE; - } + ctx->Driver.EndQuery(ctx, q); } @@ -346,13 +375,8 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) switch (pname) { case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } + if (!q->Ready) + ctx->Driver.WaitQuery(ctx, q); /* if result is too large for returned type, clamp to max value */ if (q->Result > 0x7fffffff) { *params = 0x7fffffff; @@ -362,7 +386,6 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) } break; case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ *params = q->Ready; break; default: @@ -390,13 +413,8 @@ _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) switch (pname) { case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } + if (!q->Ready) + ctx->Driver.WaitQuery(ctx, q); /* if result is too large for returned type, clamp to max value */ if (q->Result > 0xffffffff) { *params = 0xffffffff; @@ -406,7 +424,6 @@ _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) } break; case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ *params = q->Ready; break; default: @@ -439,17 +456,11 @@ _mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) switch (pname) { case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } + if (!q->Ready) + ctx->Driver.WaitQuery(ctx, q); *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ *params = q->Ready; break; default: @@ -480,17 +491,11 @@ _mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) switch (pname) { case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } + if (!q->Ready) + ctx->Driver.WaitQuery(ctx, q); *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ *params = q->Ready; break; default: diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h index ada8cf8356..d466aae652 100644 --- a/src/mesa/main/queryobj.h +++ b/src/mesa/main/queryobj.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,6 +36,16 @@ _mesa_init_query(GLcontext *ctx); extern void _mesa_free_query_data(GLcontext *ctx); +extern void +_mesa_begin_query(GLcontext *ctx, struct gl_query_object *q); + +extern void +_mesa_end_query(GLcontext *ctx, struct gl_query_object *q); + +extern void +_mesa_wait_query(GLcontext *ctx, struct gl_query_object *q); + + extern void GLAPIENTRY _mesa_GenQueriesARB(GLsizei n, GLuint *ids); diff --git a/src/mesa/pipe/failover/fo_context.c b/src/mesa/pipe/failover/fo_context.c index b88f1b466c..c58fc9cedc 100644 --- a/src/mesa/pipe/failover/fo_context.c +++ b/src/mesa/pipe/failover/fo_context.c @@ -129,8 +129,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, * at this point - if the hardware doesn't support it, don't * advertise it to the application. */ - failover->pipe.reset_occlusion_counter = hw->reset_occlusion_counter; - failover->pipe.get_occlusion_counter = hw->get_occlusion_counter; + failover->pipe.begin_query = hw->begin_query; + failover->pipe.end_query = hw->end_query; failover_init_state_functions( failover ); diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c index f4121419f7..6e48b3bd03 100644 --- a/src/mesa/pipe/i915simple/i915_context.c +++ b/src/mesa/pipe/i915simple/i915_context.c @@ -149,6 +149,22 @@ static void i915_destroy( struct pipe_context *pipe ) +static void +i915_begin_query(struct pipe_context *pipe, struct pipe_query_object *q) +{ + /* should never be called */ + assert(0); +} + + +static void +i915_end_query(struct pipe_context *pipe, struct pipe_query_object *q) +{ + /* should never be called */ + assert(0); +} + + static boolean i915_draw_elements( struct pipe_context *pipe, struct pipe_buffer_handle *indexBuffer, unsigned indexSize, @@ -257,8 +273,9 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915->pipe.supported_formats = i915_supported_formats; i915->pipe.max_texture_size = i915_max_texture_size; i915->pipe.clear = i915_clear; - i915->pipe.reset_occlusion_counter = NULL; /* no support */ - i915->pipe.get_occlusion_counter = NULL; + + i915->pipe.begin_query = i915_begin_query; + i915->pipe.end_query = i915_end_query; i915->pipe.draw_arrays = i915_draw_arrays; i915->pipe.draw_elements = i915_draw_elements; diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 27a1128365..dafbef410e 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -75,11 +75,12 @@ struct pipe_context { void (*clear)(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue); - /** occlusion counting (XXX this may be temporary - we should probably - * have generic query objects with begin/end methods) + /** + * Query objects */ - void (*reset_occlusion_counter)(struct pipe_context *pipe); - unsigned (*get_occlusion_counter)(struct pipe_context *pipe); + void (*begin_query)(struct pipe_context *pipe, struct pipe_query_object *q); + void (*end_query)(struct pipe_context *pipe, struct pipe_query_object *q); + void (*wait_query)(struct pipe_context *pipe, struct pipe_query_object *q); /* * State functions diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h index c1164c5c08..b3ee890576 100644 --- a/src/mesa/pipe/p_defines.h +++ b/src/mesa/pipe/p_defines.h @@ -299,4 +299,12 @@ #define PIPE_PRIM_POLYGON 9 +/** + * Query object types + */ +#define PIPE_QUERY_OCCLUSION_COUNTER 0 +#define PIPE_QUERY_PRIMITIVES_GENERATED 1 +#define PIPE_QUERY_PRIMITIVES_EMITTED 2 +#define PIPE_QUERY_TYPES 3 + #endif diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index ccd40d39e6..b994d17ea9 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -381,4 +381,14 @@ struct pipe_feedback_buffer { }; +/** + * Hardware queries (occlusion, transform feedback, timing, etc) + */ +struct pipe_query_object { + uint type:3; /**< PIPE_QUERY_x */ + uint ready:1; /**< is result ready? */ + uint64 count; +}; + + #endif diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 26453d9785..92357808e2 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -195,19 +195,37 @@ static void softpipe_destroy( struct pipe_context *pipe ) } -static void softpipe_reset_occlusion_counter(struct pipe_context *pipe) +static void +softpipe_begin_query(struct pipe_context *pipe, struct pipe_query_object *q) { struct softpipe_context *softpipe = softpipe_context( pipe ); - softpipe->occlusion_counter = 0; + assert(q->type < PIPE_QUERY_TYPES); + assert(!softpipe->queries[q->type]); + softpipe->queries[q->type] = q; } -/* XXX pipe param should be const */ -static unsigned softpipe_get_occlusion_counter(struct pipe_context *pipe) + +static void +softpipe_end_query(struct pipe_context *pipe, struct pipe_query_object *q) { struct softpipe_context *softpipe = softpipe_context( pipe ); - return softpipe->occlusion_counter; + assert(q->type < PIPE_QUERY_TYPES); + assert(softpipe->queries[q->type]); + q->ready = 1; /* software rendering is synchronous */ + softpipe->queries[q->type] = NULL; +} + + +static void +softpipe_wait_query(struct pipe_context *pipe, struct pipe_query_object *q) +{ + /* Should never get here since we indicated that the result was + * ready in softpipe_end_query(). + */ + assert(0); } + static const char *softpipe_get_name( struct pipe_context *pipe ) { return "softpipe"; @@ -260,8 +278,11 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush; - softpipe->pipe.reset_occlusion_counter = softpipe_reset_occlusion_counter; - softpipe->pipe.get_occlusion_counter = softpipe_get_occlusion_counter; + + softpipe->pipe.begin_query = softpipe_begin_query; + softpipe->pipe.end_query = softpipe_end_query; + softpipe->pipe.wait_query = softpipe_wait_query; + softpipe->pipe.get_name = softpipe_get_name; softpipe->pipe.get_vendor = softpipe_get_vendor; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 2a6b932523..13d1143c89 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -93,6 +93,11 @@ struct softpipe_context { struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; unsigned dirty; + /* + * Active queries + */ + struct pipe_query_object *queries[PIPE_QUERY_TYPES]; + /* * Mapped vertex buffers */ @@ -120,8 +125,6 @@ struct softpipe_context { /** Derived from scissor and surface bounds: */ struct pipe_scissor_state cliprect; - unsigned occlusion_counter; - unsigned line_stipple_counter; /** Software quad rendering pipeline */ diff --git a/src/mesa/pipe/softpipe/sp_quad_occlusion.c b/src/mesa/pipe/softpipe/sp_quad_occlusion.c index 6b094a5bef..4f178f0557 100644 --- a/src/mesa/pipe/softpipe/sp_quad_occlusion.c +++ b/src/mesa/pipe/softpipe/sp_quad_occlusion.c @@ -44,11 +44,13 @@ static void occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; + struct pipe_query_object *occ + = softpipe->queries[PIPE_QUERY_OCCLUSION_COUNTER]; - softpipe->occlusion_counter += (quad->mask ) & 1; - softpipe->occlusion_counter += (quad->mask >> 1) & 1; - softpipe->occlusion_counter += (quad->mask >> 2) & 1; - softpipe->occlusion_counter += (quad->mask >> 3) & 1; + occ->count += (quad->mask ) & 1; + occ->count += (quad->mask >> 1) & 1; + occ->count += (quad->mask >> 2) & 1; + occ->count += (quad->mask >> 3) & 1; if (quad->mask) qs->next->run(qs->next, quad); diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c index 3a8fbde8ab..5b95dd7fd3 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ b/src/mesa/state_tracker/st_cb_queryobj.c @@ -44,33 +44,102 @@ #include "st_public.h" +struct st_query_object +{ + struct gl_query_object base; + struct pipe_query_object pq; +}; + + +/** + * Cast wrapper + */ +static struct st_query_object * +st_query_object(struct gl_query_object *q) +{ + return (struct st_query_object *) q; +} + + +static struct gl_query_object * +st_NewQueryObject(GLcontext *ctx, GLuint id) +{ + struct st_query_object *stq = CALLOC_STRUCT(st_query_object); + if (stq) { + stq->base.Id = id; + stq->base.Ready = GL_TRUE; + return &stq->base; + } + return NULL; +} + + /** * 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. */ static void -st_BeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +st_BeginQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; - if (target == GL_SAMPLES_PASSED_ARB) { - pipe->reset_occlusion_counter(pipe); + struct st_query_object *stq = st_query_object(q); + + stq->pq.count = 0; + + switch (q->Target) { + case GL_SAMPLES_PASSED_ARB: + stq->pq.type = PIPE_QUERY_OCCLUSION_COUNTER; + break; + case GL_PRIMITIVES_GENERATED_NV: + /* someday */ + stq->pq.type = PIPE_QUERY_PRIMITIVES_GENERATED; + break; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV: + /* someday */ + stq->pq.type = PIPE_QUERY_PRIMITIVES_EMITTED; + break; + default: + assert(0); } + + pipe->begin_query(pipe, &stq->pq); } static void -st_EndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +st_EndQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; - if (target == GL_SAMPLES_PASSED_ARB) { - q->Result = pipe->get_occlusion_counter(pipe); - } + struct st_query_object *stq = st_query_object(q); + + pipe->end_query(pipe, &stq->pq); + stq->base.Ready = stq->pq.ready; + if (stq->base.Ready) + stq->base.Result = stq->pq.count; +} + + +static void +st_WaitQuery(GLcontext *ctx, struct gl_query_object *q) +{ + struct pipe_context *pipe = ctx->st->pipe; + struct st_query_object *stq = st_query_object(q); + + /* this function should only be called if we don't have a ready result */ + assert(!stq->base.Ready); + + pipe->wait_query(pipe, &stq->pq); + q->Ready = GL_TRUE; + q->Result = stq->pq.count; } + void st_init_query_functions(struct dd_function_table *functions) { + functions->NewQueryObject = st_NewQueryObject; functions->BeginQuery = st_BeginQuery; functions->EndQuery = st_EndQuery; + functions->WaitQuery = st_WaitQuery; } -- cgit v1.2.3 From 8fed2466e4056668a76a87cf935b5fbff8ae15ca Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 26 Oct 2007 19:19:09 -0600 Subject: Re-implement GLSL texture sampler variables. GLSL sampler variables indicate which texture unit to use for TEX instructions. Previously, this was baked into the fragment/vertex program and couldn't be readily changed once set. Now, SamplerUnits[] array indicates which texture unit is to be used for each sampler variable. These values are set with glUniform1i(). This is extra state that must be passed to the fragment/vertex program executor at runtime. --- src/mesa/main/config.h | 1 + src/mesa/main/mtypes.h | 6 ++ src/mesa/pipe/failover/fo_context.h | 1 + src/mesa/pipe/failover/fo_state.c | 14 ++++ src/mesa/pipe/i915simple/i915_context.h | 1 + src/mesa/pipe/i915simple/i915_state.c | 10 +++ src/mesa/pipe/p_context.h | 3 + src/mesa/pipe/softpipe/sp_context.c | 1 + src/mesa/pipe/softpipe/sp_context.h | 1 + src/mesa/pipe/softpipe/sp_quad_fs.c | 1 + src/mesa/pipe/softpipe/sp_state.h | 3 + src/mesa/pipe/softpipe/sp_state_sampler.c | 14 ++++ src/mesa/pipe/tgsi/exec/tgsi_exec.c | 5 +- src/mesa/pipe/tgsi/exec/tgsi_exec.h | 1 + src/mesa/shader/prog_execute.c | 16 ++--- src/mesa/shader/prog_execute.h | 2 + src/mesa/shader/prog_instruction.c | 11 +++ src/mesa/shader/prog_instruction.h | 5 ++ src/mesa/shader/prog_parameter.c | 7 +- src/mesa/shader/prog_parameter.h | 2 +- src/mesa/shader/prog_print.c | 7 ++ src/mesa/shader/program.c | 5 ++ src/mesa/shader/shader_api.c | 113 +++++++++++++++++++----------- src/mesa/shader/slang/slang_codegen.c | 15 +++- src/mesa/shader/slang/slang_compile.c | 6 ++ src/mesa/shader/slang/slang_emit.c | 6 +- src/mesa/shader/slang/slang_link.c | 71 +++++++------------ src/mesa/shader/slang/slang_link.h | 4 -- src/mesa/shader/slang/slang_typeinfo.h | 1 + src/mesa/state_tracker/st_atom_sampler.c | 33 ++++++++- src/mesa/swrast/s_fragprog.c | 2 + 31 files changed, 262 insertions(+), 106 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index cebef1c383..8c64248845 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -207,6 +207,7 @@ #define MAX_PROGRAM_ADDRESS_REGS 2 #define MAX_UNIFORMS 128 #define MAX_VARYING 8 +#define MAX_SAMPLERS 8 /*@}*/ /** For GL_ARB_vertex_shader */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 514170dbcf..8adc4e3373 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1901,6 +1901,7 @@ struct gl_program GLbitfield InputsRead; /**< Bitmask of which input regs are read */ GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */ GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */ + GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */ GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */ /** Named parameters, constants, etc. from program text */ @@ -1913,6 +1914,11 @@ struct gl_program /** Vertex program user-defined attributes */ struct gl_program_parameter_list *Attributes; + /** Map from sampler unit to texture unit (set by glUniform1i()) */ + GLubyte SamplerUnits[MAX_SAMPLERS]; + /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */ + GLubyte SamplerTargets[MAX_SAMPLERS]; + /** Logical counts */ /*@{*/ GLuint NumInstructions; diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index 7a597013ab..759b53ccbe 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -84,6 +84,7 @@ struct failover_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; + uint sampler_units[PIPE_MAX_SAMPLERS]; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c index f63137f591..2cd1a50b20 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -294,6 +294,19 @@ failover_set_polygon_stipple( struct pipe_context *pipe, failover->hw->set_polygon_stipple( failover->hw, stipple ); } +static void +failover_set_sampler_units( struct pipe_context *pipe, + uint num_samplers, const uint *units ) +{ + struct failover_context *failover = failover_context(pipe); + uint i; + + for (i = 0; i < num_samplers; i++) + failover->sampler_units[i] = units[i]; + failover->dirty |= FO_NEW_SAMPLER; + failover->hw->set_sampler_units(failover->hw, num_samplers, units); +} + static void * failover_create_rasterizer_state(struct pipe_context *pipe, const struct pipe_rasterizer_state *templ) @@ -470,6 +483,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_clear_color_state = failover_set_clear_color_state; failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; + failover->pipe.set_sampler_units = failover_set_sampler_units; failover->pipe.set_scissor_state = failover_set_scissor_state; failover->pipe.set_texture_state = failover_set_texture_state; failover->pipe.set_viewport_state = failover_set_viewport_state; diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index a3dd392e75..5a3ecedad2 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -173,6 +173,7 @@ struct i915_context struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; + uint sampler_units[PIPE_MAX_SAMPLERS]; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 8da5662e3f..05f8a6e1fd 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -446,6 +446,15 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe, { } +static void i915_set_sampler_units(struct pipe_context *pipe, + uint numSamplers, const uint *units) +{ + struct i915_context *i915 = i915_context(pipe); + uint i; + for (i = 0; i < numSamplers; i++) + i915->sampler_units[i] = units[i]; +} + static void * i915_create_fs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { @@ -765,6 +774,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.set_feedback_buffer = i915_set_feedback_buffer; i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; + i915->pipe.set_sampler_units = i915_set_sampler_units; i915->pipe.set_scissor_state = i915_set_scissor_state; i915->pipe.set_texture_state = i915_set_texture_state; i915->pipe.set_viewport_state = i915_set_viewport_state; diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 3a041f158b..5497f50f73 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -148,6 +148,9 @@ struct pipe_context { void (*set_polygon_stipple)( struct pipe_context *, const struct pipe_poly_stipple * ); + void (*set_sampler_units)( struct pipe_context *, + uint num_samplers, const uint *units ); + void (*set_scissor_state)( struct pipe_context *, const struct pipe_scissor_state * ); diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 476d4ac01c..58ef744f30 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -318,6 +318,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.set_feedback_state = softpipe_set_feedback_state; softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_sampler_units = softpipe_set_sampler_units; softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; softpipe->pipe.set_texture_state = softpipe_set_texture_state; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 3e77bd6b85..88a418d3c7 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -95,6 +95,7 @@ struct softpipe_context { struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + uint sampler_units[PIPE_MAX_SAMPLERS]; unsigned dirty; /* diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 3371b109fc..9b9504cd15 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -85,6 +85,7 @@ shade_quad( /* Consts does not require 16 byte alignment. */ machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + machine->SamplerUnits = softpipe->sampler_units; machine->InterpCoefs = quad->coef; machine->Inputs[0].xyzw[0].f[0] = fx; diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index c194f0ea0d..61532bcdeb 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -99,6 +99,9 @@ void softpipe_delete_vs_state(struct pipe_context *, void *); void softpipe_set_polygon_stipple( struct pipe_context *, const struct pipe_poly_stipple * ); +void softpipe_set_sampler_units( struct pipe_context *, + uint numSamplers, const uint *units ); + void softpipe_set_scissor_state( struct pipe_context *, const struct pipe_scissor_state * ); diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index c00e815f2d..e70eabd578 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -78,3 +78,17 @@ softpipe_set_texture_state(struct pipe_context *pipe, softpipe->dirty |= SP_NEW_TEXTURE; } + + +void +softpipe_set_sampler_units(struct pipe_context *pipe, + uint num_samplers, const uint *units ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + for (i = 0; i < num_samplers; i++) + softpipe->sampler_units[i] = units[i]; + softpipe->dirty |= SP_NEW_SAMPLER; +} + + diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.c b/src/mesa/pipe/tgsi/exec/tgsi_exec.c index 0125f40dd2..66a81b4bd8 100644 --- a/src/mesa/pipe/tgsi/exec/tgsi_exec.c +++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.c @@ -1219,11 +1219,14 @@ exec_tex(struct tgsi_exec_machine *mach, const struct tgsi_full_instruction *inst, boolean biasLod) { - const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; + const uint sampler = inst->FullSrcRegisters[1].SrcRegister.Index; + const uint unit = mach->SamplerUnits[sampler]; union tgsi_exec_channel r[8]; uint chan_index; float lodBias; + // printf("Sampler %u unit %u\n", sampler, unit); + switch (inst->InstructionExtTexture.Texture) { case TGSI_TEXTURE_1D: diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.h b/src/mesa/pipe/tgsi/exec/tgsi_exec.h index 1805e72487..38f9218520 100644 --- a/src/mesa/pipe/tgsi/exec/tgsi_exec.h +++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.h @@ -118,6 +118,7 @@ struct tgsi_exec_machine struct tgsi_exec_vector *Temps; struct tgsi_exec_vector *Addrs; + uint *SamplerUnits; struct tgsi_sampler *Samplers; float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 28d195d0ee..bd64b57eb9 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -1316,22 +1316,22 @@ _mesa_execute_program(GLcontext * ctx, * The rest of the time, just use zero (until we get a more * sophisticated way of computing lambda). */ + const GLuint unit = machine->Samplers[inst->TexSrcUnit]; GLfloat coord[4], color[4], lambda; #if 0 if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + unit) + lambda = span->array->lambda[unit][column]; else #endif lambda = 0.0; fetch_vector4(&inst->SrcReg[0], machine, coord); - machine->FetchTexelLod(ctx, coord, lambda, inst->TexSrcUnit, - color); + machine->FetchTexelLod(ctx, coord, lambda, unit, color); if (DEBUG_PROG) { printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " "lod %f\n", color[0], color[1], color[2], color[3], - inst->TexSrcUnit, + unit, coord[0], coord[1], coord[2], coord[3], lambda); } store_vector4(inst, machine, color); @@ -1375,11 +1375,12 @@ _mesa_execute_program(GLcontext * ctx, case OPCODE_TXP: /* GL_ARB_fragment_program only */ /* Texture lookup w/ projective divide */ { + const GLuint unit = machine->Samplers[inst->TexSrcUnit]; GLfloat texcoord[4], color[4], lambda; #if 0 if (inst->SrcReg[0].File == PROGRAM_INPUT && inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; + lambda = span->array->lambda[unit][column]; else #endif lambda = 0.0; @@ -1393,8 +1394,7 @@ _mesa_execute_program(GLcontext * ctx, texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; } - machine->FetchTexelLod(ctx, texcoord, lambda, - inst->TexSrcUnit, color); + machine->FetchTexelLod(ctx, texcoord, lambda, unit, color); store_vector4(inst, machine, color); } break; diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h index be29eceeda..db7bcee516 100644 --- a/src/mesa/shader/prog_execute.h +++ b/src/mesa/shader/prog_execute.h @@ -62,6 +62,8 @@ struct gl_program_machine GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4]; + GLuint *Samplers; /** Array mapping sampler var to tex unit */ + GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index c84c76fd5b..066129037a 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -246,6 +246,17 @@ _mesa_num_inst_dst_regs(gl_inst_opcode opcode) } +GLboolean +_mesa_is_tex_instruction(gl_inst_opcode opcode) +{ + return (opcode == OPCODE_TEX || + opcode == OPCODE_TXB || + opcode == OPCODE_TXD || + opcode == OPCODE_TXL || + opcode == OPCODE_TXP); +} + + /** * Return string name for given program opcode. */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 643969b367..e8a2407ea8 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -413,11 +413,13 @@ struct prog_instruction */ GLint BranchTarget; +#if 0 /** * For TEX instructions in shaders, the sampler to use for the * texture lookup. */ GLint Sampler; +#endif const char *Comment; }; @@ -443,6 +445,9 @@ _mesa_num_inst_src_regs(gl_inst_opcode opcode); extern GLuint _mesa_num_inst_dst_regs(gl_inst_opcode opcode); +extern GLboolean +_mesa_is_tex_instruction(gl_inst_opcode opcode); + extern const char * _mesa_opcode_string(gl_inst_opcode opcode); diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 9e3d3fecf2..b4008abbd9 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -283,22 +283,25 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList, * Add a sampler to the parameter list. * \param name uniform's name * \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc. + * \param index the sampler number (as seen in TEX instructions) */ GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype) + const char *name, GLenum datatype, GLuint index) { GLint i = _mesa_lookup_parameter_index(paramList, -1, name); if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { ASSERT(paramList->Parameters[i].Size == 1); ASSERT(paramList->Parameters[i].DataType == datatype); + ASSERT(paramList->ParameterValues[i][0] == index); /* already in list */ return i; } else { + GLfloat indexf = index; const GLint size = 1; /* a sampler is basically a texture unit number */ i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, - size, datatype, NULL, NULL); + size, datatype, &indexf, NULL); return i; } } diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 09ff851ea7..40c8c09e09 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -104,7 +104,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList, extern GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype); + const char *name, GLenum datatype, GLuint index); extern GLint _mesa_add_varying(struct gl_program_parameter_list *paramList, diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index e92837f739..c421b1228b 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -719,6 +719,8 @@ _mesa_print_program_opt(const struct gl_program *prog, void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) { + GLuint i; + _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead); _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten); _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); @@ -726,6 +728,11 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) _mesa_printf("NumParameters=%d\n", prog->NumParameters); _mesa_printf("NumAttributes=%d\n", prog->NumAttributes); _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs); + _mesa_printf("Samplers=[ "); + for (i = 0; i < MAX_SAMPLERS; i++) { + _mesa_printf("%d ", prog->SamplerUnits[i]); + } + _mesa_printf("]\n"); _mesa_load_state_parameters(ctx, prog->Parameters); diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 1f227390af..cafc0dcfaa 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -187,12 +187,17 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog, { (void) ctx; if (prog) { + GLuint i; _mesa_bzero(prog, sizeof(*prog)); prog->Id = id; prog->Target = target; prog->Resident = GL_TRUE; prog->RefCount = 1; prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; + + /* default mapping from samplers to texture units */ + for (i = 0; i < MAX_SAMPLERS; i++) + prog->SamplerUnits[i] = i; } return prog; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 9f6c54dd4c..bc5ecdaa15 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1045,6 +1045,28 @@ _mesa_use_program(GLcontext *ctx, GLuint program) } + +/** + * Update the vertex and fragment program's TexturesUsed arrays. + */ +static void +update_textures_used(struct gl_program *prog) +{ + GLuint s; + + memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed)); + + for (s = 0; s < MAX_SAMPLERS; s++) { + if (prog->SamplersUsed & (1 << s)) { + GLuint u = prog->SamplerUnits[s]; + GLuint t = prog->SamplerTargets[s]; + assert(u < MAX_TEXTURE_IMAGE_UNITS); + prog->TexturesUsed[u] |= (1 << t); + } + } +} + + /** * Called via ctx->Driver.Uniform(). */ @@ -1067,26 +1089,6 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, FLUSH_VERTICES(ctx, _NEW_PROGRAM); - /* - * If we're setting a sampler, we must use glUniformi1()! - */ - if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { - GLint unit; - if (type != GL_INT || count != 1) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniform(only glUniform1i can be used " - "to set sampler uniforms)"); - return; - } - /* check that the sampler (tex unit index) is legal */ - unit = ((GLint *) values)[0]; - if (unit >= ctx->Const.MaxTextureImageUnits) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glUniform1(invalid sampler/tex unit index)"); - return; - } - } - if (count < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)"); return; @@ -1119,32 +1121,61 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, return; } - for (k = 0; k < count; k++) { - GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k]; - if (type == GL_INT || - type == GL_INT_VEC2 || - type == GL_INT_VEC3 || - type == GL_INT_VEC4) { - const GLint *iValues = ((const GLint *) values) + k * elems; - for (i = 0; i < elems; i++) { - uniformVal[i] = (GLfloat) iValues[i]; - } + if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { + /* This controls which texture unit which is used by a sampler */ + GLuint texUnit, sampler; + + /* data type for setting samplers must be int */ + if (type != GL_INT || count != 1) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUniform(only glUniform1i can be used " + "to set sampler uniforms)"); + return; } - else { - const GLfloat *fValues = ((const GLfloat *) values) + k * elems; - for (i = 0; i < elems; i++) { - uniformVal[i] = fValues[i]; - } + + sampler = (GLuint) shProg->Uniforms->ParameterValues[location][0]; + texUnit = ((GLuint *) values)[0]; + + /* check that the sampler (tex unit index) is legal */ + if (texUnit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glUniform1(invalid sampler/tex unit index)"); + return; } - } - if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { - if (shProg->VertexProgram) - _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base); - if (shProg->FragmentProgram) - _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base); + if (shProg->VertexProgram) { + shProg->VertexProgram->Base.SamplerUnits[sampler] = texUnit; + update_textures_used(&shProg->VertexProgram->Base); + } + if (shProg->FragmentProgram) { + shProg->FragmentProgram->Base.SamplerUnits[sampler] = texUnit; + update_textures_used(&shProg->FragmentProgram->Base); + } + + FLUSH_VERTICES(ctx, _NEW_TEXTURE); } + else { + /* ordinary uniform variable */ + for (k = 0; k < count; k++) { + GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k]; + if (type == GL_INT || + type == GL_INT_VEC2 || + type == GL_INT_VEC3 || + type == GL_INT_VEC4) { + const GLint *iValues = ((const GLint *) values) + k * elems; + for (i = 0; i < elems; i++) { + uniformVal[i] = (GLfloat) iValues[i]; + } + } + else { + const GLfloat *fValues = ((const GLfloat *) values) + k * elems; + for (i = 0; i < elems; i++) { + uniformVal[i] = fValues[i]; + } + } + } + } } diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index fb1f9d5a20..767ba3ffb4 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2874,14 +2874,23 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, const GLint texIndex = sampler_to_texture_index(var->type.specifier.type); if (texIndex != -1) { - /* Texture sampler: + /* This is a texture sampler variable... * store->File = PROGRAM_SAMPLER - * store->Index = sampler uniform location + * store->Index = sampler number (0..7, typically) * store->Size = texture type index (1D, 2D, 3D, cube, etc) */ +#if 0 GLint samplerUniform = _mesa_add_sampler(prog->Parameters, varName, datatype); - store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex); +#elif 0 + GLint samplerUniform + = _mesa_add_sampler(prog->Samplers, varName, datatype); + (void) _mesa_add_sampler(prog->Parameters, varName, datatype); /* dummy entry */ +#else + const GLint sampNum = A->numSamplers++; + _mesa_add_sampler(prog->Parameters, varName, datatype, sampNum); +#endif + store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex); if (dbg) printf("SAMPLER "); } else if (var->type.qualifier == SLANG_QUAL_UNIFORM) { diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 2be89a5ce0..bfb9ca4db6 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1618,6 +1618,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.program = O->program; A.vartable = O->vartable; A.curFuncEndLabel = NULL; + A.numSamplers = 0; if (!_slang_codegen_global_variable(&A, var, C->type)) return 0; } @@ -1640,6 +1641,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.space.funcs = O->funs; A.space.structs = O->structs; A.space.vars = O->vars; + A.numSamplers = 0; if (!initialize_global(&A, var)) return 0; } @@ -1773,6 +1775,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, A.program = O->program; A.vartable = O->vartable; A.log = C->L; + A.numSamplers = 0; _slang_codegen_function(&A, *parsed_func_ret); } @@ -2152,6 +2155,9 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) shader->Programs[0]->Parameters = _mesa_new_parameter_list(); shader->Programs[0]->Varying = _mesa_new_parameter_list(); shader->Programs[0]->Attributes = _mesa_new_parameter_list(); +#if 0 + shader->Programs[0]->Samplers = _mesa_new_parameter_list(); +#endif } slang_info_log_construct(&info_log); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index fe13f2865c..2b08e7020f 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -906,11 +906,15 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n) assert(n->Children[0]->Store->Size >= TEXTURE_1D_INDEX); assert(n->Children[0]->Store->Size <= TEXTURE_RECT_INDEX); - inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */ inst->TexSrcTarget = n->Children[0]->Store->Size; +#if 0 inst->TexSrcUnit = 27; /* Dummy value; the TexSrcUnit will be computed at * link time, using the sampler uniform's value. */ + inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */ +#else + inst->TexSrcUnit = n->Children[0]->Store->Index; /* i.e. uniform's index */ +#endif return inst; } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index eaa29ba094..32f7168553 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -144,10 +144,14 @@ is_uniform(GLuint file) } +static GLuint shProg_NumSamplers = 0; /** XXX temporary */ + + static GLboolean link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) { GLuint *map, i; + GLuint samplerMap[MAX_SAMPLERS]; #if 0 printf("================ pre link uniforms ===============\n"); @@ -168,10 +172,13 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) /* sanity check */ assert(is_uniform(p->Type)); + /* See if this uniform is already in the linked program's list */ if (p->Name) { + /* this is a named uniform */ j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name); } else { + /* this is an unnamed constant */ /*GLuint swizzle;*/ ASSERT(p->Type == PROGRAM_CONSTANT); if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals, @@ -184,7 +191,8 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) } if (j >= 0) { - /* already in list, check size XXX check this */ + /* already in linked program's list */ + /* check size XXX check this */ #if 0 assert(p->Size == shProg->Uniforms->Parameters[j].Size); #endif @@ -205,7 +213,15 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType); break; case PROGRAM_SAMPLER: - j = _mesa_add_sampler(shProg->Uniforms, p->Name, p->DataType); + { + GLuint sampNum = shProg_NumSamplers++; + GLuint oldSampNum; + j = _mesa_add_sampler(shProg->Uniforms, p->Name, + p->DataType, sampNum); + oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0]; + assert(oldSampNum < MAX_SAMPLERS); + samplerMap[oldSampNum] = sampNum; + } break; default: _mesa_problem(NULL, "bad parameter type in link_uniform_vars()"); @@ -243,6 +259,7 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) /* OK, now scan the program/shader instructions looking for uniform vars, * replacing the old index with the new index. */ + prog->SamplersUsed = 0x0; for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; GLuint j; @@ -257,14 +274,15 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) } } - if (inst->Opcode == OPCODE_TEX || - inst->Opcode == OPCODE_TXB || - inst->Opcode == OPCODE_TXP) { + if (_mesa_is_tex_instruction(inst->Opcode)) { /* printf("====== remap sampler from %d to %d\n", inst->Sampler, map[ inst->Sampler ]); */ - inst->Sampler = map[ inst->Sampler ]; + /* here, texUnit is really samplerUnit */ + inst->TexSrcUnit = samplerMap[inst->TexSrcUnit]; + prog->SamplerTargets[inst->TexSrcUnit] = inst->TexSrcTarget; + prog->SamplersUsed |= (1 << inst->TexSrcUnit); } } @@ -404,36 +422,6 @@ _slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttr -/** - * Scan program for texture instructions, lookup sampler/uniform's value - * to determine which texture unit to use. - * Also, update the program's TexturesUsed[] array. - */ -void -_slang_resolve_samplers(struct gl_shader_program *shProg, - struct gl_program *prog) -{ - GLuint i; - - for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) - prog->TexturesUsed[i] = 0; - - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - if (inst->Opcode == OPCODE_TEX || - inst->Opcode == OPCODE_TXB || - inst->Opcode == OPCODE_TXP) { - GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0]; - assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS); - inst->TexSrcUnit = sampleUnit; - - prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget); - } - } -} - - - /** cast wrapper */ static struct gl_vertex_program * vertex_program(struct gl_program *prog) @@ -490,6 +478,8 @@ _slang_link(GLcontext *ctx, const struct gl_fragment_program *fragProg; GLuint i; + shProg_NumSamplers = 0; /** XXX temporary */ + _mesa_clear_shader_program_data(ctx, shProg); shProg->Uniforms = _mesa_new_parameter_list(); @@ -549,13 +539,6 @@ _slang_link(GLcontext *ctx, shProg->FragmentProgram->Base.Parameters = shProg->Uniforms; } - if (shProg->VertexProgram) { - _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base); - } - if (shProg->FragmentProgram) { - _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base); - } - if (shProg->VertexProgram) { if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) { /*goto cleanup;*/ @@ -601,7 +584,7 @@ _slang_link(GLcontext *ctx, _mesa_print_program(&fragProg->Base); _mesa_print_program_parameters(ctx, &fragProg->Base); #endif -#if 0 +#if 01 printf("************** linked fragment prog\n"); _mesa_print_program(&shProg->FragmentProgram->Base); _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base); diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 606b9e46b1..8ef8a6b4b3 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -32,10 +32,6 @@ extern void _slang_link(GLcontext *ctx, GLhandleARB h, struct gl_shader_program *shProg); -extern void -_slang_resolve_samplers(struct gl_shader_program *shProg, - struct gl_program *prog); - extern void _slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib); diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index 587331e8b1..ad5aa3e195 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -65,6 +65,7 @@ typedef struct slang_assemble_ctx_ struct slang_label_ *curFuncEndLabel; struct slang_ir_node_ *CurLoop; struct slang_function_ *CurFunction; + GLuint numSamplers; } slang_assemble_ctx; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 38de35933e..80b8cae013 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -113,6 +113,23 @@ gl_filter_to_img_filter(GLenum filter) } +static struct gl_fragment_program * +current_fragment_program(GLcontext *ctx) +{ + struct gl_fragment_program *f; + + if (ctx->Shader.CurrentProgram && + ctx->Shader.CurrentProgram->LinkStatus && + ctx->Shader.CurrentProgram->FragmentProgram) { + f = ctx->Shader.CurrentProgram->FragmentProgram; + } + else { + f = ctx->FragmentProgram._Current; + assert(f); + } + return f; +} + static void update_samplers(struct st_context *st) @@ -165,13 +182,27 @@ update_samplers(struct st_context *st) st->pipe->bind_sampler_state(st->pipe, u, cso->data); } } + + + /* mapping from sampler vars to texture units */ + { + struct gl_fragment_program *fprog = current_fragment_program(st->ctx); + const GLubyte *samplerUnits = fprog->Base.SamplerUnits; + uint sample_units[PIPE_MAX_SAMPLERS]; + uint s; + for (s = 0; s < PIPE_MAX_SAMPLERS; s++) { + sample_units[s] = fprog->Base.SamplerUnits[s]; + } + + st->pipe->set_sampler_units(st->pipe, PIPE_MAX_SAMPLERS, sample_units); + } } const struct st_tracked_state st_update_sampler = { .name = "st_update_sampler", .dirty = { - .mesa = _NEW_TEXTURE, + .mesa = _NEW_TEXTURE | _NEW_PROGRAM, .st = 0, }, .update = update_samplers diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 6656ebc0d0..6ee8bfd0a5 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -113,6 +113,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, machine->DerivY = (GLfloat (*)[4]) span->attrStepY; machine->NumDeriv = FRAG_ATTRIB_MAX; + machine->Samplers = program->Base.SamplerUnits; + /* if running a GLSL program (not ARB_fragment_program) */ if (ctx->Shader.CurrentProgram) { /* Store front/back facing value in register FOGC.Y */ -- cgit v1.2.3 From f18d4e058ed979c6e42e868c7febde4fa62c5810 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 29 Oct 2007 12:25:46 -0600 Subject: Remove ctx field from texenvprog_cache --- src/mesa/main/mtypes.h | 1 - src/mesa/main/texenvprogram.c | 23 +++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 8adc4e3373..44587ae962 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1566,7 +1566,6 @@ struct texenvprog_cache_item { struct texenvprog_cache { struct texenvprog_cache_item **items; GLuint size, n_items; - GLcontext *ctx; }; /** diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index d8f3314c70..cf92503c34 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -399,9 +399,9 @@ static struct ureg get_tex_temp( struct texenv_fragment_program *p ) } -static void release_temps( struct texenv_fragment_program *p ) +static void release_temps(GLcontext *ctx, struct texenv_fragment_program *p ) { - GLuint max_temp = p->ctx->Const.FragmentProgram.MaxTemps; + GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; /* KW: To support tex_env_crossbar, don't release the registers in * temps_output. @@ -1037,7 +1037,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, p.one = undef; p.last_tex_stage = 0; - release_temps(&p); + release_temps(ctx, &p); if (key->enabled_units) { /* First pass - to support texture_env_crossbar, first identify @@ -1055,7 +1055,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) if (key->enabled_units & (1<size = size; } -static void clear_cache( struct texenvprog_cache *cache ) +static void clear_cache( GLcontext *ctx, struct texenvprog_cache *cache ) { struct texenvprog_cache_item *c, *next; GLuint i; @@ -1178,8 +1178,7 @@ static void clear_cache( struct texenvprog_cache *cache ) for (c = cache->items[i]; c; c = next) { next = c->next; _mesa_free(c->key); - cache->ctx->Driver.DeleteProgram(cache->ctx, - (struct gl_program *) c->data); + ctx->Driver.DeleteProgram(ctx, (struct gl_program *) c->data); _mesa_free(c); } cache->items[i] = NULL; @@ -1190,7 +1189,8 @@ static void clear_cache( struct texenvprog_cache *cache ) } -static void cache_item( struct texenvprog_cache *cache, +static void cache_item( GLcontext *ctx, + struct texenvprog_cache *cache, GLuint hash, const struct state_key *key, void *data ) @@ -1208,7 +1208,7 @@ static void cache_item( struct texenvprog_cache *cache, if (cache->size < 1000) rehash(cache); else - clear_cache(cache); + clear_cache(ctx, cache); } cache->n_items++; @@ -1259,7 +1259,7 @@ _mesa_get_fixed_func_fragment_program(GLcontext *ctx) create_new_program(ctx, &key, prog); - cache_item(&ctx->Texture.env_fp_cache, hash, &key, prog); + cache_item(ctx, &ctx->Texture.env_fp_cache, hash, &key, prog); } return prog; @@ -1301,7 +1301,6 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx ) void _mesa_TexEnvProgramCacheInit( GLcontext *ctx ) { - ctx->Texture.env_fp_cache.ctx = ctx; ctx->Texture.env_fp_cache.size = 17; ctx->Texture.env_fp_cache.n_items = 0; ctx->Texture.env_fp_cache.items = (struct texenvprog_cache_item **) @@ -1312,6 +1311,6 @@ void _mesa_TexEnvProgramCacheInit( GLcontext *ctx ) void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx ) { - clear_cache(&ctx->Texture.env_fp_cache); + clear_cache(ctx, &ctx->Texture.env_fp_cache); _mesa_free(ctx->Texture.env_fp_cache.items); } -- cgit v1.2.3 From b26aae67f5fe4194b48a5d3ddf704797b804b58c Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 31 Oct 2007 12:00:38 -0600 Subject: alloc caches for fixed-func vertex/fragment progs --- src/mesa/main/mtypes.h | 7 +++++++ src/mesa/shader/program.c | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 44587ae962..b435c29793 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -123,6 +123,7 @@ typedef int GLfixed; /*@{*/ struct _mesa_HashTable; struct gl_pixelstore_attrib; +struct gl_program_cache; struct gl_texture_format; struct gl_texture_image; struct gl_texture_object; @@ -2000,6 +2001,9 @@ struct gl_vertex_program_state /** Program to emulate fixed-function T&L (see above) */ struct gl_vertex_program *_TnlProgram; + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; + #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; GLvoid *CallbackData; @@ -2033,6 +2037,9 @@ struct gl_fragment_program_state /** Program to emulate fixed-function texture env/combine (see above) */ struct gl_fragment_program *_TexEnvProgram; + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; + #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; GLvoid *CallbackData; diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index ed1aacd068..f13aa18e95 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -33,6 +33,7 @@ #include "context.h" #include "hash.h" #include "program.h" +#include "prog_cache.h" #include "prog_parameter.h" #include "prog_instruction.h" @@ -66,6 +67,7 @@ _mesa_init_program(GLcontext *ctx) ctx->VertexProgram.TrackMatrix[i] = GL_NONE; ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; } + ctx->VertexProgram.Cache = _mesa_new_program_cache(); #endif #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program @@ -73,8 +75,10 @@ _mesa_init_program(GLcontext *ctx) ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram; assert(ctx->FragmentProgram.Current); ctx->FragmentProgram.Current->Base.RefCount++; + ctx->FragmentProgram.Cache = _mesa_new_program_cache(); #endif + /* XXX probably move this stuff */ #if FEATURE_ATI_fragment_shader ctx->ATIFragmentShader.Enabled = GL_FALSE; -- cgit v1.2.3 From f4a5ea2ccb472958a4635c606e9510011bceaa3d Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 31 Oct 2007 12:45:32 -0600 Subject: Update texenvprogram.c code to use prog_cache.c routines. --- src/mesa/main/mtypes.h | 14 ----- src/mesa/main/texenvprogram.c | 135 +++--------------------------------------- src/mesa/main/texenvprogram.h | 11 +--- src/mesa/main/texstate.c | 4 -- 4 files changed, 9 insertions(+), 155 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b435c29793..8e49431a8f 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1557,17 +1557,6 @@ struct gl_texture_unit /*@}*/ }; -struct texenvprog_cache_item { - GLuint hash; - void *key; - struct gl_fragment_program *data; - struct texenvprog_cache_item *next; -}; - -struct texenvprog_cache { - struct texenvprog_cache_item **items; - GLuint size, n_items; -}; /** * Texture attribute group (GL_TEXTURE_BIT). @@ -1599,9 +1588,6 @@ struct gl_texture_attrib /** GL_EXT_shared_texture_palette */ GLboolean SharedPalette; struct gl_color_table Palette; - - /** Cached texenv fragment programs */ - struct texenvprog_cache env_fp_cache; }; diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index cf92503c34..efb3b35f6a 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -29,6 +29,7 @@ #include "macros.h" #include "enums.h" #include "shader/prog_parameter.h" +#include "shader/prog_cache.h" #include "shader/prog_instruction.h" #include "shader/prog_print.h" #include "shader/prog_statevars.h" @@ -1131,109 +1132,6 @@ create_new_program(GLcontext *ctx, struct state_key *key, } -static struct gl_fragment_program * -search_cache(const struct texenvprog_cache *cache, - GLuint hash, - const void *key, - GLuint keysize) -{ - struct texenvprog_cache_item *c; - - for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->hash == hash && memcmp(c->key, key, keysize) == 0) - return (struct gl_fragment_program *) c->data; - } - - return NULL; -} - -static void rehash( struct texenvprog_cache *cache ) -{ - struct texenvprog_cache_item **items; - struct texenvprog_cache_item *c, *next; - GLuint size, i; - - size = cache->size * 3; - items = (struct texenvprog_cache_item**) _mesa_malloc(size * sizeof(*items)); - _mesa_memset(items, 0, size * sizeof(*items)); - - for (i = 0; i < cache->size; i++) - for (c = cache->items[i]; c; c = next) { - next = c->next; - c->next = items[c->hash % size]; - items[c->hash % size] = c; - } - - _mesa_free(cache->items); - cache->items = items; - cache->size = size; -} - -static void clear_cache( GLcontext *ctx, struct texenvprog_cache *cache ) -{ - struct texenvprog_cache_item *c, *next; - GLuint i; - - for (i = 0; i < cache->size; i++) { - for (c = cache->items[i]; c; c = next) { - next = c->next; - _mesa_free(c->key); - ctx->Driver.DeleteProgram(ctx, (struct gl_program *) c->data); - _mesa_free(c); - } - cache->items[i] = NULL; - } - - - cache->n_items = 0; -} - - -static void cache_item( GLcontext *ctx, - struct texenvprog_cache *cache, - GLuint hash, - const struct state_key *key, - void *data ) -{ - struct texenvprog_cache_item *c - = (struct texenvprog_cache_item *) MALLOC(sizeof(*c)); - c->hash = hash; - - c->key = _mesa_malloc(sizeof(*key)); - memcpy(c->key, key, sizeof(*key)); - - c->data = (struct gl_fragment_program *) data; - - if (cache->n_items > cache->size * 1.5) { - if (cache->size < 1000) - rehash(cache); - else - clear_cache(ctx, cache); - } - - cache->n_items++; - c->next = cache->items[hash % cache->size]; - cache->items[hash % cache->size] = c; -} - -static GLuint hash_key( const struct state_key *key ) -{ - GLuint *ikey = (GLuint *)key; - GLuint hash = 0, i; - - /* Make a slightly better attempt at a hash function: - */ - for (i = 0; i < sizeof(*key)/sizeof(*ikey); i++) - { - hash += ikey[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - return hash; -} - - /** * Return a fragment program which implements the current * fixed-function texture, fog and color-sum operations. @@ -1243,23 +1141,21 @@ _mesa_get_fixed_func_fragment_program(GLcontext *ctx) { struct gl_fragment_program *prog; struct state_key key; - GLuint hash; make_state_key(ctx, &key); - hash = hash_key(&key); - prog = search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key)); + prog = (struct gl_fragment_program *) + _mesa_search_program_cache(ctx->FragmentProgram.Cache, + &key, sizeof(key)); if (!prog) { - if (0) - _mesa_printf("Building new texenv proggy for key %x\n", hash); - prog = (struct gl_fragment_program *) ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); create_new_program(ctx, &key, prog); - cache_item(ctx, &ctx->Texture.env_fp_cache, hash, &key, prog); + _mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache, + &key, sizeof(key), &prog->Base); } return prog; @@ -1297,20 +1193,3 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx ) (struct gl_program *) ctx->FragmentProgram._Current); } } - - -void _mesa_TexEnvProgramCacheInit( GLcontext *ctx ) -{ - ctx->Texture.env_fp_cache.size = 17; - ctx->Texture.env_fp_cache.n_items = 0; - ctx->Texture.env_fp_cache.items = (struct texenvprog_cache_item **) - _mesa_calloc(ctx->Texture.env_fp_cache.size * - sizeof(struct texenvprog_cache_item)); -} - - -void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx ) -{ - clear_cache(ctx, &ctx->Texture.env_fp_cache); - _mesa_free(ctx->Texture.env_fp_cache.items); -} diff --git a/src/mesa/main/texenvprogram.h b/src/mesa/main/texenvprogram.h index ac73910cb5..a7aa60cf37 100644 --- a/src/mesa/main/texenvprogram.h +++ b/src/mesa/main/texenvprogram.h @@ -1,13 +1,8 @@ -/** - * \file texenvprogram.h - * Texture state management. - */ - /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 7.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -38,7 +33,5 @@ extern struct gl_fragment_program * _mesa_get_fixed_func_fragment_program(GLcontext *ctx); extern void _mesa_UpdateTexEnvProgram( GLcontext *ctx ); -extern void _mesa_TexEnvProgramCacheInit( GLcontext *ctx ); -extern void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx ); #endif diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index c9f8a0656e..cb7da39b51 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -3210,8 +3210,6 @@ _mesa_init_texture(GLcontext *ctx) ctx->Texture.SharedPalette = GL_FALSE; _mesa_init_colortable(&ctx->Texture.Palette); - _mesa_TexEnvProgramCacheInit( ctx ); - /* Allocate proxy textures */ if (!alloc_proxy_textures( ctx )) return GL_FALSE; @@ -3239,6 +3237,4 @@ _mesa_free_texture_data(GLcontext *ctx) for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable ); - - _mesa_TexEnvProgramCacheDestroy( ctx ); } -- cgit v1.2.3 From bc029247d9d886f4546a4c3a36737d09c488b7f9 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 4 Apr 2008 18:59:21 -0600 Subject: mesa: no longer combine vertex/fragment shader parameters/uniforms GLSL Vertex and fragment shaders now have independent parameter buffers. A new gl_uniform_list is used to keep track of program uniforms and where each uniform is located in each shader's parameter buffer. This makes better use of the space in each buffer and simplifies shader linking. --- src/mesa/main/mtypes.h | 8 +- src/mesa/shader/shader_api.c | 308 ++++++++++++++++++++++--------------- src/mesa/shader/slang/slang_link.c | 192 +++++++---------------- src/mesa/sources | 1 + 4 files changed, 239 insertions(+), 270 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 8e49431a8f..50b22d25bf 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1868,6 +1868,7 @@ enum register_file /** Vertex and fragment instructions */ struct prog_instruction; struct gl_program_parameter_list; +struct gl_uniform_list; /** @@ -2104,7 +2105,7 @@ struct gl_query_state /** - * A GLSL shader object. + * A GLSL vertex or fragment shader object. */ struct gl_shader { @@ -2122,7 +2123,8 @@ struct gl_shader /** - * A GLSL program object. Basically a linked collection of "shaders". + * A GLSL program object. + * Basically a linked collection of vertex and fragment shaders. */ struct gl_shader_program { @@ -2137,7 +2139,7 @@ struct gl_shader_program /* post-link info: */ struct gl_vertex_program *VertexProgram; /**< Linked vertex program */ struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */ - struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */ + struct gl_uniform_list *Uniforms; struct gl_program_parameter_list *Varying; struct gl_program_parameter_list *Attributes; /**< Vertex attributes */ GLboolean LinkStatus; /**< GL_LINK_STATUS */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 4cb8bb8ed1..9c419c9903 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -43,6 +43,7 @@ #include "prog_parameter.h" #include "prog_print.h" #include "prog_statevars.h" +#include "prog_uniform.h" #include "shader/shader_api.h" #include "shader/slang/slang_compile.h" #include "shader/slang/slang_link.h" @@ -75,25 +76,25 @@ _mesa_clear_shader_program_data(GLcontext *ctx, struct gl_shader_program *shProg) { if (shProg->VertexProgram) { - if (shProg->VertexProgram->Base.Parameters == shProg->Uniforms) { - /* to prevent a double-free in the next call */ - shProg->VertexProgram->Base.Parameters = NULL; - } + /* Set ptr to NULL since the param list is shared with the + * original/unlinked program. + */ + shProg->VertexProgram->Base.Parameters = NULL; ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base); shProg->VertexProgram = NULL; } if (shProg->FragmentProgram) { - if (shProg->FragmentProgram->Base.Parameters == shProg->Uniforms) { - /* to prevent a double-free in the next call */ - shProg->FragmentProgram->Base.Parameters = NULL; - } + /* Set ptr to NULL since the param list is shared with the + * original/unlinked program. + */ + shProg->FragmentProgram->Base.Parameters = NULL; ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base); shProg->FragmentProgram = NULL; } if (shProg->Uniforms) { - _mesa_free_parameter_list(shProg->Uniforms); + _mesa_free_uniform_list(shProg->Uniforms); shProg->Uniforms = NULL; } @@ -673,39 +674,43 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *nameOut) { - struct gl_shader_program *shProg + const struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); - GLuint ind, j; + const struct gl_program *prog; + GLint progPos; if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform"); return; } - if (!shProg->Uniforms || index >= shProg->Uniforms->NumParameters) { + if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); return; } - ind = 0; - for (j = 0; j < shProg->Uniforms->NumParameters; j++) { - if (shProg->Uniforms->Parameters[j].Type == PROGRAM_UNIFORM || - shProg->Uniforms->Parameters[j].Type == PROGRAM_SAMPLER) { - if (ind == index) { - /* found it */ - copy_string(nameOut, maxLength, length, - shProg->Uniforms->Parameters[j].Name); - if (size) - *size = shProg->Uniforms->Parameters[j].Size; - if (type) - *type = shProg->Uniforms->Parameters[j].DataType; - return; - } - ind++; + progPos = shProg->Uniforms->Uniforms[index].VertPos; + if (progPos >= 0) { + prog = &shProg->VertexProgram->Base; + } + else { + progPos = shProg->Uniforms->Uniforms[index].FragPos; + if (progPos >= 0) { + prog = &shProg->FragmentProgram->Base; } } - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); + if (!prog || progPos < 0) + return; /* should never happen */ + + if (nameOut) + copy_string(nameOut, maxLength, length, + prog->Parameters->Parameters[progPos].Name); + if (size) + *size = prog->Parameters->Parameters[progPos].Size; + + if (type) + *type = prog->Parameters->Parameters[progPos].DataType; } @@ -792,14 +797,10 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program, PROGRAM_INPUT) + 1; break; case GL_ACTIVE_UNIFORMS: - *params - = _mesa_num_parameters_of_type(shProg->Uniforms, PROGRAM_UNIFORM) - + _mesa_num_parameters_of_type(shProg->Uniforms, PROGRAM_SAMPLER); + *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0; break; case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = MAX2( - _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_UNIFORM), - _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_SAMPLER)); + *params = _mesa_longest_uniform_name(shProg->Uniforms); if (*params > 0) (*params)++; /* add one for terminating zero */ break; @@ -896,10 +897,23 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (shProg) { - GLint i; - if (location >= 0 && location < shProg->Uniforms->NumParameters) { - for (i = 0; i < shProg->Uniforms->Parameters[location].Size; i++) { - params[i] = shProg->Uniforms->ParameterValues[location][i]; + if (location < shProg->Uniforms->NumUniforms) { + GLint progPos, i; + const struct gl_program *prog; + + progPos = shProg->Uniforms->Uniforms[location].VertPos; + if (progPos >= 0) { + prog = &shProg->VertexProgram->Base; + } + else { + progPos = shProg->Uniforms->Uniforms[location].FragPos; + if (progPos >= 0) { + prog = &shProg->FragmentProgram->Base; + } + } + + for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) { + params[i] = prog->Parameters->ParameterValues[progPos][i]; } } else { @@ -920,23 +934,10 @@ _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); - if (shProg) { - GLuint loc; - for (loc = 0; loc < shProg->Uniforms->NumParameters; loc++) { - const struct gl_program_parameter *u - = shProg->Uniforms->Parameters + loc; - /* XXX this is a temporary simplification / short-cut. - * We need to handle things like "e.c[0].b" as seen in the - * GLSL orange book, page 189. - */ - if ((u->Type == PROGRAM_UNIFORM || - u->Type == PROGRAM_SAMPLER) && !strcmp(u->Name, name)) { - return loc; - } - } - } - return -1; + if (!shProg) + return -1; + return _mesa_lookup_uniform(shProg->Uniforms, name); } @@ -1067,6 +1068,78 @@ update_textures_used(struct gl_program *prog) } +/** + * Set the value of a program's uniform variable. + * \param program the program whose uniform to update + * \param location the location/index of the uniform + * \param type the datatype of the uniform + * \param count the number of uniforms to set + * \param elems number of elements per uniform + * \param values the new values + */ +static void +set_program_uniform(GLcontext *ctx, struct gl_program *program, GLint location, + GLenum type, GLint count, GLint elems, const void *values) +{ + if (program->Parameters->Parameters[location].Type == PROGRAM_SAMPLER) { + /* This controls which texture unit which is used by a sampler */ + GLuint texUnit, sampler; + + /* data type for setting samplers must be int */ + if (type != GL_INT || count != 1) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUniform(only glUniform1i can be used " + "to set sampler uniforms)"); + return; + } + + sampler = (GLuint) program->Parameters->ParameterValues[location][0]; + texUnit = ((GLuint *) values)[0]; + + /* check that the sampler (tex unit index) is legal */ + if (texUnit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glUniform1(invalid sampler/tex unit index)"); + return; + } + + /* This maps a sampler to a texture unit: */ + program->SamplerUnits[sampler] = texUnit; + update_textures_used(program); + + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + } + else { + /* ordinary uniform variable */ + GLint k, i; + + if (count * elems > program->Parameters->Parameters[location].Size) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)"); + return; + } + + for (k = 0; k < count; k++) { + GLfloat *uniformVal = program->Parameters->ParameterValues[location + k]; + if (type == GL_INT || + type == GL_INT_VEC2 || + type == GL_INT_VEC3 || + type == GL_INT_VEC4) { + const GLint *iValues = ((const GLint *) values) + k * elems; + for (i = 0; i < elems; i++) { + uniformVal[i] = (GLfloat) iValues[i]; + } + } + else { + const GLfloat *fValues = ((const GLfloat *) values) + k * elems; + for (i = 0; i < elems; i++) { + uniformVal[i] = fValues[i]; + } + } + } + } +} + + /** * Called via ctx->Driver.Uniform(). */ @@ -1075,20 +1148,18 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, const GLvoid *values, GLenum type) { struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; - GLint elems, i, k; + GLint elems; if (!shProg || !shProg->LinkStatus) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)"); return; } - if (location < 0 || location >= (GLint) shProg->Uniforms->NumParameters) { + if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)"); return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - if (count < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)"); return; @@ -1116,63 +1187,54 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, return; } - if (count * elems > shProg->Uniforms->Parameters[location].Size) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)"); - return; - } - - if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { - /* This controls which texture unit which is used by a sampler */ - GLuint texUnit, sampler; - - /* data type for setting samplers must be int */ - if (type != GL_INT || count != 1) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniform(only glUniform1i can be used " - "to set sampler uniforms)"); - return; - } - - sampler = (GLuint) shProg->Uniforms->ParameterValues[location][0]; - texUnit = ((GLuint *) values)[0]; + FLUSH_VERTICES(ctx, _NEW_PROGRAM); - /* check that the sampler (tex unit index) is legal */ - if (texUnit >= ctx->Const.MaxTextureImageUnits) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glUniform1(invalid sampler/tex unit index)"); - return; + /* A uniform var may be used by both a vertex shader and a fragment + * shader. We may need to update one or both shader's uniform here: + */ + if (shProg->VertexProgram) { + GLint loc = shProg->Uniforms->Uniforms[location].VertPos; + if (loc >= 0) { + set_program_uniform(ctx, &shProg->VertexProgram->Base, + loc, type, count, elems, values); } + } - if (shProg->VertexProgram) { - shProg->VertexProgram->Base.SamplerUnits[sampler] = texUnit; - update_textures_used(&shProg->VertexProgram->Base); - } - if (shProg->FragmentProgram) { - shProg->FragmentProgram->Base.SamplerUnits[sampler] = texUnit; - update_textures_used(&shProg->FragmentProgram->Base); + if (shProg->FragmentProgram) { + GLint loc = shProg->Uniforms->Uniforms[location].FragPos; + if (loc >= 0) { + set_program_uniform(ctx, &shProg->FragmentProgram->Base, + loc, type, count, elems, values); } + } +} - FLUSH_VERTICES(ctx, _NEW_TEXTURE); +static void +set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, + GLuint location, GLuint rows, GLuint cols, + GLboolean transpose, const GLfloat *values) +{ + /* + * Note: the _columns_ of a matrix are stored in program registers, not + * the rows. + */ + /* XXXX need to test 3x3 and 2x2 matrices... */ + if (transpose) { + GLuint row, col; + for (col = 0; col < cols; col++) { + GLfloat *v = program->Parameters->ParameterValues[location + col]; + for (row = 0; row < rows; row++) { + v[row] = values[row * cols + col]; + } + } } else { - /* ordinary uniform variable */ - for (k = 0; k < count; k++) { - GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k]; - if (type == GL_INT || - type == GL_INT_VEC2 || - type == GL_INT_VEC3 || - type == GL_INT_VEC4) { - const GLint *iValues = ((const GLint *) values) + k * elems; - for (i = 0; i < elems; i++) { - uniformVal[i] = (GLfloat) iValues[i]; - } - } - else { - const GLfloat *fValues = ((const GLfloat *) values) + k * elems; - for (i = 0; i < elems; i++) { - uniformVal[i] = fValues[i]; - } + GLuint row, col; + for (col = 0; col < cols; col++) { + GLfloat *v = program->Parameters->ParameterValues[location + col]; + for (row = 0; row < rows; row++) { + v[row] = values[col * rows + row]; } } } @@ -1193,7 +1255,7 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, "glUniformMatrix(program not linked)"); return; } - if (location < 0 || location >= shProg->Uniforms->NumParameters) { + if (location < 0 || location >= shProg->Uniforms->NumUniforms) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)"); return; } @@ -1204,27 +1266,19 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, FLUSH_VERTICES(ctx, _NEW_PROGRAM); - /* - * Note: the _columns_ of a matrix are stored in program registers, not - * the rows. - */ - /* XXXX need to test 3x3 and 2x2 matrices... */ - if (transpose) { - GLuint row, col; - for (col = 0; col < cols; col++) { - GLfloat *v = shProg->Uniforms->ParameterValues[location + col]; - for (row = 0; row < rows; row++) { - v[row] = values[row * cols + col]; - } + if (shProg->VertexProgram) { + GLint loc = shProg->Uniforms->Uniforms[location].VertPos; + if (loc >= 0) { + set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base, + loc, rows, cols, transpose, values); } } - else { - GLuint row, col; - for (col = 0; col < cols; col++) { - GLfloat *v = shProg->Uniforms->ParameterValues[location + col]; - for (row = 0; row < rows; row++) { - v[row] = values[col * rows + row]; - } + + if (shProg->FragmentProgram) { + GLint loc = shProg->Uniforms->Uniforms[location].FragPos; + if (loc >= 0) { + set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base, + loc, rows, cols, transpose, values); } } } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 390ae56aa5..addff20421 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -37,12 +37,17 @@ #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "shader/prog_statevars.h" +#include "shader/prog_uniform.h" #include "shader/shader_api.h" #include "slang_link.h" - +/** + * Linking varying vars involves rearranging varying vars so that the + * vertex program's output varyings matches the order of the fragment + * program's input varyings. + */ static GLboolean link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) { @@ -132,148 +137,53 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) } -static GLboolean -is_uniform(GLuint file) -{ - return (file == PROGRAM_ENV_PARAM || - file == PROGRAM_STATE_VAR || - file == PROGRAM_NAMED_PARAM || - file == PROGRAM_CONSTANT || - file == PROGRAM_SAMPLER || - file == PROGRAM_UNIFORM); -} - - -static GLuint shProg_NumSamplers = 0; /** XXX temporary */ - - -static GLboolean -link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) +/** + * Build the shProg->Uniforms list. + * This is basically a list/index of all uniforms found in either/both of + * the vertex and fragment shaders. + */ +static void +link_uniform_vars(struct gl_shader_program *shProg, + struct gl_program *prog, + GLuint *numSamplers) { - GLuint *map, i; GLuint samplerMap[MAX_SAMPLERS]; + GLuint i; -#if 0 - printf("================ pre link uniforms ===============\n"); - _mesa_print_parameter_list(shProg->Uniforms); -#endif - - map = (GLuint *) malloc(prog->Parameters->NumParameters * sizeof(GLuint)); - if (!map) - return GL_FALSE; - - for (i = 0; i < prog->Parameters->NumParameters; /* incr below*/) { - /* see if this uniform is in the linked uniform list */ + for (i = 0; i < prog->Parameters->NumParameters; i++) { const struct gl_program_parameter *p = prog->Parameters->Parameters + i; - const GLfloat *pVals = prog->Parameters->ParameterValues[i]; - GLint j; - GLint size; - /* sanity check */ - assert(is_uniform(p->Type)); - - /* See if this uniform is already in the linked program's list */ - if (p->Name) { - /* this is a named uniform */ - j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name); - } - else { - /* this is an unnamed constant */ - /*GLuint swizzle;*/ - ASSERT(p->Type == PROGRAM_CONSTANT); - if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals, - p->Size, &j, NULL)) { - assert(j >= 0); - } - else { - j = -1; - } - } - - if (j >= 0) { - /* already in linked program's list */ - /* check size XXX check this */ -#if 0 - assert(p->Size == shProg->Uniforms->Parameters[j].Size); -#endif - } - else { - /* not already in linked list */ - switch (p->Type) { - case PROGRAM_ENV_PARAM: - j = _mesa_add_named_parameter(shProg->Uniforms, p->Name, pVals); - break; - case PROGRAM_CONSTANT: - j = _mesa_add_named_constant(shProg->Uniforms, p->Name, pVals, p->Size); - break; - case PROGRAM_STATE_VAR: - j = _mesa_add_state_reference(shProg->Uniforms, p->StateIndexes); - break; - case PROGRAM_UNIFORM: - j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType); - break; - case PROGRAM_SAMPLER: - { - GLuint sampNum = shProg_NumSamplers++; - GLuint oldSampNum; - j = _mesa_add_sampler(shProg->Uniforms, p->Name, - p->DataType, sampNum); - oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0]; - assert(oldSampNum < MAX_SAMPLERS); - samplerMap[oldSampNum] = sampNum; - } - break; - default: - _mesa_problem(NULL, "bad parameter type in link_uniform_vars()"); - return GL_FALSE; - } + /* + * XXX FIX NEEDED HERE + * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR. + * For example, modelview matrix, light pos, etc. + * Also, we need to update the state-var name-generator code to + * generate GLSL-style names, like "gl_LightSource[0].position". + * Furthermore, we'll need to fix the state-var's size/datatype info. + */ + + if (p->Type == PROGRAM_UNIFORM || + p->Type == PROGRAM_SAMPLER) { + _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i); } - ASSERT(j >= 0); - - size = p->Size; - while (size > 0) { - map[i] = j; - i++; - j++; - size -= 4; + if (p->Type == PROGRAM_SAMPLER) { + /* Allocate a new sampler index */ + GLuint sampNum = *numSamplers; + GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0]; + assert(oldSampNum < MAX_SAMPLERS); + samplerMap[oldSampNum] = sampNum; + (*numSamplers)++; } - } -#if 0 - printf("================ post link uniforms ===============\n"); - _mesa_print_parameter_list(shProg->Uniforms); -#endif - -#if 0 - { - GLuint i; - for (i = 0; i < prog->Parameters->NumParameters; i++) { - printf("map[%d] = %d\n", i, map[i]); - } - _mesa_print_parameter_list(shProg->Uniforms); - } -#endif - /* OK, now scan the program/shader instructions looking for uniform vars, + /* OK, now scan the program/shader instructions looking for sampler vars, * replacing the old index with the new index. */ prog->SamplersUsed = 0x0; for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; - GLuint j; - - if (is_uniform(inst->DstReg.File)) { - inst->DstReg.Index = map[ inst->DstReg.Index ]; - } - - for (j = 0; j < 3; j++) { - if (is_uniform(inst->SrcReg[j].File)) { - inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ]; - } - } - if (_mesa_is_tex_instruction(inst->Opcode)) { /* printf("====== remap sampler from %d to %d\n", @@ -286,9 +196,6 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) } } - free(map); - - return GL_TRUE; } @@ -476,13 +383,12 @@ _slang_link(GLcontext *ctx, { const struct gl_vertex_program *vertProg; const struct gl_fragment_program *fragProg; + GLuint numSamplers = 0; GLuint i; - shProg_NumSamplers = 0; /** XXX temporary */ - _mesa_clear_shader_program_data(ctx, shProg); - shProg->Uniforms = _mesa_new_parameter_list(); + shProg->Uniforms = _mesa_new_uniform_list(); shProg->Varying = _mesa_new_parameter_list(); /** @@ -519,24 +425,30 @@ _slang_link(GLcontext *ctx, shProg->FragmentProgram = NULL; } + /* link varying vars */ if (shProg->VertexProgram) link_varying_vars(shProg, &shProg->VertexProgram->Base); if (shProg->FragmentProgram) link_varying_vars(shProg, &shProg->FragmentProgram->Base); + /* link uniform vars */ if (shProg->VertexProgram) - link_uniform_vars(shProg, &shProg->VertexProgram->Base); + link_uniform_vars(shProg, &shProg->VertexProgram->Base, &numSamplers); if (shProg->FragmentProgram) - link_uniform_vars(shProg, &shProg->FragmentProgram->Base); + link_uniform_vars(shProg, &shProg->FragmentProgram->Base, &numSamplers); + + /*_mesa_print_uniforms(shProg->Uniforms);*/ - /* The vertex and fragment programs share a common set of uniforms now */ if (shProg->VertexProgram) { - _mesa_free_parameter_list(shProg->VertexProgram->Base.Parameters); - shProg->VertexProgram->Base.Parameters = shProg->Uniforms; + /* Rather than cloning the parameter list here, just share it. + * We need to be careful _mesa_clear_shader_program_data() in + * to avoid double-freeing. + */ + shProg->VertexProgram->Base.Parameters = vertProg->Base.Parameters; } if (shProg->FragmentProgram) { - _mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters); - shProg->FragmentProgram->Base.Parameters = shProg->Uniforms; + /* see comment just above */ + shProg->FragmentProgram->Base.Parameters = fragProg->Base.Parameters; } if (shProg->VertexProgram) { diff --git a/src/mesa/sources b/src/mesa/sources index d109dce5bc..a4e2026e4b 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -213,6 +213,7 @@ SHADER_SOURCES = \ shader/prog_parameter.c \ shader/prog_print.c \ shader/prog_statevars.c \ + shader/prog_uniform.c \ shader/programopt.c \ shader/shader_api.c \ -- cgit v1.2.3 From a56a59ce74b7f18f25a13992d2a2c1ae7cf973ce Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 7 May 2008 08:55:33 -0600 Subject: gallium: implement full reference counting for vertex/fragment programs Use _mesa_reference_vert/fragprog() wherever we assign program pointers. Fixes a memory corruption bug found with glean/api2 test. Another memory bug involving shaders yet to be fixed... Picked from gallium-0.1 --- src/mesa/main/context.c | 26 ++++---- src/mesa/main/mtypes.h | 4 +- src/mesa/main/state.c | 32 ++++++---- src/mesa/shader/prog_cache.c | 5 +- src/mesa/shader/program.c | 103 +++++++++++++++++++++----------- src/mesa/shader/program.h | 22 +++++++ src/mesa/shader/shader_api.c | 6 +- src/mesa/shader/slang/slang_link.c | 12 ++-- src/mesa/state_tracker/st_atom_shader.c | 7 ++- src/mesa/state_tracker/st_context.c | 3 + src/mesa/state_tracker/st_program.h | 24 +++++++- 11 files changed, 170 insertions(+), 74 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7b8d934170..b9053344b2 100755 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -150,8 +150,6 @@ int MESA_DEBUG_FLAGS = 0; /* ubyte -> float conversion */ GLfloat _mesa_ubyte_to_float_color_tab[256]; -static void -free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ); /** @@ -423,12 +421,14 @@ alloc_shared_state( GLcontext *ctx ) #endif #if FEATURE_ARB_vertex_program - ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); + ss->DefaultVertexProgram = (struct gl_vertex_program *) + ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); if (!ss->DefaultVertexProgram) goto cleanup; #endif #if FEATURE_ARB_fragment_program - ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); + ss->DefaultFragmentProgram = (struct gl_fragment_program *) + ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!ss->DefaultFragmentProgram) goto cleanup; #endif @@ -513,12 +513,10 @@ alloc_shared_state( GLcontext *ctx ) _mesa_DeleteHashTable(ss->Programs); #endif #if FEATURE_ARB_vertex_program - if (ss->DefaultVertexProgram) - ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram); + _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); #endif #if FEATURE_ARB_fragment_program - if (ss->DefaultFragmentProgram) - ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram); + _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); #endif #if FEATURE_ATI_fragment_shader if (ss->DefaultFragmentShader) @@ -695,10 +693,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->Programs); #endif #if FEATURE_ARB_vertex_program - ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram); + _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); #endif #if FEATURE_ARB_fragment_program - ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram); + _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); #endif #if FEATURE_ATI_fragment_shader @@ -1190,6 +1188,14 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_unreference_framebuffer(&ctx->ReadBuffer); } + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); + + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); + _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 50b22d25bf..463142fe39 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2203,10 +2203,10 @@ struct gl_shared_state /*@{*/ struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */ #if FEATURE_ARB_vertex_program - struct gl_program *DefaultVertexProgram; + struct gl_vertex_program *DefaultVertexProgram; #endif #if FEATURE_ARB_fragment_program - struct gl_program *DefaultFragmentProgram; + struct gl_fragment_program *DefaultFragmentProgram; #endif /*@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 0b1c56fdd5..90379a1772 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -982,16 +982,20 @@ update_program(GLcontext *ctx) #endif if (shProg && shProg->LinkStatus && shProg->FragmentProgram) { /* user-defined fragment shader */ - ctx->FragmentProgram._Current = shProg->FragmentProgram; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + shProg->FragmentProgram); } else if (ctx->FragmentProgram._Enabled) { /* use user-defined fragment program */ - ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + ctx->FragmentProgram.Current); } else if (ctx->FragmentProgram._MaintainTexEnvProgram) { /* fragment program generated from fixed-function state */ - ctx->FragmentProgram._Current = _mesa_get_fixed_func_fragment_program(ctx); - ctx->FragmentProgram._TexEnvProgram = ctx->FragmentProgram._Current; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + _mesa_get_fixed_func_fragment_program(ctx)); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + ctx->FragmentProgram._Current); /* XXX get rid of this confusing stuff someday? */ ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; @@ -1000,7 +1004,7 @@ update_program(GLcontext *ctx) } else { /* no fragment program */ - ctx->FragmentProgram._Current = NULL; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); } if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) { @@ -1013,29 +1017,33 @@ update_program(GLcontext *ctx) **/ #if 1 /* XXX get rid of this someday? */ - ctx->VertexProgram._TnlProgram = NULL; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); #endif if (shProg && shProg->LinkStatus && shProg->VertexProgram) { /* user-defined vertex shader */ - ctx->VertexProgram._Current = shProg->VertexProgram; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + shProg->VertexProgram); } else if (ctx->VertexProgram._Enabled) { /* use user-defined vertex program */ - ctx->VertexProgram._Current = ctx->VertexProgram.Current; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + ctx->VertexProgram.Current); } else if (ctx->VertexProgram._MaintainTnlProgram) { /* vertex program generated from fixed-function state */ - ctx->VertexProgram._Current = _mesa_get_fixed_func_vertex_program(ctx); - ctx->VertexProgram._TnlProgram = ctx->VertexProgram._Current; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + _mesa_get_fixed_func_vertex_program(ctx)); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, + ctx->VertexProgram._Current); } else { /* no vertex program / used fixed-function code */ - ctx->VertexProgram._Current = NULL; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); } if (ctx->VertexProgram._Current != prevVP && ctx->Driver.BindProgram) { ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - (struct gl_program *) ctx->VertexProgram._Current); + (struct gl_program *) ctx->VertexProgram._Current); } } diff --git a/src/mesa/shader/prog_cache.c b/src/mesa/shader/prog_cache.c index dd0241ef24..36a25377c5 100644 --- a/src/mesa/shader/prog_cache.c +++ b/src/mesa/shader/prog_cache.c @@ -30,6 +30,7 @@ #include "main/mtypes.h" #include "main/imports.h" #include "shader/prog_cache.h" +#include "shader/program.h" struct cache_item @@ -109,7 +110,7 @@ clear_cache(GLcontext *ctx, struct gl_program_cache *cache) for (c = cache->items[i]; c; c = next) { next = c->next; _mesa_free(c->key); - ctx->Driver.DeleteProgram(ctx, c->program); + _mesa_reference_program(ctx, &c->program, NULL); _mesa_free(c); } cache->items[i] = NULL; @@ -177,7 +178,7 @@ _mesa_program_cache_insert(GLcontext *ctx, c->key = _mesa_malloc(keysize); memcpy(c->key, key, keysize); - c->program = program; + c->program = program; /* no refcount change */ if (cache->n_items > cache->size * 1.5) { if (cache->size < 1000) diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 0ed7f833d2..9a23c5d7d3 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -60,9 +60,9 @@ _mesa_init_program(GLcontext *ctx) ctx->VertexProgram.Enabled = GL_FALSE; ctx->VertexProgram.PointSizeEnabled = GL_FALSE; ctx->VertexProgram.TwoSideEnabled = GL_FALSE; - ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + ctx->Shared->DefaultVertexProgram); assert(ctx->VertexProgram.Current); - ctx->VertexProgram.Current->Base.RefCount++; for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { ctx->VertexProgram.TrackMatrix[i] = GL_NONE; ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; @@ -72,9 +72,9 @@ _mesa_init_program(GLcontext *ctx) #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program ctx->FragmentProgram.Enabled = GL_FALSE; - ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + ctx->Shared->DefaultFragmentProgram); assert(ctx->FragmentProgram.Current); - ctx->FragmentProgram.Current->Base.RefCount++; ctx->FragmentProgram.Cache = _mesa_new_program_cache(); #endif @@ -96,19 +96,11 @@ void _mesa_free_program_data(GLcontext *ctx) { #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program - if (ctx->VertexProgram.Current) { - ctx->VertexProgram.Current->Base.RefCount--; - if (ctx->VertexProgram.Current->Base.RefCount <= 0) - ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base)); - } + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache); #endif #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program - if (ctx->FragmentProgram.Current) { - ctx->FragmentProgram.Current->Base.RefCount--; - if (ctx->FragmentProgram.Current->Base.RefCount <= 0) - ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base)); - } + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); _mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache); #endif /* XXX probably move this stuff */ @@ -325,6 +317,59 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id) } +/** + * Reference counting for vertex/fragment programs + */ +void +_mesa_reference_program(GLcontext *ctx, + struct gl_program **ptr, + struct gl_program *prog) +{ + assert(ptr); + if (*ptr && prog) { + /* sanity check */ + ASSERT((*ptr)->Target == prog->Target); + } + if (*ptr == prog) { + return; /* no change */ + } + if (*ptr) { + GLboolean deleteFlag; + + /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/ +#if 0 + printf("Program %p %u 0x%x Refcount-- to %d\n", + *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1); +#endif + ASSERT((*ptr)->RefCount > 0); + (*ptr)->RefCount--; + + deleteFlag = ((*ptr)->RefCount == 0); + /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/ + + if (deleteFlag) { + ASSERT(ctx); + ctx->Driver.DeleteProgram(ctx, *ptr); + } + + *ptr = NULL; + } + + assert(!*ptr); + if (prog) { + /*_glthread_LOCK_MUTEX(prog->Mutex);*/ + prog->RefCount++; +#if 0 + printf("Program %p %u 0x%x Refcount++ to %d\n", + prog, prog->Id, prog->Target, prog->RefCount); +#endif + /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/ + } + + *ptr = prog; +} + + /** * Return a copy of a program. * XXX Problem here if the program object is actually OO-derivation @@ -340,8 +385,9 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) return NULL; assert(clone->Target == prog->Target); + assert(clone->RefCount == 1); + clone->String = (GLubyte *) _mesa_strdup((char *) prog->String); - clone->RefCount = 1; clone->Format = prog->Format; clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions); if (!clone->Instructions) { @@ -704,9 +750,9 @@ _mesa_BindProgram(GLenum target, GLuint id) /* Bind a default program */ newProg = NULL; if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */ - newProg = ctx->Shared->DefaultVertexProgram; + newProg = &ctx->Shared->DefaultVertexProgram->Base; else - newProg = ctx->Shared->DefaultFragmentProgram; + newProg = &ctx->Shared->DefaultFragmentProgram->Base; } else { /* Bind a user program */ @@ -734,26 +780,16 @@ _mesa_BindProgram(GLenum target, GLuint id) return; } - /* unbind/delete oldProg */ - if (curProg->Id != 0) { - /* decrement refcount on previously bound fragment program */ - curProg->RefCount--; - /* and delete if refcount goes below one */ - if (curProg->RefCount <= 0) { - /* the program ID was already removed from the hash table */ - ctx->Driver.DeleteProgram(ctx, curProg); - } - } - /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ - ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + (struct gl_vertex_program *) newProg); } else if (target == GL_FRAGMENT_PROGRAM_NV || target == GL_FRAGMENT_PROGRAM_ARB) { - ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + (struct gl_fragment_program *) newProg); } - newProg->RefCount++; /* Never null pointers */ ASSERT(ctx->VertexProgram.Current); @@ -811,10 +847,7 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids) } /* The ID is immediately available for re-use now */ _mesa_HashRemove(ctx->Shared->Programs, ids[i]); - prog->RefCount--; - if (prog->RefCount <= 0) { - ctx->Driver.DeleteProgram(ctx, prog); - } + _mesa_reference_program(ctx, &prog, NULL); } } } diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 414a57d39c..08fe576afc 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -83,6 +83,28 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog); extern struct gl_program * _mesa_lookup_program(GLcontext *ctx, GLuint id); +extern void +_mesa_reference_program(GLcontext *ctx, + struct gl_program **ptr, + struct gl_program *prog); + +static INLINE void +_mesa_reference_vertprog(GLcontext *ctx, + struct gl_vertex_program **ptr, + struct gl_vertex_program *prog) +{ + _mesa_reference_program(ctx, (struct gl_program **) ptr, + (struct gl_program *) prog); +} + +static INLINE void +_mesa_reference_fragprog(GLcontext *ctx, + struct gl_fragment_program **ptr, + struct gl_fragment_program *prog) +{ + _mesa_reference_program(ctx, (struct gl_program **) ptr, + (struct gl_program *) prog); +} extern struct gl_program * _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 9c419c9903..f12fa28d97 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -80,8 +80,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx, * original/unlinked program. */ shProg->VertexProgram->Base.Parameters = NULL; - ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base); - shProg->VertexProgram = NULL; + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); } if (shProg->FragmentProgram) { @@ -89,8 +88,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx, * original/unlinked program. */ shProg->FragmentProgram->Base.Parameters = NULL; - ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base); - shProg->FragmentProgram = NULL; + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); } if (shProg->Uniforms) { diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index addff20421..ae581553dc 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -410,19 +410,19 @@ _slang_link(GLcontext *ctx, * changing src/dst registers after merging the uniforms and varying vars. */ if (vertProg) { - shProg->VertexProgram - = vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, + vertex_program(_mesa_clone_program(ctx, &vertProg->Base))); } else { - shProg->VertexProgram = NULL; + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); } if (fragProg) { - shProg->FragmentProgram - = fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, + fragment_program(_mesa_clone_program(ctx, &fragProg->Base))); } else { - shProg->FragmentProgram = NULL; + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); } /* link varying vars */ diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 652500f52a..7745591afb 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -39,6 +39,7 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "shader/program.h" #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" @@ -264,14 +265,16 @@ update_linkage( struct st_context *st ) */ assert(st->ctx->VertexProgram._Current); stvp = st_vertex_program(st->ctx->VertexProgram._Current); + assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); assert(st->ctx->FragmentProgram._Current); stfp = st_fragment_program(st->ctx->FragmentProgram._Current); + assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); xvp = find_translated_vp(st, stvp, stfp); - st->vp = stvp; - st->fp = stfp; + st_reference_vertprog(st, &st->vp, stvp); + st_reference_fragprog(st, &st->fp, stfp); cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index c900064f2b..8db55a179f 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -158,6 +158,9 @@ static void st_destroy_context_priv( struct st_context *st ) { uint i; + st_reference_fragprog(st, &st->fp, NULL); + st_reference_vertprog(st, &st->vp, NULL); + draw_destroy(st->draw); st_destroy_atoms( st ); st_destroy_draw( st ); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index d8f26da2ee..bf07a50789 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -34,7 +34,8 @@ #ifndef ST_PROGRAM_H #define ST_PROGRAM_H -#include "mtypes.h" +#include "main/mtypes.h" +#include "shader/program.h" #include "pipe/p_shader_tokens.h" @@ -115,6 +116,27 @@ st_vertex_program( struct gl_vertex_program *vp ) } +static INLINE void +st_reference_vertprog(struct st_context *st, + struct st_vertex_program **ptr, + struct st_vertex_program *prog) +{ + _mesa_reference_program(st->ctx, + (struct gl_program **) ptr, + (struct gl_program *) prog); +} + +static INLINE void +st_reference_fragprog(struct st_context *st, + struct st_fragment_program **ptr, + struct st_fragment_program *prog) +{ + _mesa_reference_program(st->ctx, + (struct gl_program **) ptr, + (struct gl_program *) prog); +} + + extern void st_translate_fragment_program(struct st_context *st, struct st_fragment_program *fp, -- cgit v1.2.3 From 8b11fa4d4496032246b33182b9285c1181d41f1f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 13 Jun 2008 16:45:15 -0600 Subject: mesa: move some glapi bits around Move _glapi_proc typedef from glapitable.h to glapi.h Also, don't include glapitable.h from glapi.h Before we were including the huge glapitable.h file in every .c file. --- src/mesa/glapi/dispatch.h | 3 +++ src/mesa/glapi/gl_table.py | 1 - src/mesa/glapi/glapi.h | 5 ++++- src/mesa/glapi/glapitable.h | 1 - src/mesa/main/blend.c | 1 + src/mesa/main/context.c | 1 + src/mesa/main/mtypes.h | 3 +-- 7 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/glapi/dispatch.h b/src/mesa/glapi/dispatch.h index 7123156085..98f654f402 100644 --- a/src/mesa/glapi/dispatch.h +++ b/src/mesa/glapi/dispatch.h @@ -28,6 +28,9 @@ #if !defined( _DISPATCH_H_ ) # define _DISPATCH_H_ +#include "glapitable.h" + + /** * \file dispatch.h * Macros for handling GL dispatch tables. diff --git a/src/mesa/glapi/gl_table.py b/src/mesa/glapi/gl_table.py index 69f7bd7c7b..7023a4b71a 100644 --- a/src/mesa/glapi/gl_table.py +++ b/src/mesa/glapi/gl_table.py @@ -56,7 +56,6 @@ class PrintGlTable(gl_XML.gl_print_base): print '# define GLAPIENTRYP GLAPIENTRY *' print '#endif' print '' - print 'typedef void (*_glapi_proc)(void); /* generic function pointer */' print '' print 'struct _glapi_table' print '{' diff --git a/src/mesa/glapi/glapi.h b/src/mesa/glapi/glapi.h index ddfb1cffb9..20d35769cf 100644 --- a/src/mesa/glapi/glapi.h +++ b/src/mesa/glapi/glapi.h @@ -46,10 +46,13 @@ #include "GL/gl.h" -#include "glapitable.h" #include "glthread.h" +struct _glapi_table; + +typedef void (*_glapi_proc)(void); /* generic function pointer */ + typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...); diff --git a/src/mesa/glapi/glapitable.h b/src/mesa/glapi/glapitable.h index 48941f5590..5d9d40a8a2 100644 --- a/src/mesa/glapi/glapitable.h +++ b/src/mesa/glapi/glapitable.h @@ -37,7 +37,6 @@ # define GLAPIENTRYP GLAPIENTRY * #endif -typedef void (*_glapi_proc)(void); /* generic function pointer */ struct _glapi_table { diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index 81bd4c2f32..742247f8e2 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -36,6 +36,7 @@ #include "enums.h" #include "macros.h" #include "mtypes.h" +#include "glapi/glapitable.h" /** diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 086272ca01..dcc518e9fd 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -146,6 +146,7 @@ #include "vtxfmt.h" #include "glapi/glthread.h" #include "glapi/glapioffsets.h" +#include "glapi/glapitable.h" #include "shader/program.h" #include "shader/shader_api.h" #include "shader/atifragshader.h" diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 463142fe39..8a6c84368a 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -38,8 +38,7 @@ #include "glheader.h" #include /* __GLcontextModes (GLvisual) */ #include "config.h" /* Hardwired parameters */ -#include "glapi/glapitable.h" -#include "glapi/glthread.h" +#include "glapi/glapi.h" #include "math/m_matrix.h" /* GLmatrix */ #include "bitset.h" -- cgit v1.2.3 From d378f7b3dfda3b549e4b02380e492671cc34bb59 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 25 Jun 2008 08:45:14 -0600 Subject: mesa: point size arrays --- src/mesa/main/arrayobj.c | 9 +++++++++ src/mesa/main/enable.c | 12 ++++++++++++ src/mesa/main/ffvertex_prog.c | 34 ++++++++++++++++++++++++++++++---- src/mesa/main/glheader.h | 10 ++++++++++ src/mesa/main/mfeatures.h | 1 + src/mesa/main/mtypes.h | 4 ++++ src/mesa/main/state.c | 2 +- src/mesa/main/varray.c | 31 +++++++++++++++++++++++++++++++ src/mesa/main/varray.h | 4 ++++ src/mesa/state_tracker/st_program.c | 4 ++++ src/mesa/vbo/vbo_exec_array.c | 4 ++++ 11 files changed, 110 insertions(+), 5 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index f08f99d8e1..d62661e2b5 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -164,6 +164,15 @@ _mesa_initialize_array_object( GLcontext *ctx, obj->VertexAttrib[i].Normalized = GL_FALSE; } +#if FEATURE_point_size_array + obj->PointSize.Type = GL_FLOAT; + obj->PointSize.Stride = 0; + obj->PointSize.StrideB = 0; + obj->PointSize.Ptr = NULL; + obj->PointSize.Enabled = GL_FALSE; + obj->PointSize.BufferObj = ctx->Array.NullBufferObj; +#endif + #if FEATURE_ARB_vertex_buffer_object /* Vertex array buffers */ obj->Vertex.BufferObj = ctx->Array.NullBufferObj; diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 6b4ad8eea3..9dc55d4e69 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -92,6 +92,13 @@ client_state(GLcontext *ctx, GLenum cap, GLboolean state) flag = _NEW_ARRAY_COLOR1; break; +#if FEATURE_point_size_array + case GL_POINT_SIZE_ARRAY_OES: + var = &ctx->Array.ArrayObj->PointSize.Enabled; + flag = _NEW_ARRAY_POINT_SIZE; + break; +#endif + #if FEATURE_NV_vertex_program case GL_VERTEX_ATTRIB_ARRAY0_NV: case GL_VERTEX_ATTRIB_ARRAY1_NV: @@ -652,6 +659,7 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_EDGE_FLAG_ARRAY: case GL_FOG_COORDINATE_ARRAY_EXT: case GL_SECONDARY_COLOR_ARRAY_EXT: + case GL_POINT_SIZE_ARRAY_OES: client_state( ctx, cap, state ); return; @@ -1174,6 +1182,10 @@ _mesa_IsEnabled( GLenum cap ) case GL_SECONDARY_COLOR_ARRAY_EXT: CHECK_EXTENSION(EXT_secondary_color); return (ctx->Array.ArrayObj->SecondaryColor.Enabled != 0); +#if FEATURE_point_size_array + case GL_POINT_SIZE_ARRAY_OES: + return (ctx->Array.ArrayObj->PointSize.Enabled != 0); +#endif /* GL_EXT_histogram */ case GL_HISTOGRAM: diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index e6c7c1040f..2baae77570 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -63,6 +63,7 @@ struct state_key { unsigned separate_specular:1; unsigned fog_mode:2; unsigned point_attenuated:1; + unsigned point_array:1; unsigned texture_enabled_global:1; unsigned fragprog_inputs_read:12; @@ -264,6 +265,9 @@ static struct state_key *make_state_key( GLcontext *ctx ) if (ctx->Point._Attenuated) key->point_attenuated = 1; + if (ctx->Array.ArrayObj->PointSize.Enabled) + key->point_array = 1; + if (ctx->Texture._TexGenEnabled || ctx->Texture._TexMatEnabled || ctx->Texture._EnabledUnits) @@ -444,12 +448,18 @@ static void release_temps( struct tnl_program *p ) +/** + * \param input one of VERT_ATTRIB_x tokens. + */ static struct ureg register_input( struct tnl_program *p, GLuint input ) { p->program->Base.InputsRead |= (1<program->Base.OutputsWritten |= (1<state->point_attenuated) - build_pointsize(p); + build_atten_pointsize(p); + else if (p->state->point_array) + build_array_pointsize(p); #if 0 else - constant_pointsize(p); + build_constant_pointsize(p); #endif /* Finish up: diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index 57d7e60ad3..3131a356b8 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -167,6 +167,16 @@ #endif +#ifndef GL_OES_point_size_array +#define GL_POINT_SIZE_ARRAY_OES 0x8B9C +#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A +#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B +#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C +#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F +#endif + + + #if !defined(CAPI) && defined(WIN32) && !defined(BUILD_FOR_SNAP) #define CAPI _cdecl #endif diff --git a/src/mesa/main/mfeatures.h b/src/mesa/main/mfeatures.h index a305bbd605..c3c337ea90 100644 --- a/src/mesa/main/mfeatures.h +++ b/src/mesa/main/mfeatures.h @@ -49,6 +49,7 @@ #define FEATURE_fixedpt 0 #define FEATURE_histogram _HAVE_FULL_GL #define FEATURE_pixel_transfer _HAVE_FULL_GL +#define FEATURE_point_size_array 0 #define FEATURE_texgen _HAVE_FULL_GL #define FEATURE_texture_fxt1 _HAVE_FULL_GL #define FEATURE_texture_s3tc _HAVE_FULL_GL diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 8a6c84368a..dceb7611f2 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -151,6 +151,7 @@ enum VERT_ATTRIB_COLOR1 = 4, VERT_ATTRIB_FOG = 5, VERT_ATTRIB_COLOR_INDEX = 6, + VERT_ATTRIB_POINT_SIZE = 6, /*alias*/ VERT_ATTRIB_EDGEFLAG = 7, VERT_ATTRIB_TEX0 = 8, VERT_ATTRIB_TEX1 = 9, @@ -1707,6 +1708,7 @@ struct gl_array_object struct gl_client_array Index; struct gl_client_array EdgeFlag; struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; + struct gl_client_array PointSize; /*@}*/ /** Generic arrays for vertex programs/shaders */ @@ -2748,6 +2750,7 @@ struct gl_matrix_stack #define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG #define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX #define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG +#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */ #define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0 #define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1 #define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2 @@ -2765,6 +2768,7 @@ struct gl_matrix_stack /*@}*/ + /** * \name A bunch of flags that we think might be useful to drivers. * diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 4d1fdbf47c..315253d90a 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -448,7 +448,7 @@ _mesa_update_state_locked( GLcontext *ctx ) prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); } if (ctx->VertexProgram._MaintainTnlProgram) { - prog_flags |= (_NEW_TEXTURE | _NEW_TEXTURE_MATRIX | + prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT | _NEW_FOG | _NEW_LIGHT | _MESA_NEW_NEED_EYE_COORDS); diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 220db35855..50fe874556 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -468,6 +468,37 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) } +void GLAPIENTRY +_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GLsizei elementSize; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (stride < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPointSizePointer(stride)" ); + return; + } + + switch (type) { + case GL_FLOAT: + elementSize = sizeof(GLfloat); + break; +#if FEATURE_fixedpt + case GL_FIXED: + elementSize = sizeof(GLfixed); + break; +#endif + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glPointSizePointer(type)" ); + return; + } + + update_array(ctx, &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE, + elementSize, 1, type, stride, GL_FALSE, ptr); +} + + #if FEATURE_NV_vertex_program void GLAPIENTRY _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index ba91ecf5f6..f557940738 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -111,6 +111,10 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); +extern void GLAPIENTRY +_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr); + + extern void GLAPIENTRY _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index d450c30694..958096f68e 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -136,6 +136,10 @@ st_translate_vertex_program(struct st_context *st, vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG; vs_input_semantic_index[slot] = 0; break; + case VERT_ATTRIB_POINT_SIZE: + vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; + vs_input_semantic_index[slot] = 0; + break; case VERT_ATTRIB_TEX0: case VERT_ATTRIB_TEX1: case VERT_ATTRIB_TEX2: diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index e3d2fc51cb..bf97956286 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -107,6 +107,10 @@ static void bind_array_obj( GLcontext *ctx ) exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &ctx->Array.ArrayObj->SecondaryColor; exec->array.legacy_array[VERT_ATTRIB_FOG] = &ctx->Array.ArrayObj->FogCoord; exec->array.legacy_array[VERT_ATTRIB_COLOR_INDEX] = &ctx->Array.ArrayObj->Index; + if (ctx->Array.ArrayObj->PointSize.Enabled) { + /* this aliases COLOR_INDEX */ + exec->array.legacy_array[VERT_ATTRIB_POINT_SIZE] = &ctx->Array.ArrayObj->PointSize; + } exec->array.legacy_array[VERT_ATTRIB_EDGEFLAG] = &ctx->Array.ArrayObj->EdgeFlag; for (i = 0; i < 8; i++) -- cgit v1.2.3 From 429a08384c2ea66d446e46beb28e33ee3b764d52 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 27 Jun 2008 16:02:43 +0200 Subject: gallium: handle msaa --- src/gallium/include/pipe/p_state.h | 6 +- src/gallium/winsys/dri/intel/intel_screen.c | 6 +- src/mesa/drivers/dri/common/utils.c | 97 ++++++++++++++++------------- src/mesa/drivers/dri/common/utils.h | 3 +- src/mesa/main/mtypes.h | 1 + src/mesa/state_tracker/st_cb_fbo.c | 4 +- src/mesa/state_tracker/st_cb_fbo.h | 2 +- src/mesa/state_tracker/st_framebuffer.c | 18 +++--- 8 files changed, 77 insertions(+), 60 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2992e2f3b3..5546796936 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -276,7 +276,7 @@ struct pipe_surface unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; - unsigned usage; /**< PIPE_BUFFER_USAGE_* */ + unsigned usage; /**< PIPE_BUFFER_USAGE_* */ struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ @@ -311,7 +311,9 @@ struct pipe_texture unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; - + + unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */ + unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ /* These are also refcounted: diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 89de188ada..cfecebdb8c 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -483,11 +483,13 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, uint8_t depth_bits_array[3]; uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; depth_bits_array[0] = 0; depth_bits_array[1] = depth_bits; depth_bits_array[2] = depth_bits; + msaa_samples_array[0] = 0; /* Just like with the accumulation buffer, always provide some modes * with a stencil buffer. It will be a sw fallback, but some apps won't @@ -521,7 +523,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; @@ -529,7 +531,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 94db319928..3cf2146dce 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -521,6 +521,9 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, * \c GLX_SWAP_UNDEFINED_OML. See the * GLX_OML_swap_method extension spec for more details. * \param num_db_modes Number of entries in \c db_modes. + * \param msaa_samples Array of msaa sample count. 0 represents a visual + * without a multisample buffer. + * \param num_msaa_modes Number of entries in \c msaa_samples. * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or * \c GLX_DIRECT_COLOR. * @@ -542,6 +545,7 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, const GLenum * db_modes, unsigned num_db_modes, + const u_int8_t * msaa_samples, unsigned num_msaa_modes, int visType ) { static const uint8_t bits_table[3][4] = { @@ -607,9 +611,7 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, const uint32_t * masks; const int index = fb_type & 0x07; __GLcontextModes * modes = *ptr_to_modes; - unsigned i; - unsigned j; - unsigned k; + unsigned i, j, k, h; if ( bytes_per_pixel[ index ] == 0 ) { @@ -659,49 +661,54 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { for ( i = 0 ; i < num_db_modes ; i++ ) { - for ( j = 0 ; j < 2 ; j++ ) { - - modes->redBits = bits[0]; - modes->greenBits = bits[1]; - modes->blueBits = bits[2]; - modes->alphaBits = bits[3]; - modes->redMask = masks[0]; - modes->greenMask = masks[1]; - modes->blueMask = masks[2]; - modes->alphaMask = masks[3]; - modes->rgbBits = modes->redBits + modes->greenBits - + modes->blueBits + modes->alphaBits; - - modes->accumRedBits = 16 * j; - modes->accumGreenBits = 16 * j; - modes->accumBlueBits = 16 * j; - modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; - modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; - - modes->stencilBits = stencil_bits[k]; - modes->depthBits = depth_bits[k]; - - modes->visualType = visType; - modes->renderType = GLX_RGBA_BIT; - modes->drawableType = GLX_WINDOW_BIT; - modes->rgbMode = GL_TRUE; - - if ( db_modes[i] == GLX_NONE ) { - modes->doubleBufferMode = GL_FALSE; + for ( h = 0 ; h < num_msaa_modes; h++ ) { + for ( j = 0 ; j < 2 ; j++ ) { + + modes->redBits = bits[0]; + modes->greenBits = bits[1]; + modes->blueBits = bits[2]; + modes->alphaBits = bits[3]; + modes->redMask = masks[0]; + modes->greenMask = masks[1]; + modes->blueMask = masks[2]; + modes->alphaMask = masks[3]; + modes->rgbBits = modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits; + + modes->accumRedBits = 16 * j; + modes->accumGreenBits = 16 * j; + modes->accumBlueBits = 16 * j; + modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; + modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; + + modes->stencilBits = stencil_bits[k]; + modes->depthBits = depth_bits[k]; + + modes->visualType = visType; + modes->renderType = GLX_RGBA_BIT; + modes->drawableType = GLX_WINDOW_BIT; + modes->rgbMode = GL_TRUE; + + if ( db_modes[i] == GLX_NONE ) { + modes->doubleBufferMode = GL_FALSE; + } + else { + modes->doubleBufferMode = GL_TRUE; + modes->swapMethod = db_modes[i]; + } + + modes->samples = msaa_samples[h]; + modes->sampleBuffers = modes->samples ? 1 : 0; + + modes->haveAccumBuffer = ((modes->accumRedBits + + modes->accumGreenBits + + modes->accumBlueBits + + modes->accumAlphaBits) > 0); + modes->haveDepthBuffer = (modes->depthBits > 0); + modes->haveStencilBuffer = (modes->stencilBits > 0); + + modes = modes->next; } - else { - modes->doubleBufferMode = GL_TRUE; - modes->swapMethod = db_modes[i]; - } - - modes->haveAccumBuffer = ((modes->accumRedBits + - modes->accumGreenBits + - modes->accumBlueBits + - modes->accumAlphaBits) > 0); - modes->haveDepthBuffer = (modes->depthBits > 0); - modes->haveStencilBuffer = (modes->stencilBits > 0); - - modes = modes->next; } } } diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h index 1067d0a8bf..20940c21b4 100644 --- a/src/mesa/drivers/dri/common/utils.h +++ b/src/mesa/drivers/dri/common/utils.h @@ -115,6 +115,7 @@ extern GLboolean driFillInModes( __GLcontextModes ** modes, GLenum fb_format, GLenum fb_type, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes, int visType ); + const GLenum * db_modes, unsigned num_db_modes, + const u_int8_t * msaa_samples, unsigned num_msaa_modes, int visType ); #endif /* DRI_DEBUG_H */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index dceb7611f2..0a065541e1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2269,6 +2269,7 @@ struct gl_renderbuffer GLubyte IndexBits; GLubyte DepthBits; GLubyte StencilBits; + GLubyte Samples; /**< Number of samples - 0 if not multisampled */ GLvoid *Data; /**< This may not be used by some kinds of RBs */ /* Used to wrap one renderbuffer around another: */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1067caf9b3..7245798d0d 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -118,6 +118,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, template.height[0] = height; template.depth[0] = 1; template.last_level = 0; + template.nr_samples = rb->Samples; if (pf_is_depth_stencil(template.format)) { template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; @@ -249,7 +250,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) * renderbuffer). The window system code determines the format. */ struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format) +st_new_renderbuffer_fb(enum pipe_format format, int samples) { struct st_renderbuffer *strb; @@ -261,6 +262,7 @@ st_new_renderbuffer_fb(enum pipe_format format) _mesa_init_renderbuffer(&strb->Base, 0); strb->Base.ClassID = 0x4242; /* just a unique value */ + strb->Base.Samples = samples; strb->format = format; switch (format) { diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 87b0734a0c..ff56001a4e 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -58,7 +58,7 @@ st_renderbuffer(struct gl_renderbuffer *rb) extern struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format); +st_new_renderbuffer_fb(enum pipe_format format, int samples); extern void st_init_fbo_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 1b6e68c2a1..1994a1c826 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -51,27 +51,29 @@ st_create_framebuffer( const __GLcontextModes *visual, { struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { + int samples = 0; _mesa_initialize_framebuffer(&stfb->Base, visual); + if (visual->sampleBuffers) samples = visual->samples; { /* fake frontbuffer */ /* XXX allocation should only happen in the unusual case it's actually needed */ struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat); + = st_new_renderbuffer_fb(colorFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (visual->doubleBufferMode) { struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat); + = st_new_renderbuffer_fb(colorFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } if (visual->depthBits == 24 && visual->stencilBits == 8) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); @@ -82,26 +84,26 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->depthBits == 32) { /* 32-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits == 24) { /* 24-bit depth buffer, ignore stencil bits */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits > 0) { /* 16-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } if (visual->stencilBits > 0) { /* 8-bit stencil */ struct gl_renderbuffer *stencilRb - = st_new_renderbuffer_fb(stencilFormat); + = st_new_renderbuffer_fb(stencilFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); } } @@ -109,7 +111,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->accumRedBits > 0) { /* 16-bit/channel accum */ struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT); + = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); } -- cgit v1.2.3 From 489fc4d10a57538de59a89e19ce752e4b7253d22 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 2 Jul 2008 20:08:27 +0200 Subject: mesa: fix issues around multisample enable multisample enable is enabled by default, however gl mandates multisample rendering rules only apply if there's also a multisampled buffer. --- src/mesa/drivers/dri/r300/r300_render.c | 2 +- src/mesa/main/mtypes.h | 1 + src/mesa/main/multisample.c | 2 +- src/mesa/main/state.c | 17 +++++++++++++++++ src/mesa/state_tracker/st_atom_rasterizer.c | 2 +- src/mesa/swrast/s_points.c | 2 +- 6 files changed, 22 insertions(+), 4 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index eee1e803a0..c809679e6c 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -359,7 +359,7 @@ static int r300Fallback(GLcontext * ctx) if (!r300->disable_lowimpact_fallback) { FALLBACK_IF(ctx->Polygon.StippleFlag); - FALLBACK_IF(ctx->Multisample.Enabled); + FALLBACK_IF(ctx->Multisample._Enabled); FALLBACK_IF(ctx->Line.StippleFlag); FALLBACK_IF(ctx->Line.SmoothFlag); FALLBACK_IF(ctx->Point.SmoothFlag); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 0a065541e1..00e7d5d395 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -961,6 +961,7 @@ struct gl_list_extensions struct gl_multisample_attrib { GLboolean Enabled; + GLboolean _Enabled; /**< true if Enabled and multisample buffer */ GLboolean SampleAlphaToCoverage; GLboolean SampleAlphaToOne; GLboolean SampleCoverage; diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c index e138087436..b9cfad9216 100644 --- a/src/mesa/main/multisample.c +++ b/src/mesa/main/multisample.c @@ -57,7 +57,7 @@ _mesa_SampleCoverageARB(GLclampf value, GLboolean invert) void _mesa_init_multisample(GLcontext *ctx) { - ctx->Multisample.Enabled = GL_FALSE; + ctx->Multisample.Enabled = GL_TRUE; ctx->Multisample.SampleAlphaToCoverage = GL_FALSE; ctx->Multisample.SampleAlphaToOne = GL_FALSE; ctx->Multisample.SampleCoverage = GL_FALSE; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 315253d90a..344af91e17 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -288,6 +288,20 @@ update_viewport_matrix(GLcontext *ctx) } +/** + * Update derived multisample state. + */ +static void +update_multisample(GLcontext *ctx) +{ + ctx->Multisample._Enabled = GL_FALSE; + if (ctx->DrawBuffer) { + if (ctx->DrawBuffer->Visual.sampleBuffers) + ctx->Multisample._Enabled = GL_TRUE; + } +} + + /** * Update derived color/blend/logicop state. */ @@ -425,6 +439,9 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) update_viewport_matrix(ctx); + if (new_state & _NEW_MULTISAMPLE) + update_multisample( ctx ); + if (new_state & _NEW_COLOR) update_color( ctx ); diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 87a91d56d0..ff40bb4312 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -254,7 +254,7 @@ static void update_raster_state( struct st_context *st ) raster->line_stipple_factor = ctx->Line.StippleFactor - 1; /* _NEW_MULTISAMPLE */ - if (ctx->Multisample.Enabled) + if (ctx->Multisample._Enabled) raster->multisample = 1; /* _NEW_SCISSOR */ diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index c0f32e9c91..f4b3650210 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -250,7 +250,7 @@ smooth_point(GLcontext *ctx, const SWvertex *vert) size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA); /* alpha attenuation / fade factor */ - if (ctx->Multisample.Enabled) { + if (ctx->Multisample._Enabled) { if (vert->pointSize >= ctx->Point.Threshold) { alphaAtten = 1.0F; } -- cgit v1.2.3 From 2fa7b3f78639114aec42fcbbfc29d3645832708b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Jul 2008 10:29:15 -0600 Subject: mesa: Implement mutex/locking around texture object reference counting. Use new _mesa_reference_texobj() function for referencing/unreferencing textures. Add new assertions/tests to try to detect invalid usage of deleted textures. cherry-picked from master (9e01b915f1243a3f551cb795b7124bd1e52ca15f) --- src/mesa/main/attrib.c | 1 + src/mesa/main/context.c | 14 +-- src/mesa/main/fbobject.c | 17 ++- src/mesa/main/framebuffer.c | 13 +-- src/mesa/main/mtypes.h | 1 + src/mesa/main/texobj.c | 253 ++++++++++++++++++++++---------------------- src/mesa/main/texobj.h | 4 + src/mesa/main/texstate.c | 104 ++++++++---------- 8 files changed, 194 insertions(+), 213 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 2e6bb76586..b990369a9e 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -361,6 +361,7 @@ _mesa_PushAttrib(GLbitfield mask) ctx->Texture.Unit[u].Current1DArray->RefCount++; ctx->Texture.Unit[u].Current2DArray->RefCount++; } + attr = MALLOC_STRUCT( gl_texture_attrib ); MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); /* copy state of the currently bound texture objects */ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 33f6d2c0d0..279880cf40 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -500,19 +500,12 @@ alloc_shared_state( GLcontext *ctx ) if (!ss->Default2DArray) goto cleanup; - /* Effectively bind the default textures to all texture units */ - ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default1DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS; + /* sanity check */ + assert(ss->Default1D->RefCount == 1); _glthread_INIT_MUTEX(ss->TexMutex); ss->TextureStateStamp = 0; - #if FEATURE_EXT_framebuffer_object ss->FrameBuffers = _mesa_NewHashTable(); if (!ss->FrameBuffers) @@ -522,10 +515,9 @@ alloc_shared_state( GLcontext *ctx ) goto cleanup; #endif - return GL_TRUE; - cleanup: +cleanup: /* Ran out of memory at some point. Free everything and return NULL */ if (ss->DisplayList) _mesa_DeleteHashTable(ss->DisplayList); diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 56a3131016..0ae69bdce7 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -172,17 +172,12 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) { if (att->Type == GL_TEXTURE) { ASSERT(att->Texture); - att->Texture->RefCount--; - if (att->Texture->RefCount == 0) { - ctx->Driver.DeleteTexture(ctx, att->Texture); - } - else { + if (ctx->Driver.FinishRenderTexture) { /* tell driver that we're done rendering to this texture. */ - if (ctx->Driver.FinishRenderTexture) { - ctx->Driver.FinishRenderTexture(ctx, att); - } + ctx->Driver.FinishRenderTexture(ctx, att); } - att->Texture = NULL; + _mesa_reference_texobj(&att->Texture, NULL); /* unbind */ + ASSERT(!att->Texture); } if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) { ASSERT(!att->Texture); @@ -213,8 +208,8 @@ _mesa_set_texture_attachment(GLcontext *ctx, /* new attachment */ _mesa_remove_attachment(ctx, att); att->Type = GL_TEXTURE; - att->Texture = texObj; - texObj->RefCount++; + assert(!att->Texture); + _mesa_reference_texobj(&att->Texture, texObj); } /* always update these fields */ diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 96f1b30c9b..dab449fc09 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -38,6 +38,7 @@ #include "fbobject.h" #include "framebuffer.h" #include "renderbuffer.h" +#include "texobj.h" @@ -192,17 +193,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); } if (att->Texture) { - /* render to texture */ - att->Texture->RefCount--; - if (att->Texture->RefCount == 0) { - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - ctx->Driver.DeleteTexture(ctx, att->Texture); - } - } + _mesa_reference_texobj(&att->Texture, NULL); } + ASSERT(!att->Renderbuffer); + ASSERT(!att->Texture); att->Type = GL_NONE; - att->Texture = NULL; } /* unbind _Depth/_StencilBuffer to decr ref counts */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 00e7d5d395..a38ec02852 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1404,6 +1404,7 @@ struct gl_texture_image */ struct gl_texture_object { + _glthread_Mutex Mutex; /**< for thread safety */ GLint RefCount; /**< reference count */ GLuint Name; /**< the user-visible texture object ID */ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 606e62d7a0..b77a00dd15 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -108,6 +108,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, _mesa_bzero(obj, sizeof(*obj)); /* init the non-zero fields */ + _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Target = target; @@ -155,6 +156,11 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) (void) ctx; + /* Set Target to an invalid value. With some assertions elsewhere + * we can try to detect possible use of deleted textures. + */ + texObj->Target = 0x99; + #if FEATURE_colortable _mesa_free_colortable_data(&texObj->Palette); #endif @@ -168,6 +174,9 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) } } + /* destroy the mutex -- it may have allocated memory (eg on bsd) */ + _glthread_DESTROY_MUTEX(texObj->Mutex); + /* free this object */ _mesa_free(texObj); } @@ -186,6 +195,7 @@ void _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ) { + dest->Target = src->Target; dest->Name = src->Name; dest->Priority = src->Priority; dest->BorderColor[0] = src->BorderColor[0]; @@ -217,6 +227,94 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, } +/** + * Check if the given texture object is valid by examining its Target field. + * For debugging only. + */ +static GLboolean +valid_texture_object(const struct gl_texture_object *tex) +{ + switch (tex->Target) { + case 0: + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: + return GL_TRUE; + case 0x99: + _mesa_problem(NULL, "invalid reference to a deleted texture object"); + return GL_FALSE; + default: + _mesa_problem(NULL, "invalid texture object Target value"); + return GL_FALSE; + } +} + + +/** + * Reference (or unreference) a texture object. + * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero). + * If 'tex' is non-null, increment its refcount. + */ +void +_mesa_reference_texobj(struct gl_texture_object **ptr, + struct gl_texture_object *tex) +{ + assert(ptr); + if (*ptr == tex) { + /* no change */ + return; + } + + if (*ptr) { + /* Unreference the old texture */ + GLboolean deleteFlag = GL_FALSE; + struct gl_texture_object *oldTex = *ptr; + + assert(valid_texture_object(oldTex)); + + _glthread_LOCK_MUTEX(oldTex->Mutex); + ASSERT(oldTex->RefCount > 0); + oldTex->RefCount--; + + deleteFlag = (oldTex->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldTex->Mutex); + + if (deleteFlag) { + GET_CURRENT_CONTEXT(ctx); + if (ctx) + ctx->Driver.DeleteTexture(ctx, oldTex); + else + _mesa_problem(NULL, "Unable to delete texture, no context"); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (tex) { + /* reference new texture */ + assert(valid_texture_object(tex)); + _glthread_LOCK_MUTEX(tex->Mutex); + if (tex->RefCount == 0) { + /* this texture's being deleted (look just above) */ + /* Not sure this can every really happen. Warn if it does. */ + _mesa_problem(NULL, "referencing deleted texture object"); + *ptr = NULL; + } + else { + tex->RefCount++; + *ptr = tex; + } + _glthread_UNLOCK_MUTEX(tex->Mutex); + } +} + + + /** * Report why a texture object is incomplete. * @@ -613,8 +711,7 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj) /** * Check if the given texture object is bound to any texture image units and - * unbind it if so. - * XXX all RefCount accesses should be protected by a mutex. + * unbind it if so (revert to default textures). */ static void unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj) @@ -623,42 +720,26 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj) for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; - struct gl_texture_object **curr = NULL; - if (texObj == unit->Current1D) { - curr = &unit->Current1D; - unit->Current1D = ctx->Shared->Default1D; + _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D); } else if (texObj == unit->Current2D) { - curr = &unit->Current2D; - unit->Current2D = ctx->Shared->Default2D; + _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D); } else if (texObj == unit->Current3D) { - curr = &unit->Current3D; - unit->Current3D = ctx->Shared->Default3D; + _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D); } else if (texObj == unit->CurrentCubeMap) { - curr = &unit->CurrentCubeMap; - unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; + _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); } else if (texObj == unit->CurrentRect) { - curr = &unit->CurrentRect; - unit->CurrentRect = ctx->Shared->DefaultRect; + _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect); } else if (texObj == unit->Current1DArray) { - curr = &unit->Current1DArray; - unit->CurrentRect = ctx->Shared->Default1DArray; + _mesa_reference_texobj(&unit->Current1DArray, ctx->Shared->Default1DArray); } else if (texObj == unit->Current2DArray) { - curr = &unit->Current1DArray; - unit->CurrentRect = ctx->Shared->Default2DArray; - } - - if (curr) { - (*curr)->RefCount++; - texObj->RefCount--; - if (texObj == unit->_Current) - unit->_Current = *curr; + _mesa_reference_texobj(&unit->Current2DArray, ctx->Shared->Default2DArray); } } } @@ -694,8 +775,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { - GLboolean deleted; - _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. @@ -705,10 +784,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) unbind_texobj_from_fbo(ctx, delObj); /* Check if this texture is currently bound to any texture units. - * If so, unbind it and decrement the reference count. + * If so, unbind it. */ unbind_texobj_from_texunits(ctx, delObj); + _mesa_unlock_texture(ctx, delObj); + ctx->NewState |= _NEW_TEXTURE; /* The texture _name_ is now free for re-use. @@ -718,23 +799,10 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - /* The actual texture object will not be freed until it's no - * longer bound in any context. - * XXX all RefCount accesses should be protected by a mutex. + /* Unreference the texobj. If refcount hits zero, the texture + * will be deleted. */ - delObj->RefCount--; - deleted = (delObj->RefCount == 0); - _mesa_unlock_texture(ctx, delObj); - - /* We know that refcount went to zero above, so this is - * the only pointer left to delObj, so we don't have to - * worry about locking any more: - */ - if (deleted) { - ASSERT(delObj->Name != 0); /* Never delete default tex objs */ - ASSERT(ctx->Driver.DeleteTexture); - (*ctx->Driver.DeleteTexture)(ctx, delObj); - } + _mesa_reference_texobj(&delObj, NULL); } } } @@ -762,7 +830,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *oldTexObj; struct gl_texture_object *newTexObj = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -770,62 +837,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) _mesa_debug(ctx, "glBindTexture %s %d\n", _mesa_lookup_enum_by_nr(target), (GLint) texName); - /* - * Get pointer to currently bound texture object (oldTexObj) - */ - switch (target) { - case GL_TEXTURE_1D: - oldTexObj = texUnit->Current1D; - break; - case GL_TEXTURE_2D: - oldTexObj = texUnit->Current2D; - break; - case GL_TEXTURE_3D: - oldTexObj = texUnit->Current3D; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->CurrentCubeMap; - break; - case GL_TEXTURE_RECTANGLE_NV: - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->CurrentRect; - break; - case GL_TEXTURE_1D_ARRAY_EXT: - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->Current1DArray; - break; - case GL_TEXTURE_2D_ARRAY_EXT: - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->Current2DArray; - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - - if (oldTexObj->Name == texName) { - /* XXX this might be wrong. If the texobj is in use by another - * context and a texobj parameter was changed, this might be our - * only chance to update this context's hardware state. - * Note that some applications re-bind the same texture a lot so we - * want to handle that case quickly. - */ - return; /* rebinding the same texture- no change */ - } - /* * Get pointer to new texture object (newTexObj) */ @@ -854,7 +865,8 @@ _mesa_BindTexture( GLenum target, GLuint texName ) newTexObj = ctx->Shared->Default2DArray; break; default: - ; /* Bad targets are caught above */ + _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)"); + return; } } else { @@ -900,28 +912,30 @@ _mesa_BindTexture( GLenum target, GLuint texName ) newTexObj->Target = target; } - /* XXX all RefCount accesses should be protected by a mutex. */ - newTexObj->RefCount++; + assert(valid_texture_object(newTexObj)); - /* do the actual binding, but first flush outstanding vertices: - */ + /* flush before changing binding */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* Do the actual binding. The refcount on the previously bound + * texture object will be decremented. It'll be deleted if the + * count hits zero. + */ switch (target) { case GL_TEXTURE_1D: - texUnit->Current1D = newTexObj; + _mesa_reference_texobj(&texUnit->Current1D, newTexObj); break; case GL_TEXTURE_2D: - texUnit->Current2D = newTexObj; + _mesa_reference_texobj(&texUnit->Current2D, newTexObj); break; case GL_TEXTURE_3D: - texUnit->Current3D = newTexObj; + _mesa_reference_texobj(&texUnit->Current3D, newTexObj); break; case GL_TEXTURE_CUBE_MAP_ARB: - texUnit->CurrentCubeMap = newTexObj; + _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj); break; case GL_TEXTURE_RECTANGLE_NV: - texUnit->CurrentRect = newTexObj; + _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj); break; case GL_TEXTURE_1D_ARRAY_EXT: texUnit->Current1DArray = newTexObj; @@ -930,6 +944,7 @@ _mesa_BindTexture( GLenum target, GLuint texName ) texUnit->Current2DArray = newTexObj; break; default: + /* Bad target should be caught above */ _mesa_problem(ctx, "bad target in BindTexture"); return; } @@ -937,18 +952,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) /* Pass BindTexture call to device driver */ if (ctx->Driver.BindTexture) (*ctx->Driver.BindTexture)( ctx, target, newTexObj ); - - /* Decrement the reference count on the old texture and check if it's - * time to delete it. - */ - /* XXX all RefCount accesses should be protected by a mutex. */ - oldTexObj->RefCount--; - ASSERT(oldTexObj->RefCount >= 0); - if (oldTexObj->RefCount == 0) { - ASSERT(oldTexObj->Name != 0); - ASSERT(ctx->Driver.DeleteTexture); - (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); - } } diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index 2a2bde3601..d5374c5d6c 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -57,6 +57,10 @@ extern void _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ); +extern void +_mesa_reference_texobj(struct gl_texture_object **ptr, + struct gl_texture_object *tex); + extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 421f912849..3bdb55257f 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -62,31 +62,6 @@ static const struct gl_tex_env_combine_state default_combine_state = { }; -/** - * Copy a texture binding. Helper used by _mesa_copy_texture_state(). - */ -static void -copy_texture_binding(const GLcontext *ctx, - struct gl_texture_object **dst, - struct gl_texture_object *src) -{ - /* only copy if names differ (per OpenGL SI) */ - if ((*dst)->Name != src->Name) { - /* unbind/delete dest binding which we're changing */ - (*dst)->RefCount--; - if ((*dst)->RefCount == 0) { - /* time to delete this texture object */ - ASSERT((*dst)->Name != 0); - ASSERT(ctx->Driver.DeleteTexture); - /* XXX cast-away const, unfortunately */ - (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst); - } - /* make new binding, incrementing ref count */ - *dst = src; - src->RefCount++; - } -} - /** * Used by glXCopyContext to copy texture state from one context to another. @@ -143,20 +118,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) /* copy texture object bindings, not contents of texture objects */ _mesa_lock_context_textures(dst); - copy_texture_binding(src, &dst->Texture.Unit[i].Current1D, - src->Texture.Unit[i].Current1D); - copy_texture_binding(src, &dst->Texture.Unit[i].Current2D, - src->Texture.Unit[i].Current2D); - copy_texture_binding(src, &dst->Texture.Unit[i].Current3D, - src->Texture.Unit[i].Current3D); - copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap, - src->Texture.Unit[i].CurrentCubeMap); - copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect, - src->Texture.Unit[i].CurrentRect); - copy_texture_binding(src, &dst->Texture.Unit[i].Current1DArray, - src->Texture.Unit[i].Current1DArray); - copy_texture_binding(src, &dst->Texture.Unit[i].Current2DArray, - src->Texture.Unit[i].Current2DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D, + src->Texture.Unit[i].Current1D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D, + src->Texture.Unit[i].Current2D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D, + src->Texture.Unit[i].Current3D); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap, + src->Texture.Unit[i].CurrentCubeMap); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect, + src->Texture.Unit[i].CurrentRect); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray, + src->Texture.Unit[i].Current1DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray, + src->Texture.Unit[i].Current2DArray); _mesa_unlock_context_textures(dst); } @@ -727,6 +702,8 @@ alloc_proxy_textures( GLcontext *ctx ) if (!ctx->Texture.Proxy2DArray) goto cleanup; + assert(ctx->Texture.Proxy1D->RefCount == 1); + return GL_TRUE; cleanup: @@ -786,13 +763,14 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 ); ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 ); - texUnit->Current1D = ctx->Shared->Default1D; - texUnit->Current2D = ctx->Shared->Default2D; - texUnit->Current3D = ctx->Shared->Default3D; - texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; - texUnit->CurrentRect = ctx->Shared->DefaultRect; - texUnit->Current1DArray = ctx->Shared->Default1DArray; - texUnit->Current2DArray = ctx->Shared->Default2DArray; + /* initialize current texture object ptrs to the shared default objects */ + _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D); + _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D); + _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D); + _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); + _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect); + _mesa_reference_texobj(&texUnit->Current1DArray, ctx->Shared->Default1DArray); + _mesa_reference_texobj(&texUnit->Current2DArray, ctx->Shared->Default2DArray); } @@ -807,25 +785,22 @@ _mesa_init_texture(GLcontext *ctx) assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); - /* Effectively bind the default textures to all texture units */ - ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default1DArray->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default2DArray->RefCount += MAX_TEXTURE_UNITS; - /* Texture group */ ctx->Texture.CurrentUnit = 0; /* multitexture */ ctx->Texture._EnabledUnits = 0; - for (i=0; iTexture.SharedPalette = GL_FALSE; #if FEATURE_colortable _mesa_init_colortable(&ctx->Texture.Palette); #endif + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + init_texture_unit( ctx, i ); + + /* After we're done initializing the context's texture state the default + * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1. + */ + assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1); + /* Allocate proxy textures */ if (!alloc_proxy_textures( ctx )) return GL_FALSE; @@ -840,6 +815,20 @@ _mesa_init_texture(GLcontext *ctx) void _mesa_free_texture_data(GLcontext *ctx) { + GLuint u; + + /* unreference current textures */ + for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { + struct gl_texture_unit *unit = ctx->Texture.Unit + u; + _mesa_reference_texobj(&unit->Current1D, NULL); + _mesa_reference_texobj(&unit->Current2D, NULL); + _mesa_reference_texobj(&unit->Current3D, NULL); + _mesa_reference_texobj(&unit->CurrentCubeMap, NULL); + _mesa_reference_texobj(&unit->CurrentRect, NULL); + _mesa_reference_texobj(&unit->Current1DArray, NULL); + _mesa_reference_texobj(&unit->Current2DArray, NULL); + } + /* Free proxy texture objects */ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D ); @@ -849,6 +838,7 @@ _mesa_free_texture_data(GLcontext *ctx) (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray ); (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray ); + #if FEATURE_colortable { GLuint i; -- cgit v1.2.3 From 0bc2409e3808df54bf7d228475320e2ec4fe80a1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Jul 2008 10:37:07 -0600 Subject: mesa: Replace Proxy1D/2D/etc with ProxyTex[] indexed by TEXTURE_x_INDEX. Simplification in colortab.c too. cherry-picked from master (fe469007037d9d5cdbe1677d8ff7368b276e9e7c) --- src/mesa/drivers/dri/tdfx/tdfx_tex.c | 2 +- src/mesa/main/colortab.c | 306 +++++++++++------------------------ src/mesa/main/mtypes.h | 4 + src/mesa/main/teximage.c | 58 +++---- src/mesa/main/texstate.c | 81 ++++------ 5 files changed, 154 insertions(+), 297 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index 65e665ee39..70ef726437 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -1821,7 +1821,7 @@ tdfxTestProxyTexImage(GLcontext *ctx, GLenum target, tdfxTexInfo *ti; int memNeeded; - tObj = ctx->Texture.Proxy2D; + tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; if (!tObj->DriverData) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = TDFX_TEXTURE_DATA(tObj); diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c index 610acba306..97120398f9 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -30,6 +30,7 @@ #include "image.h" #include "macros.h" #include "state.h" +#include "teximage.h" /** @@ -305,49 +306,6 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ switch (target) { - case GL_TEXTURE_1D: - texObj = texUnit->Current1D; - table = &texObj->Palette; - break; - case GL_TEXTURE_2D: - texObj = texUnit->Current2D; - table = &texObj->Palette; - break; - case GL_TEXTURE_3D: - texObj = texUnit->Current3D; - table = &texObj->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; - } - texObj = texUnit->CurrentCubeMap; - table = &texObj->Palette; - break; - case GL_PROXY_TEXTURE_1D: - texObj = ctx->Texture.Proxy1D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_2D: - texObj = ctx->Texture.Proxy2D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_3D: - texObj = ctx->Texture.Proxy3D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; - } - texObj = ctx->Texture.ProxyCubeMap; - table = &texObj->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -396,8 +354,19 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, proxy = GL_TRUE; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + proxy = _mesa_is_proxy_texture(target); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); + return; + } + } } assert(table); @@ -499,26 +468,6 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { - case GL_TEXTURE_1D: - texObj = texUnit->Current1D; - table = &texObj->Palette; - break; - case GL_TEXTURE_2D: - texObj = texUnit->Current2D; - table = &texObj->Palette; - break; - case GL_TEXTURE_3D: - texObj = texUnit->Current3D; - table = &texObj->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); - return; - } - texObj = texUnit->CurrentCubeMap; - table = &texObj->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -547,8 +496,15 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); - return; + /* try texture targets */ + texObj = _mesa_select_tex_object(ctx, texUnit, target); + if (texObj && !_mesa_is_proxy_texture(target)) { + table = &texObj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); + return; + } } assert(table); @@ -636,22 +592,6 @@ _mesa_GetColorTable( GLenum target, GLenum format, } switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -672,8 +612,18 @@ _mesa_GetColorTable( GLenum target, GLenum format, table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj && !_mesa_is_proxy_texture(target)) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); + return; + } + } } ASSERT(table); @@ -781,65 +731,41 @@ _mesa_GetColorTable( GLenum target, GLenum format, void GLAPIENTRY _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) { + GLfloat *scale, *bias; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { - case GL_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_TEXTURE_COLOR_TABLE_SGI: - if (!ctx->Extensions.SGI_texture_color_table) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); - return; - } - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.TextureColorTableScale, params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.TextureColorTableBias, params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); - return; + case GL_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; + break; + case GL_TEXTURE_COLOR_TABLE_SGI: + scale = ctx->Pixel.TextureColorTableScale; + bias = ctx->Pixel.TextureColorTableBias; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); + return; + } + + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + COPY_4V(scale, params); + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + COPY_4V(bias, params); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); + return; } ctx->NewState |= _NEW_PIXEL; @@ -879,40 +805,6 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameterfv(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; - case GL_PROXY_TEXTURE_1D: - table = &ctx->Texture.Proxy1D->Palette; - break; - case GL_PROXY_TEXTURE_2D: - table = &ctx->Texture.Proxy2D->Palette; - break; - case GL_PROXY_TEXTURE_3D: - table = &ctx->Texture.Proxy3D->Palette; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameterfv(target)"); - return; - } - table = &ctx->Texture.ProxyCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -981,8 +873,19 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetColorTableParameterfv(target)"); + return; + } + } } assert(table); @@ -1029,40 +932,6 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameteriv(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; - case GL_PROXY_TEXTURE_1D: - table = &ctx->Texture.Proxy1D->Palette; - break; - case GL_PROXY_TEXTURE_2D: - table = &ctx->Texture.Proxy2D->Palette; - break; - case GL_PROXY_TEXTURE_3D: - table = &ctx->Texture.Proxy3D->Palette; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameteriv(target)"); - return; - } - table = &ctx->Texture.ProxyCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -1161,8 +1030,19 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); - return; + /* Try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetColorTableParameteriv(target)"); + return; + } + } } assert(table); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index a38ec02852..2d6be1983c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1579,6 +1579,7 @@ struct gl_texture_attrib struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; +#if 0 struct gl_texture_object *Proxy1D; struct gl_texture_object *Proxy2D; struct gl_texture_object *Proxy3D; @@ -1586,6 +1587,9 @@ struct gl_texture_attrib struct gl_texture_object *ProxyRect; struct gl_texture_object *Proxy1DArray; struct gl_texture_object *Proxy2DArray; +#else + struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; +#endif /** GL_EXT_shared_texture_palette */ GLboolean SharedPalette; diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index eed1937517..36557f19fd 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -767,15 +767,15 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, case GL_TEXTURE_1D: return texUnit->Current1D; case GL_PROXY_TEXTURE_1D: - return ctx->Texture.Proxy1D; + return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; case GL_TEXTURE_2D: return texUnit->Current2D; case GL_PROXY_TEXTURE_2D: - return ctx->Texture.Proxy2D; + return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; case GL_TEXTURE_3D: return texUnit->Current3D; case GL_PROXY_TEXTURE_3D: - return ctx->Texture.Proxy3D; + return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: @@ -787,25 +787,25 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, ? texUnit->CurrentCubeMap : NULL; case GL_PROXY_TEXTURE_CUBE_MAP_ARB: return ctx->Extensions.ARB_texture_cube_map - ? ctx->Texture.ProxyCubeMap : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; case GL_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle ? texUnit->CurrentRect : NULL; case GL_PROXY_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle - ? ctx->Texture.ProxyRect : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; case GL_TEXTURE_1D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array ? texUnit->Current1DArray : NULL; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array - ? ctx->Texture.Proxy1DArray : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; case GL_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array ? texUnit->Current2DArray : NULL; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array - ? ctx->Texture.Proxy2DArray : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; default: _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); return NULL; @@ -932,106 +932,106 @@ _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level) case GL_PROXY_TEXTURE_1D: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy1D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy1D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy1D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_2D: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy2D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy2D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy2D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_3D: if (level >= ctx->Const.Max3DTextureLevels) return NULL; - texImage = ctx->Texture.Proxy3D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy3D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy3D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_CUBE_MAP: if (level >= ctx->Const.MaxCubeTextureLevels) return NULL; - texImage = ctx->Texture.ProxyCubeMap->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.ProxyCubeMap->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.ProxyCubeMap; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]; } return texImage; case GL_PROXY_TEXTURE_RECTANGLE_NV: if (level > 0) return NULL; - texImage = ctx->Texture.ProxyRect->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.ProxyRect->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.ProxyRect; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]; } return texImage; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy1DArray->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy1DArray->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy1DArray; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]; } return texImage; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy2DArray->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy2DArray->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy2DArray; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]; } return texImage; default: @@ -2611,7 +2611,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 1, border)) { /* when error, clear all proxy texture image parameters */ if (texImage) - clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]); + clear_teximage_fields(ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]); } else { /* no error, set the tex image parameters */ diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 3bdb55257f..20f9c4512c 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -674,54 +674,32 @@ _mesa_update_texture( GLcontext *ctx, GLuint new_state ) static GLboolean alloc_proxy_textures( GLcontext *ctx ) { - ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); - if (!ctx->Texture.Proxy1D) - goto cleanup; - - ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D); - if (!ctx->Texture.Proxy2D) - goto cleanup; - - ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D); - if (!ctx->Texture.Proxy3D) - goto cleanup; - - ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB); - if (!ctx->Texture.ProxyCubeMap) - goto cleanup; - - ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV); - if (!ctx->Texture.ProxyRect) - goto cleanup; - - ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT); - if (!ctx->Texture.Proxy1DArray) - goto cleanup; - - ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT); - if (!ctx->Texture.Proxy2DArray) - goto cleanup; - - assert(ctx->Texture.Proxy1D->RefCount == 1); + static const GLenum targets[] = { + GL_TEXTURE_1D, + GL_TEXTURE_2D, + GL_TEXTURE_3D, + GL_TEXTURE_CUBE_MAP_ARB, + GL_TEXTURE_RECTANGLE_NV, + GL_TEXTURE_1D_ARRAY_EXT, + GL_TEXTURE_2D_ARRAY_EXT + }; + GLint tgt; + + ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); + + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + if (!(ctx->Texture.ProxyTex[tgt] + = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) { + /* out of memory, free what we did allocate */ + while (--tgt >= 0) { + ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); + } + return GL_FALSE; + } + } + assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */ return GL_TRUE; - - cleanup: - if (ctx->Texture.Proxy1D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D); - if (ctx->Texture.Proxy2D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D); - if (ctx->Texture.Proxy3D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D); - if (ctx->Texture.ProxyCubeMap) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap); - if (ctx->Texture.ProxyRect) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect); - if (ctx->Texture.Proxy1DArray) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray); - if (ctx->Texture.Proxy2DArray) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray); - return GL_FALSE; } @@ -815,7 +793,7 @@ _mesa_init_texture(GLcontext *ctx) void _mesa_free_texture_data(GLcontext *ctx) { - GLuint u; + GLuint u, tgt; /* unreference current textures */ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { @@ -830,13 +808,8 @@ _mesa_free_texture_data(GLcontext *ctx) } /* Free proxy texture objects */ - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray ); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) + ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); #if FEATURE_colortable -- cgit v1.2.3 From 51654783ef0aa48560f70cd3944128a94a87d86b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 14 Jul 2008 11:20:58 -0600 Subject: mesa: comments about vectors vs components --- src/mesa/main/config.h | 4 ++-- src/mesa/main/mtypes.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 9ff0b708dd..f8109ec755 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -190,8 +190,8 @@ #define MAX_PROGRAM_CALL_DEPTH 8 #define MAX_PROGRAM_TEMPS 128 #define MAX_PROGRAM_ADDRESS_REGS 2 -#define MAX_UNIFORMS 128 -#define MAX_VARYING 8 +#define MAX_UNIFORMS 128 /**< number of float components */ +#define MAX_VARYING 8 /**< number of float[4] vectors */ #define MAX_SAMPLERS 8 /*@}*/ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2d6be1983c..88312da7f0 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2519,7 +2519,7 @@ struct gl_constants GLuint MaxRenderbufferSize; /* GL_ARB_vertex_shader */ GLuint MaxVertexTextureImageUnits; - GLuint MaxVarying; + GLuint MaxVarying; /**< Number of float[4] vectors */ }; -- cgit v1.2.3 From 90a3af7d9d0849afcee0d35ed0621fe24e1008a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Jul 2008 14:56:54 -0600 Subject: mesa: glsl: only try to link shaders defining main() --- src/mesa/main/mtypes.h | 4 +-- src/mesa/shader/shader_api.c | 6 +---- src/mesa/shader/slang/slang_compile.c | 47 ++++++++++++++++------------------- src/mesa/shader/slang/slang_link.c | 11 ++++---- 4 files changed, 31 insertions(+), 37 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 88312da7f0..a95f02b889 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2123,9 +2123,9 @@ struct gl_shader const GLchar *Source; /**< Source code string */ GLboolean CompileStatus; - GLuint NumPrograms; /**< size of Programs[] array */ - struct gl_program **Programs; /**< Post-compile assembly code */ + struct gl_program *Program; /**< Post-compile assembly code */ GLchar *InfoLog; + GLboolean Main; /**< shader defines main() */ }; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index b33dfd6663..e894b7b211 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -262,15 +262,11 @@ _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type) void _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh) { - GLuint i; if (sh->Source) _mesa_free((void *) sh->Source); if (sh->InfoLog) _mesa_free(sh->InfoLog); - for (i = 0; i < sh->NumPrograms; i++) - _mesa_reference_program(ctx, &sh->Programs[i], NULL); - if (sh->Programs) - _mesa_free(sh->Programs); + _mesa_reference_program(ctx, &sh->Program, NULL); _mesa_free(sh); } diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index fd5d4afacb..862d0741ff 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1930,7 +1930,7 @@ parse_invariant(slang_parse_ctx * C, slang_output_ctx * O) static GLboolean parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, - struct gl_program *program) + struct gl_shader *shader) { GET_CURRENT_CONTEXT(ctx); slang_output_ctx o; @@ -1954,7 +1954,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, o.structs = &unit->structs; o.vars = &unit->vars; o.global_pool = &unit->object->varpool; - o.program = program; + o.program = shader ? shader->Program : NULL; o.vartable = _slang_new_var_table(maxRegs); _slang_push_var_table(o.vartable); @@ -2007,6 +2007,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, _slang_codegen_function(&A, mainFunc); + shader->Main = GL_TRUE; /* this shader defines main() */ } _slang_pop_var_table(o.vartable); @@ -2020,7 +2021,7 @@ compile_binary(const byte * prod, slang_code_unit * unit, GLuint version, slang_unit_type type, slang_info_log * infolog, slang_code_unit * builtin, slang_code_unit * downlink, - struct gl_program *program) + struct gl_shader *shader) { slang_parse_ctx C; @@ -2045,14 +2046,14 @@ compile_binary(const byte * prod, slang_code_unit * unit, } /* parse translation unit */ - return parse_code_unit(&C, unit, program); + return parse_code_unit(&C, unit, shader); } static GLboolean compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, slang_unit_type type, slang_info_log * infolog, slang_code_unit * builtin, - struct gl_program *program) + struct gl_shader *shader) { byte *prod; GLuint size, start, version; @@ -2114,7 +2115,7 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, /* Syntax is okay - translate it to internal representation. */ if (!compile_binary(prod, unit, version, type, infolog, builtin, &builtin[SLANG_BUILTIN_TOTAL - 1], - program)) { + shader)) { grammar_alloc_free(prod); return GL_FALSE; } @@ -2153,7 +2154,7 @@ static const byte slang_vertex_builtin_gc[] = { static GLboolean compile_object(grammar * id, const char *source, slang_code_object * object, slang_unit_type type, slang_info_log * infolog, - struct gl_program *program) + struct gl_shader *shader) { slang_code_unit *builtins = NULL; GLuint base_version = 110; @@ -2252,7 +2253,7 @@ compile_object(grammar * id, const char *source, slang_code_object * object, /* compile the actual shader - pass-in built-in library for external shader */ return compile_with_grammar(*id, source, &object->unit, type, infolog, - builtins, program); + builtins, shader); } @@ -2261,7 +2262,6 @@ compile_shader(GLcontext *ctx, slang_code_object * object, slang_unit_type type, slang_info_log * infolog, struct gl_shader *shader) { - struct gl_program *program = shader->Programs[0]; GLboolean success; grammar id = 0; @@ -2271,12 +2271,12 @@ compile_shader(GLcontext *ctx, slang_code_object * object, _mesa_printf("************************************\n"); #endif - assert(program); + assert(shader->Program); _slang_code_object_dtr(object); _slang_code_object_ctr(object); - success = compile_object(&id, shader->Source, object, type, infolog, program); + success = compile_object(&id, shader->Source, object, type, infolog, shader); if (id != 0) grammar_destroy(id); if (!success) @@ -2308,21 +2308,18 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) ctx->Shader.MemPool = _slang_new_mempool(1024*1024); - /* XXX temporary hack */ - if (!shader->Programs) { + shader->Main = GL_FALSE; + + if (!shader->Program) { GLenum progTarget; if (shader->Type == GL_VERTEX_SHADER) progTarget = GL_VERTEX_PROGRAM_ARB; else progTarget = GL_FRAGMENT_PROGRAM_ARB; - shader->Programs - = (struct gl_program **) malloc(sizeof(struct gl_program*)); - shader->Programs[0] = ctx->Driver.NewProgram(ctx, progTarget, 1); - shader->NumPrograms = 1; - - shader->Programs[0]->Parameters = _mesa_new_parameter_list(); - shader->Programs[0]->Varying = _mesa_new_parameter_list(); - shader->Programs[0]->Attributes = _mesa_new_parameter_list(); + shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1); + shader->Program->Parameters = _mesa_new_parameter_list(); + shader->Program->Varying = _mesa_new_parameter_list(); + shader->Program->Attributes = _mesa_new_parameter_list(); } slang_info_log_construct(&info_log); @@ -2355,13 +2352,13 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) /* remove any reads of varying (output) registers */ #if 0 printf("Pre-remove output reads:\n"); - _mesa_print_program(shader->Programs[0]); + _mesa_print_program(shader->Programs); #endif - _mesa_remove_output_reads(shader->Programs[0], PROGRAM_VARYING); - _mesa_remove_output_reads(shader->Programs[0], PROGRAM_OUTPUT); + _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING); + _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT); #if 0 printf("Post-remove output reads:\n"); - _mesa_print_program(shader->Programs[0]); + _mesa_print_program(shader->Programs); #endif } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index e9b9bbc43f..1de561930a 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -401,15 +401,16 @@ _slang_link(GLcontext *ctx, shProg->Varying = _mesa_new_parameter_list(); /** - * Find attached vertex shader, fragment shader + * Find attached vertex, fragment shaders defining main() */ vertProg = NULL; fragProg = NULL; for (i = 0; i < shProg->NumShaders; i++) { - if (shProg->Shaders[i]->Type == GL_VERTEX_SHADER) - vertProg = vertex_program(shProg->Shaders[i]->Programs[0]); - else if (shProg->Shaders[i]->Type == GL_FRAGMENT_SHADER) - fragProg = fragment_program(shProg->Shaders[i]->Programs[0]); + struct gl_shader *shader = shProg->Shaders[i]; + if (shader->Type == GL_VERTEX_SHADER && shader->Main) + vertProg = vertex_program(shader->Program); + else if (shader->Type == GL_FRAGMENT_SHADER && shader->Main) + fragProg = fragment_program(shader->Program); else _mesa_problem(ctx, "unexpected shader target in slang_link()"); } -- cgit v1.2.3 From c01fbc7866d7cd5cf4263dffec6d9591470b4c23 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 12 Aug 2008 17:41:57 -0600 Subject: mesa: texture crop rect state --- src/mesa/main/glheader.h | 4 ++++ src/mesa/main/mtypes.h | 2 +- src/mesa/main/texparam.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index 3131a356b8..f0f97c218c 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -176,6 +176,10 @@ #endif +#ifndef GL_OES_draw_texture +#define GL_TEXTURE_CROP_RECT_OES 0x8B9D +#endif + #if !defined(CAPI) && defined(WIN32) && !defined(BUILD_FOR_SNAP) #define CAPI _cdecl diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index a95f02b889..71a4ca55bc 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1434,6 +1434,7 @@ struct gl_texture_object GLenum DepthMode; /**< GL_ARB_depth_texture */ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ + GLint CropRect[4]; /**< GL_OES_draw_texture */ GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */ GLboolean _Complete; /**< Is texture object complete? */ @@ -1443,7 +1444,6 @@ struct gl_texture_object /** GL_EXT_paletted_texture */ struct gl_color_table Palette; - /** * \name For device driver. * Note: instead of attaching driver data to this pointer, it's preferable diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index af288c4e18..3f3b448dbc 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -409,6 +409,14 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) } } break; +#ifdef FEATURE_OES_draw_texture + case GL_TEXTURE_CROP_RECT_OES: + texObj->CropRect[0] = (GLint) params[0]; + texObj->CropRect[1] = (GLint) params[1]; + texObj->CropRect[2] = (GLint) params[2]; + texObj->CropRect[3] = (GLint) params[3]; + break; +#endif default: _mesa_error(ctx, GL_INVALID_ENUM, @@ -447,6 +455,12 @@ _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ) fparam[2] = INT_TO_FLOAT(params[2]); fparam[3] = INT_TO_FLOAT(params[3]); } + else if (pname == GL_TEXTURE_CROP_RECT_OES) { + fparam[0] = (GLfloat) params[0]; + fparam[1] = (GLfloat) params[1]; + fparam[2] = (GLfloat) params[2]; + fparam[3] = (GLfloat) params[3]; + } else { if (pname == GL_TEXTURE_PRIORITY) fparam[0] = INT_TO_FLOAT(params[0]); @@ -885,6 +899,14 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) else error = 1; break; +#ifdef FEATURE_OES_draw_texture + case GL_TEXTURE_CROP_RECT_OES: + params[0] = obj->CropRect[0]; + params[0] = obj->CropRect[1]; + params[0] = obj->CropRect[2]; + params[0] = obj->CropRect[3]; + break; +#endif default: error = 1; break; @@ -1027,6 +1049,14 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) return; } break; +#ifdef FEATURE_OES_draw_texture + case GL_TEXTURE_CROP_RECT_OES: + params[0] = obj->CropRect[0]; + params[0] = obj->CropRect[1]; + params[0] = obj->CropRect[2]; + params[0] = obj->CropRect[3]; + break; +#endif default: ; /* silence warnings */ } -- cgit v1.2.3 From e53296c928d80c6627a9551345c160533aa1a19e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 16 Sep 2008 15:50:44 -0600 Subject: mesa: rework GLSL vertex attribute binding Calls to glBindAttribLocation() should not take effect until the next time that glLinkProgram() is called. gl_shader_program::Attributes now just contains user-defined bindings. gl_shader_program::VertexProgram->Attributes contains the actual/final bindings. --- src/mesa/main/mtypes.h | 4 +- src/mesa/shader/shader_api.c | 62 +++++++++-------- src/mesa/shader/slang/slang_link.c | 139 +++++++++++++++++++------------------ src/mesa/shader/slang/slang_link.h | 8 +-- 4 files changed, 110 insertions(+), 103 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 71a4ca55bc..2fc169493b 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2143,12 +2143,14 @@ struct gl_shader_program GLuint NumShaders; /**< number of attached shaders */ struct gl_shader **Shaders; /**< List of attached the shaders */ + /** User-defined attribute bindings (glBindAttribLocation) */ + struct gl_program_parameter_list *Attributes; + /* post-link info: */ struct gl_vertex_program *VertexProgram; /**< Linked vertex program */ struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */ struct gl_uniform_list *Uniforms; struct gl_program_parameter_list *Varying; - struct gl_program_parameter_list *Attributes; /**< Vertex attributes */ GLboolean LinkStatus; /**< GL_LINK_STATUS */ GLboolean Validated; GLchar *InfoLog; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index a86ef56c65..decdec53ed 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.2 * * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. * @@ -497,10 +497,14 @@ _mesa_get_attrib_location(GLcontext *ctx, GLuint program, if (!name) return -1; - if (shProg->Attributes) { - GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name); - if (i >= 0) { - return shProg->Attributes->Parameters[i].StateIndexes[0]; + if (shProg->VertexProgram) { + const struct gl_program_parameter_list *attribs = + shProg->VertexProgram->Base.Attributes; + if (attribs) { + GLint i = _mesa_lookup_parameter_index(attribs, -1, name); + if (i >= 0) { + return attribs->Parameters[i].StateIndexes[0]; + } } } return -1; @@ -513,7 +517,7 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, { struct gl_shader_program *shProg; const GLint size = -1; /* unknown size */ - GLint i, oldIndex; + GLint i; GLenum datatype = GL_FLOAT_VEC4; shProg = _mesa_lookup_shader_program_err(ctx, program, @@ -536,14 +540,6 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, return; } - if (shProg->LinkStatus) { - /* get current index/location for the attribute */ - oldIndex = _mesa_get_attrib_location(ctx, program, name); - } - else { - oldIndex = -1; - } - /* this will replace the current value if it's already in the list */ i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index); if (i < 0) { @@ -551,12 +547,10 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, return; } - if (shProg->VertexProgram && oldIndex >= 0 && oldIndex != index) { - /* If the index changed, need to search/replace references to that attribute - * in the vertex program. - */ - _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index); - } + /* + * Note that this attribute binding won't go into effect until + * glLinkProgram is called again. + */ } @@ -798,24 +792,29 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *nameOut) { + const struct gl_program_parameter_list *attribs = NULL; struct gl_shader_program *shProg; shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; - if (!shProg->Attributes || index >= shProg->Attributes->NumParameters) { + if (shProg->VertexProgram) + attribs = shProg->VertexProgram->Base.Attributes; + + if (!attribs || index >= attribs->NumParameters) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); return; } - copy_string(nameOut, maxLength, length, - shProg->Attributes->Parameters[index].Name); + copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name); + if (size) - *size = shProg->Attributes->Parameters[index].Size - / sizeof_glsl_type(shProg->Attributes->Parameters[index].DataType); + *size = attribs->Parameters[index].Size + / sizeof_glsl_type(attribs->Parameters[index].DataType); + if (type) - *type = shProg->Attributes->Parameters[index].DataType; + *type = attribs->Parameters[index].DataType; } @@ -937,6 +936,7 @@ static void _mesa_get_programiv(GLcontext *ctx, GLuint program, GLenum pname, GLint *params) { + const struct gl_program_parameter_list *attribs; struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); @@ -945,6 +945,11 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program, return; } + if (shProg->VertexProgram) + attribs = shProg->VertexProgram->Base.Attributes; + else + attribs = NULL; + switch (pname) { case GL_DELETE_STATUS: *params = shProg->DeletePending; @@ -962,11 +967,10 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program, *params = shProg->NumShaders; break; case GL_ACTIVE_ATTRIBUTES: - *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0; + *params = attribs ? attribs->NumParameters : 0; break; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = _mesa_longest_parameter_name(shProg->Attributes, - PROGRAM_INPUT) + 1; + *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1; break; case GL_ACTIVE_UNIFORMS: *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0; diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 57dbfc2388..30035b4fee 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.2 * - * Copyright (C) 2007 Brian Paul All Rights Reserved. + * Copyright (C) 2008 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -215,74 +215,110 @@ link_uniform_vars(struct gl_shader_program *shProg, * For example, if the vertex shader declared "attribute vec4 foobar" we'll * allocate a generic vertex attribute for "foobar" and plug that value into * the vertex program instructions. + * But if the user called glBindAttributeLocation(), those bindings will + * have priority. */ static GLboolean _slang_resolve_attributes(struct gl_shader_program *shProg, - struct gl_program *prog) + const struct gl_program *origProg, + struct gl_program *linkedProg) { + GLint attribMap[MAX_VERTEX_ATTRIBS]; GLuint i, j; GLbitfield usedAttributes; - assert(prog->Target == GL_VERTEX_PROGRAM_ARB); + assert(origProg != linkedProg); + assert(origProg->Target == GL_VERTEX_PROGRAM_ARB); + assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB); if (!shProg->Attributes) shProg->Attributes = _mesa_new_parameter_list(); + if (linkedProg->Attributes) { + _mesa_free_parameter_list(linkedProg->Attributes); + } + linkedProg->Attributes = _mesa_new_parameter_list(); + + /* Build a bitmask indicating which attribute indexes have been * explicitly bound by the user with glBindAttributeLocation(). */ usedAttributes = 0x0; for (i = 0; i < shProg->Attributes->NumParameters; i++) { GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0]; - usedAttributes |= attr; + usedAttributes |= (1 << attr); + } + + /* initialize the generic attribute map entries to -1 */ + for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) { + attribMap[i] = -1; } /* * Scan program for generic attribute references */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; + for (i = 0; i < linkedProg->NumInstructions; i++) { + struct prog_instruction *inst = linkedProg->Instructions + i; for (j = 0; j < 3; j++) { if (inst->SrcReg[j].File == PROGRAM_INPUT && inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) { - /* this is a generic attrib */ - const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; - const char *name = prog->Attributes->Parameters[k].Name; - /* See if this attrib name is in the program's attribute list - * (i.e. was bound by the user). + /* + * OK, we've found a generic vertex attribute reference. */ - GLint index = _mesa_lookup_parameter_index(shProg->Attributes, - -1, name); - GLint attr; - if (index >= 0) { - /* found, user must have specified a binding */ - attr = shProg->Attributes->Parameters[index].StateIndexes[0]; - } - else { - /* Not found, choose our own attribute number. - * Start at 1 since generic attribute 0 always aliases - * glVertex/position. + const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; + + GLint attr = attribMap[k]; + + if (attr < 0) { + /* Need to figure out attribute mapping now. + */ + const char *name = origProg->Attributes->Parameters[k].Name; + const GLint size = origProg->Attributes->Parameters[k].Size; + const GLenum type =origProg->Attributes->Parameters[k].DataType; + GLint index, attr; + + /* See if there's a user-defined attribute binding for + * this name. */ - GLint size = prog->Attributes->Parameters[k].Size; - GLenum datatype = prog->Attributes->Parameters[k].DataType; - for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) { - if (((1 << attr) & usedAttributes) == 0) - break; + index = _mesa_lookup_parameter_index(shProg->Attributes, + -1, name); + if (index >= 0) { + /* Found a user-defined binding */ + attr = shProg->Attributes->Parameters[index].StateIndexes[0]; } - if (attr == MAX_VERTEX_ATTRIBS) { - /* too many! XXX record error log */ - return GL_FALSE; + else { + /* No user-defined binding, choose our own attribute number. + * Start at 1 since generic attribute 0 always aliases + * glVertex/position. + */ + for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) { + if (((1 << attr) & usedAttributes) == 0) + break; + } + if (attr == MAX_VERTEX_ATTRIBS) { + link_error(shProg, "Too many vertex attributes"); + return GL_FALSE; + } + + /* mark this attribute as used */ + usedAttributes |= (1 << attr); } - _mesa_add_attribute(shProg->Attributes, name, size, datatype,attr); - /* set the attribute as used */ - usedAttributes |= 1<attrib binding so it can be queried + * with glGetAttributeLocation(). + */ + _mesa_add_attribute(linkedProg->Attributes, name, + size, type, attr); } + /* update the instruction's src reg */ inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr; } } } + return GL_TRUE; } @@ -344,36 +380,6 @@ _slang_update_inputs_outputs(struct gl_program *prog) } -/** - * Scan a vertex program looking for instances of - * (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + oldAttrib) and replace with - * (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + newAttrib). - * This is used when the user calls glBindAttribLocation on an already linked - * shader program. - */ -void -_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib) -{ - GLuint i, j; - - assert(prog->Target == GL_VERTEX_PROGRAM_ARB); - - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - for (j = 0; j < 3; j++) { - if (inst->SrcReg[j].File == PROGRAM_INPUT) { - if (inst->SrcReg[j].Index == VERT_ATTRIB_GENERIC0 + oldAttrib) { - inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + newAttrib; - } - } - } - } - - _slang_update_inputs_outputs(prog); -} - - - /** cast wrapper */ static struct gl_vertex_program * vertex_program(struct gl_program *prog) @@ -492,9 +498,8 @@ _slang_link(GLcontext *ctx, /*_mesa_print_uniforms(shProg->Uniforms);*/ if (shProg->VertexProgram) { - if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) { - /*goto cleanup;*/ - _mesa_problem(ctx, "_slang_resolve_attributes() failed"); + if (!_slang_resolve_attributes(shProg, &vertProg->Base, + &shProg->VertexProgram->Base)) { return; } } diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 8ef8a6b4b3..2b44d20787 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.2 * - * Copyright (C) 2007 Brian Paul All Rights Reserved. + * Copyright (C) 2008 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -32,10 +32,6 @@ extern void _slang_link(GLcontext *ctx, GLhandleARB h, struct gl_shader_program *shProg); -extern void -_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, - GLuint newAttrib); - #endif -- cgit v1.2.3 From d7a7b0a10dd355fbeb7a404091a42d4ab558c820 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 17 Sep 2008 16:48:13 -0600 Subject: mesa: new gl_fragment_program fields indicating use of fog, front-facing, point coord --- src/mesa/main/mtypes.h | 5 +++- src/mesa/shader/slang/slang_link.c | 50 ++++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 19 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2fc169493b..a5e1cf6a27 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1953,7 +1953,10 @@ struct gl_fragment_program { struct gl_program Base; /**< base class */ GLenum FogOption; - GLboolean UsesKill; + GLboolean UsesKill; /**< shader uses KIL instruction */ + GLboolean UsesPointCoord; /**< shader uses gl_PointCoord */ + GLboolean UsesFrontFacing; /**< shader used gl_FrontFacing */ + GLboolean UsesFogFragCoord; /**< shader used gl_FogFragCoord */ }; diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index a44d001477..dd7d5be6d8 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -42,6 +42,24 @@ #include "slang_link.h" +/** cast wrapper */ +static struct gl_vertex_program * +vertex_program(struct gl_program *prog) +{ + assert(prog->Target == GL_VERTEX_PROGRAM_ARB); + return (struct gl_vertex_program *) prog; +} + + +/** cast wrapper */ +static struct gl_fragment_program * +fragment_program(struct gl_program *prog) +{ + assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); + return (struct gl_fragment_program *) prog; +} + + /** * Record a linking error. */ @@ -374,6 +392,20 @@ _slang_update_inputs_outputs(struct gl_program *prog) for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].File == PROGRAM_INPUT) { prog->InputsRead |= 1 << inst->SrcReg[j].Index; + if (prog->Target == GL_FRAGMENT_PROGRAM_ARB && + inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) { + /* The fragment shader FOGC input is used for fog, + * front-facing and sprite/point coord. + */ + struct gl_fragment_program *fp = fragment_program(prog); + const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0); + if (swz == SWIZZLE_X) + fp->UsesFogFragCoord = GL_TRUE; + else if (swz == SWIZZLE_Y) + fp->UsesFrontFacing = GL_TRUE; + else if (swz == SWIZZLE_Z || swz == SWIZZLE_W) + fp->UsesPointCoord = GL_TRUE; + } } else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { maxAddrReg = MAX2(maxAddrReg, inst->SrcReg[j].Index + 1); @@ -391,24 +423,6 @@ _slang_update_inputs_outputs(struct gl_program *prog) } -/** cast wrapper */ -static struct gl_vertex_program * -vertex_program(struct gl_program *prog) -{ - assert(prog->Target == GL_VERTEX_PROGRAM_ARB); - return (struct gl_vertex_program *) prog; -} - - -/** cast wrapper */ -static struct gl_fragment_program * -fragment_program(struct gl_program *prog) -{ - assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); - return (struct gl_fragment_program *) prog; -} - - /** * Shader linker. Currently: * -- cgit v1.2.3 From fa1b533012030cd67148b5bf1e018fd5e30c96f8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 3 Oct 2008 13:55:40 +0100 Subject: mesa: add new internal state for tracking current vertex attribs --- src/mesa/main/mtypes.h | 1 + src/mesa/main/state.c | 4 ++++ src/mesa/shader/prog_statevars.c | 8 ++++++++ src/mesa/shader/prog_statevars.h | 1 + src/mesa/vbo/vbo_exec_api.c | 44 ++++++++++++++++++++++++---------------- src/mesa/vbo/vbo_save_draw.c | 24 ++++++++++++++-------- 6 files changed, 56 insertions(+), 26 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index a5e1cf6a27..bc099dabeb 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2744,6 +2744,7 @@ struct gl_matrix_stack #define _NEW_MULTISAMPLE 0x2000000 /**< __GLcontextRec::Multisample */ #define _NEW_TRACK_MATRIX 0x4000000 /**< __GLcontextRec::VertexProgram */ #define _NEW_PROGRAM 0x8000000 /**< __GLcontextRec::VertexProgram */ +#define _NEW_CURRENT_ATTRIB 0x10000000 /**< __GLcontextRec::Current */ #define _NEW_ALL ~0 /*@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index d355f78a0e..eb8dc2a339 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -407,6 +407,9 @@ _mesa_update_state_locked( GLcontext *ctx ) GLbitfield new_state = ctx->NewState; GLbitfield prog_flags = _NEW_PROGRAM; + if (new_state == _NEW_CURRENT_ATTRIB) + goto out; + if (MESA_VERBOSE & VERBOSE_STATE) _mesa_print_state("_mesa_update_state", new_state); @@ -484,6 +487,7 @@ _mesa_update_state_locked( GLcontext *ctx ) * Set ctx->NewState to zero to avoid recursion if * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) */ + out: new_state = ctx->NewState; ctx->NewState = 0; ctx->Driver.UpdateState(ctx, new_state); diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 47c46f63ec..9cc33fa2c1 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -395,6 +395,12 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], case STATE_INTERNAL: switch (state[1]) { + case STATE_CURRENT_ATTRIB: { + const GLuint idx = (GLuint) state[2]; + COPY_4V(value, ctx->Current.Attrib[idx]); + return; + } + case STATE_NORMAL_SCALE: ASSIGN_4V(value, ctx->_ModelViewInvScale, @@ -565,6 +571,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) case STATE_INTERNAL: switch (state[1]) { + case STATE_CURRENT_ATTRIB: + return _NEW_CURRENT_ATTRIB; case STATE_NORMAL_SCALE: return _NEW_MODELVIEW; diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 7b490e3d63..1f728c64e8 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h @@ -104,6 +104,7 @@ typedef enum gl_state_index_ { STATE_LOCAL, STATE_INTERNAL, /* Mesa additions */ + STATE_CURRENT_ATTRIB, /* ctx->Current vertex attrib value */ STATE_NORMAL_SCALE, STATE_TEXRECT_SCALE, STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index d70b4bb1a1..23f4f8331e 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -143,29 +143,37 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { if (exec->vtx.attrsz[i]) { - GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; - /* Note: the exec->vtx.current[i] pointers point into the * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. */ - COPY_CLEAN_4V(current, - exec->vtx.attrsz[i], - exec->vtx.attrptr[i]); + GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + GLfloat tmp[4]; + + COPY_CLEAN_4V(tmp, + exec->vtx.attrsz[i], + exec->vtx.attrptr[i]); + + if (memcmp(current, tmp, sizeof(tmp)) != 0) + { + memcpy(current, tmp, sizeof(tmp)); - /* Given that we explicitly state size here, there is no need - * for the COPY_CLEAN above, could just copy 16 bytes and be - * done. The only problem is when Mesa accesses ctx->Current - * directly. - */ - vbo->currval[i].Size = exec->vtx.attrsz[i]; - - /* This triggers rather too much recalculation of Mesa state - * that doesn't get used (eg light positions). - */ - if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && - i <= VBO_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; + /* Given that we explicitly state size here, there is no need + * for the COPY_CLEAN above, could just copy 16 bytes and be + * done. The only problem is when Mesa accesses ctx->Current + * directly. + */ + vbo->currval[i].Size = exec->vtx.attrsz[i]; + + /* This triggers rather too much recalculation of Mesa state + * that doesn't get used (eg light positions). + */ + if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && + i <= VBO_ATTRIB_MAT_BACK_INDEXES) + ctx->NewState |= _NEW_LIGHT; + + ctx->NewState |= _NEW_CURRENT_ATTRIB; + } } } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index ed82f09958..4c97acddb9 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -64,18 +64,26 @@ static void _playback_copy_to_current( GLcontext *ctx, for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { if (node->attrsz[i]) { GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + GLfloat tmp[4]; - COPY_CLEAN_4V(current, - node->attrsz[i], - data); + COPY_CLEAN_4V(tmp, + node->attrsz[i], + data); + + if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) + { + memcpy(current, tmp, 4 * sizeof(GLfloat)); - vbo->currval[i].Size = node->attrsz[i]; + vbo->currval[i].Size = node->attrsz[i]; - data += node->attrsz[i]; + if (i >= VBO_ATTRIB_FIRST_MATERIAL && + i <= VBO_ATTRIB_LAST_MATERIAL) + ctx->NewState |= _NEW_LIGHT; + + ctx->NewState |= _NEW_CURRENT_ATTRIB; + } - if (i >= VBO_ATTRIB_FIRST_MATERIAL && - i <= VBO_ATTRIB_LAST_MATERIAL) - ctx->NewState |= _NEW_LIGHT; + data += node->attrsz[i]; } } -- cgit v1.2.3 From 1680ef869625dc1fe9cf481b180382a34e0738e7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 3 Oct 2008 17:30:59 +0100 Subject: mesa: avoid generating constant vertex attributes in fixedfunc programs Keep track of enabled/active vertex attributes. Keep track of potential vertex program outputs. When generating fragment program, replace references to fragment attributes which are effectively non-varying and non-computed passthrough attributes with references to the new CURRENT_ATTRIB tracked state value. Only downside is slight ugliness in VBO code where we need to validate state twice in succession. --- src/mesa/main/mtypes.h | 2 + src/mesa/main/state.c | 38 ++++++++++++++++- src/mesa/main/state.h | 3 ++ src/mesa/main/texenvprogram.c | 94 ++++++++++++++++++++++++++++++++++++++++--- src/mesa/vbo/vbo_exec_array.c | 41 +++++++++++++++---- src/mesa/vbo/vbo_exec_draw.c | 8 ++++ src/mesa/vbo/vbo_save_draw.c | 4 ++ 7 files changed, 177 insertions(+), 13 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bc099dabeb..ca1e369a35 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3073,6 +3073,8 @@ struct __GLcontextRec GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ + GLuint varying_vp_inputs; + /** \name Derived state */ /*@{*/ GLbitfield _TriangleCaps; /**< bitwise-or of DD_* flags */ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index eb8dc2a339..e0eb5f81e2 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -465,7 +465,8 @@ _mesa_update_state_locked( GLcontext *ctx ) _mesa_update_tnl_spaces( ctx, new_state ); if (ctx->FragmentProgram._MaintainTexEnvProgram) { - prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); + prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE_MATRIX | _NEW_LIGHT | + _NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); } if (ctx->VertexProgram._MaintainTnlProgram) { prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | @@ -504,3 +505,38 @@ _mesa_update_state( GLcontext *ctx ) _mesa_update_state_locked(ctx); _mesa_unlock_context_textures(ctx); } + + + + +/* Want to figure out which fragment program inputs are actually + * constant/current values from ctx->Current. These should be + * referenced as a tracked state variable rather than a fragment + * program input, to save the overhead of putting a constant value in + * every submitted vertex, transferring it to hardware, interpolating + * it across the triangle, etc... + * + * When there is a VP bound, just use vp->outputs. But when we're + * generating vp from fixed function state, basically want to + * calculate: + * + * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | + * potential_vp_outputs ) + * + * Where potential_vp_outputs is calculated by looking at enabled + * texgen, etc. + * + * The generated fragment program should then only declare inputs that + * may vary or otherwise differ from the ctx->Current values. + * Otherwise, the fp should track them as state values instead. + */ +void +_mesa_set_varying_vp_inputs( GLcontext *ctx, + unsigned varying_inputs ) +{ + if (ctx->varying_vp_inputs != varying_inputs) { + ctx->varying_vp_inputs = varying_inputs; + ctx->NewState |= _NEW_ARRAY; + //_mesa_printf("%s %x\n", __FUNCTION__, varying_inputs); + } +} diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index bb7cb8f32a..dc08043a76 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -37,5 +37,8 @@ _mesa_update_state( GLcontext *ctx ); extern void _mesa_update_state_locked( GLcontext *ctx ); +void +_mesa_set_varying_vp_inputs( GLcontext *ctx, + unsigned varying_inputs ); #endif diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index ac49373604..7cd82f98b0 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -189,6 +189,63 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) } } +#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) +#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) + +/* Identify all possible varying inputs. The fragment program will + * never reference non-varying inputs, but will track them via state + * constants instead. + * + * This function figures out all the inputs that the fragment program + * has access to. The bitmask is later reduced to just those which + * are actually referenced. + */ +static GLuint get_fp_input_mask( GLcontext *ctx ) +{ + GLuint fp_inputs = 0; + + if (1) { + GLuint varying_inputs = ctx->varying_vp_inputs; + + /* First look at what values may be computed by the generated + * vertex program: + */ + if (ctx->Light.Enabled) { + fp_inputs |= FRAG_BIT_COL0; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + fp_inputs |= FRAG_BIT_COL1; + } + + fp_inputs |= (ctx->Texture._TexGenEnabled | + ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; + + /* Then look at what might be varying as a result of enabled + * arrays, etc: + */ + if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0; + if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1; + + fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) + << FRAG_ATTRIB_TEX0); + + } + else { + /* calculate from vp->outputs */ + GLuint vp_outputs = 0; + + if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0; + if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1; + + fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) + << VERT_RESULT_TEX0) + >> FRAG_ATTRIB_TEX0); + } + + return fp_inputs; +} + + /** * Examine current texture environment state and generate a unique * key to identify it. @@ -196,17 +253,21 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) static void make_state_key( GLcontext *ctx, struct state_key *key ) { GLuint i, j; - + GLuint inputs_referenced = FRAG_BIT_COL0; + GLuint inputs_available = get_fp_input_mask( ctx ); + memset(key, 0, sizeof(*key)); for (i=0;iTexture.Unit[i]; - if (!texUnit->_ReallyEnabled) + if (!texUnit->_ReallyEnabled) continue; key->unit[i].enabled = 1; key->enabled_units |= (1<nr_enabled_units = i+1; + inputs_referenced |= FRAG_BIT_TEX(i); key->unit[i].source_index = translate_tex_src_bit(texUnit->_ReallyEnabled); @@ -234,13 +295,18 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) } } - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { key->separate_specular = 1; + inputs_referenced |= FRAG_BIT_COL1; + } if (ctx->Fog.Enabled) { key->fog_enabled = 1; key->fog_mode = translate_fog_mode(ctx->Fog.Mode); + inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ } + + key->inputs_available = (inputs_available & inputs_referenced); } /* Use uregs to represent registers internally, translate to Mesa's @@ -446,11 +512,29 @@ static struct ureg register_param5( struct texenv_fragment_program *p, #define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) #define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) +static GLuint frag_to_vert_attrib( GLuint attrib ) +{ + switch (attrib) { + case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0; + case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1; + default: + assert(attrib >= FRAG_ATTRIB_TEX0); + assert(attrib <= FRAG_ATTRIB_TEX7); + return attrib - FRAG_ATTRIB_TEX0 + VERT_ATTRIB_TEX0; + } +} + static struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) { - p->program->Base.InputsRead |= (1 << input); - return make_ureg(PROGRAM_INPUT, input); + if (p->state->inputs_available & (1<program->Base.InputsRead |= (1 << input); + return make_ureg(PROGRAM_INPUT, input); + } + else { + GLuint idx = frag_to_vert_attrib( input ); + return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); + } } diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 0f9d8da356..3d74f9f431 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -127,6 +127,7 @@ static void recalculate_input_bindings( GLcontext *ctx ) struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; const struct gl_client_array **inputs = &exec->array.inputs[0]; + GLuint const_inputs = 0; GLuint i; exec->array.program_mode = get_program_mode(ctx); @@ -141,19 +142,24 @@ static void recalculate_input_bindings( GLcontext *ctx ) for (i = 0; i <= VERT_ATTRIB_TEX7; i++) { if (exec->array.legacy_array[i]->Enabled) inputs[i] = exec->array.legacy_array[i]; - else + else { inputs[i] = &vbo->legacy_currval[i]; + const_inputs |= 1 << i; + } } for (i = 0; i < MAT_ATTRIB_MAX; i++) { inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->mat_currval[i]; + const_inputs |= 1 << (VERT_ATTRIB_GENERIC0 + i); } /* Could use just about anything, just to fill in the empty * slots: */ - for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_MAX - VERT_ATTRIB_GENERIC0; i++) + for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_MAX - VERT_ATTRIB_GENERIC0; i++) { inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i]; + const_inputs |= 1 << (VERT_ATTRIB_GENERIC0 + i); + } break; case VP_NV: @@ -166,15 +172,19 @@ static void recalculate_input_bindings( GLcontext *ctx ) inputs[i] = exec->array.generic_array[i]; else if (exec->array.legacy_array[i]->Enabled) inputs[i] = exec->array.legacy_array[i]; - else + else { inputs[i] = &vbo->legacy_currval[i]; + const_inputs |= 1 << i; + } } /* Could use just about anything, just to fill in the empty * slots: */ - for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) + for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { inputs[i] = &vbo->generic_currval[i - VERT_ATTRIB_GENERIC0]; + const_inputs |= 1 << i; + } break; case VP_ARB: @@ -189,25 +199,34 @@ static void recalculate_input_bindings( GLcontext *ctx ) inputs[0] = exec->array.generic_array[0]; else if (exec->array.legacy_array[0]->Enabled) inputs[0] = exec->array.legacy_array[0]; - else + else { inputs[0] = &vbo->legacy_currval[0]; + const_inputs |= 1 << 0; + } for (i = 1; i <= VERT_ATTRIB_TEX7; i++) { if (exec->array.legacy_array[i]->Enabled) inputs[i] = exec->array.legacy_array[i]; - else + else { inputs[i] = &vbo->legacy_currval[i]; + const_inputs |= 1 << i; + } } for (i = 0; i < 16; i++) { if (exec->array.generic_array[i]->Enabled) inputs[VERT_ATTRIB_GENERIC0 + i] = exec->array.generic_array[i]; - else + else { inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i]; + const_inputs |= 1 << (VERT_ATTRIB_GENERIC0 + i); + } + } break; } + + _mesa_set_varying_vp_inputs( ctx, ~const_inputs ); } static void bind_arrays( GLcontext *ctx ) @@ -257,6 +276,11 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) bind_arrays( ctx ); + /* Again... + */ + if (ctx->NewState) + _mesa_update_state( ctx ); + prim[0].begin = 1; prim[0].end = 1; prim[0].weak = 0; @@ -297,6 +321,9 @@ vbo_exec_DrawRangeElements(GLenum mode, bind_arrays( ctx ); + if (ctx->NewState) + _mesa_update_state( ctx ); + ib.count = count; ib.type = type; ib.obj = ctx->Array.ElementArrayBufferObj; diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index f497e9a5a5..ad60c9b05f 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -150,6 +150,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx ) GLubyte *data = exec->vtx.buffer_map; const GLuint *map; GLuint attr; + GLuint varying_inputs = 0; /* Install the default (ie Current) attributes first, then overlay * all active ones. @@ -211,8 +212,11 @@ static void vbo_exec_bind_arrays( GLcontext *ctx ) arrays[attr]._MaxElement = count; /* ??? */ data += exec->vtx.attrsz[src] * sizeof(GLfloat); + varying_inputs |= 1<NewState) + _mesa_update_state( ctx ); + + ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj); exec->vtx.buffer_map = NULL; diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 4c97acddb9..b015bf2786 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -118,6 +118,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx, GLuint data = node->buffer_offset; const GLuint *map; GLuint attr; + GLuint varying_inputs = 0; /* Install the default (ie Current) attributes first, then overlay * all active ones. @@ -167,8 +168,11 @@ static void vbo_bind_vertex_list( GLcontext *ctx, assert(arrays[attr].BufferObj->Name); data += node->attrsz[src] * sizeof(GLfloat); + varying_inputs |= 1< Date: Tue, 7 Oct 2008 11:22:47 -0600 Subject: mesa: replace GLuint with GLbitfield to be clearer about usage Also, fix up some comments to be doxygen style. --- src/mesa/main/mtypes.h | 2 +- src/mesa/main/state.c | 2 +- src/mesa/main/state.h | 2 +- src/mesa/main/texenvprogram.c | 30 ++++++++++++++++-------------- src/mesa/vbo/vbo_exec_array.c | 2 +- src/mesa/vbo/vbo_exec_draw.c | 2 +- src/mesa/vbo/vbo_save_draw.c | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ca1e369a35..dff474d6d0 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3073,7 +3073,7 @@ struct __GLcontextRec GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ - GLuint varying_vp_inputs; + GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ /** \name Derived state */ /*@{*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index e0eb5f81e2..b124d48269 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -532,7 +532,7 @@ _mesa_update_state( GLcontext *ctx ) */ void _mesa_set_varying_vp_inputs( GLcontext *ctx, - unsigned varying_inputs ) + GLbitfield varying_inputs ) { if (ctx->varying_vp_inputs != varying_inputs) { ctx->varying_vp_inputs = varying_inputs; diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index dc08043a76..79f2f6beb0 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -39,6 +39,6 @@ _mesa_update_state_locked( GLcontext *ctx ); void _mesa_set_varying_vp_inputs( GLcontext *ctx, - unsigned varying_inputs ); + GLbitfield varying_inputs ); #endif diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 7049467c22..638d6be5ad 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -192,7 +192,8 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) #define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) #define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) -/* Identify all possible varying inputs. The fragment program will +/** + * Identify all possible varying inputs. The fragment program will * never reference non-varying inputs, but will track them via state * constants instead. * @@ -200,15 +201,15 @@ static GLuint translate_tex_src_bit( GLbitfield bit ) * has access to. The bitmask is later reduced to just those which * are actually referenced. */ -static GLuint get_fp_input_mask( GLcontext *ctx ) +static GLbitfield get_fp_input_mask( GLcontext *ctx ) { - GLuint fp_inputs = 0; + GLbitfield fp_inputs = 0x0; if (!ctx->VertexProgram._Enabled || !ctx->VertexProgram._Current) { /* Fixed function logic */ - GLuint varying_inputs = ctx->varying_vp_inputs; + GLbitfield varying_inputs = ctx->varying_vp_inputs; /* First look at what values may be computed by the generated * vertex program: @@ -235,7 +236,7 @@ static GLuint get_fp_input_mask( GLcontext *ctx ) } else { /* calculate from vp->outputs */ - GLuint vp_outputs = ctx->VertexProgram._Current->Base.OutputsWritten; + GLbitfield vp_outputs = ctx->VertexProgram._Current->Base.OutputsWritten; if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0; if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1; @@ -255,8 +256,8 @@ static GLuint get_fp_input_mask( GLcontext *ctx ) static void make_state_key( GLcontext *ctx, struct state_key *key ) { GLuint i, j; - GLuint inputs_referenced = FRAG_BIT_COL0; - GLuint inputs_available = get_fp_input_mask( ctx ); + GLbitfield inputs_referenced = FRAG_BIT_COL0; + GLbitfield inputs_available = get_fp_input_mask( ctx ); memset(key, 0, sizeof(*key)); @@ -311,7 +312,8 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) key->inputs_available = (inputs_available & inputs_referenced); } -/* Use uregs to represent registers internally, translate to Mesa's +/** + * Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. * * NOTE: These are passed by value extensively in this file rather @@ -344,16 +346,16 @@ static const struct ureg undef = { }; -/* State used to build the fragment program: +/** State used to build the fragment program: */ struct texenv_fragment_program { struct gl_fragment_program *program; GLcontext *ctx; struct state_key *state; - GLbitfield alu_temps; /* Track texture indirections, see spec. */ - GLbitfield temps_output; /* Track texture indirections, see spec. */ - GLbitfield temp_in_use; /* Tracks temporary regs which are in use. */ + GLbitfield alu_temps; /**< Track texture indirections, see spec. */ + GLbitfield temps_output; /**< Track texture indirections, see spec. */ + GLbitfield temp_in_use; /**< Tracks temporary regs which are in use. */ GLboolean error; struct ureg src_texture[MAX_TEXTURE_UNITS]; @@ -361,11 +363,11 @@ struct texenv_fragment_program { * else undef. */ - struct ureg src_previous; /* Reg containing color from previous + struct ureg src_previous; /**< Reg containing color from previous * stage. May need to be decl'd. */ - GLuint last_tex_stage; /* Number of last enabled texture unit */ + GLuint last_tex_stage; /**< Number of last enabled texture unit */ struct ureg half; struct ureg one; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 3d74f9f431..8871e10cf6 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -127,7 +127,7 @@ static void recalculate_input_bindings( GLcontext *ctx ) struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; const struct gl_client_array **inputs = &exec->array.inputs[0]; - GLuint const_inputs = 0; + GLbitfield const_inputs = 0x0; GLuint i; exec->array.program_mode = get_program_mode(ctx); diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index ad60c9b05f..ae43857c8a 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -150,7 +150,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx ) GLubyte *data = exec->vtx.buffer_map; const GLuint *map; GLuint attr; - GLuint varying_inputs = 0; + GLbitfield varying_inputs = 0x0; /* Install the default (ie Current) attributes first, then overlay * all active ones. diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 68f3a965a5..0488c5d718 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -118,7 +118,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx, GLuint data = node->buffer_offset; const GLuint *map; GLuint attr; - GLuint varying_inputs = 0; + GLbitfield varying_inputs = 0x0; /* Install the default (ie Current) attributes first, then overlay * all active ones. -- cgit v1.2.3 From 6d4d51d647c27288aa625560bc080231099c0b01 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Oct 2008 13:39:14 -0600 Subject: mesa: new _mesa_set_vp_override() function for driver-override of vertex program Patch provide by Keith. Used in state tracker by DrawPixels to indicate that the state tracker (driver) is using its own vertex program. This prevents the texenvprogram code from replacing conventional shader inputs with state vars. Fixes glDraw/CopyPixels regressions. --- src/mesa/main/mtypes.h | 2 ++ src/mesa/main/state.c | 29 ++++++++++++++++++++++++++--- src/mesa/main/state.h | 17 +++++++++++------ src/mesa/main/texenvprogram.c | 14 ++++++++++++-- src/mesa/state_tracker/st_cb_drawpixels.c | 6 ++++++ 5 files changed, 57 insertions(+), 11 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index dff474d6d0..fab6ad05ee 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2007,6 +2007,8 @@ struct gl_vertex_program_state GLboolean CallbackEnabled; GLuint CurrentPosition; #endif + + GLboolean _Overriden; }; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index b124d48269..a962f1cb41 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -466,10 +466,12 @@ _mesa_update_state_locked( GLcontext *ctx ) if (ctx->FragmentProgram._MaintainTexEnvProgram) { prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE_MATRIX | _NEW_LIGHT | + _NEW_RENDERMODE | _NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); } if (ctx->VertexProgram._MaintainTnlProgram) { prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | + _NEW_RENDERMODE | _NEW_TRANSFORM | _NEW_POINT | _NEW_FOG | _NEW_LIGHT | _MESA_NEW_NEED_EYE_COORDS); @@ -509,7 +511,8 @@ _mesa_update_state( GLcontext *ctx ) -/* Want to figure out which fragment program inputs are actually +/** + * Want to figure out which fragment program inputs are actually * constant/current values from ctx->Current. These should be * referenced as a tracked state variable rather than a fragment * program input, to save the overhead of putting a constant value in @@ -537,6 +540,26 @@ _mesa_set_varying_vp_inputs( GLcontext *ctx, if (ctx->varying_vp_inputs != varying_inputs) { ctx->varying_vp_inputs = varying_inputs; ctx->NewState |= _NEW_ARRAY; - //_mesa_printf("%s %x\n", __FUNCTION__, varying_inputs); + /*_mesa_printf("%s %x\n", __FUNCTION__, varying_inputs);*/ + } +} + + +/** + * Used by drivers to tell core Mesa that the driver is going to + * install/ use its own vertex program. In particular, this will + * prevent generated fragment programs from using state vars instead + * of ordinary varyings/inputs. + */ +void +_mesa_set_vp_override(GLcontext *ctx, GLboolean flag) +{ + if (ctx->VertexProgram._Overriden != flag) { + ctx->VertexProgram._Overriden = flag; + + /* Set one of the bits which will trigger fragment program + * regeneration: + */ + ctx->NewState |= _NEW_ARRAY; } } diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index 79f2f6beb0..29db08a0b9 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -29,16 +29,21 @@ #include "mtypes.h" extern void -_mesa_update_state( GLcontext *ctx ); +_mesa_update_state(GLcontext *ctx); /* As above but can only be called between _mesa_lock_context_textures() and * _mesa_unlock_context_textures(). */ extern void -_mesa_update_state_locked( GLcontext *ctx ); +_mesa_update_state_locked(GLcontext *ctx); + + +extern void +_mesa_set_varying_vp_inputs(GLcontext *ctx, GLbitfield varying_inputs); + + +extern void +_mesa_set_vp_override(GLcontext *ctx, GLboolean flag); -void -_mesa_set_varying_vp_inputs( GLcontext *ctx, - GLbitfield varying_inputs ); #endif diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 638d6be5ad..f3bac86dfe 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -205,8 +205,18 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx ) { GLbitfield fp_inputs = 0x0; - if (!ctx->VertexProgram._Enabled || - !ctx->VertexProgram._Current) { + if (ctx->VertexProgram._Overriden) { + /* Somebody's messing with the vertex program and we don't have + * a clue what's happening. Assume that it could be producing + * all possible outputs. + */ + fp_inputs = ~0; + } + else if (ctx->RenderMode == GL_FEEDBACK) { + fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0); + } + else if (!ctx->VertexProgram._Enabled || + !ctx->VertexProgram._Current) { /* Fixed function logic */ GLbitfield varying_inputs = ctx->varying_vp_inputs; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 00bbcae32a..5b24b9f068 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -35,6 +35,7 @@ #include "main/bufferobj.h" #include "main/macros.h" #include "main/texformat.h" +#include "main/state.h" #include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" @@ -835,6 +836,9 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, return; } + _mesa_set_vp_override( ctx, TRUE ); + _mesa_update_state( ctx ); + st_validate_state(st); if (format == GL_DEPTH_COMPONENT) { @@ -874,6 +878,8 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* blit */ draw_blit(st, width, height, format, type, pixels); } + + _mesa_set_vp_override( ctx, FALSE ); } -- cgit v1.2.3 From 9585f8daef6681bf1ad62ff4ad9a4102cf5d1abd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 17 Dec 2008 14:54:46 -0700 Subject: mesa: updated comments --- src/mesa/main/mtypes.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 556b4ed016..2a48b7c517 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -7,7 +7,7 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.3 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -1958,14 +1958,15 @@ struct gl_program_state */ struct gl_vertex_program_state { - GLboolean Enabled; /**< GL_VERTEX_PROGRAM_ARB/NV */ - GLboolean _Enabled; /**< Enabled and valid program? */ + GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */ + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ - struct gl_vertex_program *Current; /**< user-bound vertex program */ + struct gl_vertex_program *Current; /**< User-bound vertex program */ - /** Currently enabled and valid program (including internal programs - * and compiled shader programs). + /** Currently enabled and valid vertex program (including internal programs, + * user-defined vertex programs and GLSL vertex shaders). + * This is the program we must use when rendering. */ struct gl_vertex_program *_Current; @@ -2001,12 +2002,12 @@ struct gl_vertex_program_state struct gl_fragment_program_state { GLboolean Enabled; /**< User-set fragment program enable flag */ - GLboolean _Enabled; /**< Fragment program enabled and valid? */ - GLboolean _Active; + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ struct gl_fragment_program *Current; /**< User-bound fragment program */ - /** Currently enabled and valid program (including internal programs - * and compiled shader programs). + /** Currently enabled and valid fragment program (including internal programs, + * user-defined fragment programs and GLSL fragment shaders). + * This is the program we must use when rendering. */ struct gl_fragment_program *_Current; @@ -2015,6 +2016,7 @@ struct gl_fragment_program_state /** Should fixed-function texturing be implemented with a fragment prog? */ GLboolean _MaintainTexEnvProgram; GLboolean _UseTexEnvProgram; + GLboolean _Active; /**< Use internal texenv program? */ /** Program to emulate fixed-function texture env/combine (see above) */ struct gl_fragment_program *_TexEnvProgram; -- cgit v1.2.3 From 510916f50961a3a9286807e7f75ba716f3e7f967 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 7 Jan 2009 14:09:07 -0800 Subject: mesa: Remove _Active and _UseTexEnvProgram flags from fragment programs. There was a note in state.c about _Active deserving to die, and there were potential issues with it due to i965 forgetting to set _UseTexEnvProgram. Removing both simplifies things. Reviewed-by: Brian Paul --- src/mesa/drivers/dri/i915/i915_context.c | 1 - src/mesa/drivers/dri/i915/i915_state.c | 2 +- src/mesa/drivers/dri/intel/intel_pixel_draw.c | 25 ++----------------------- src/mesa/main/context.c | 1 - src/mesa/main/mtypes.h | 2 -- src/mesa/main/state.c | 11 ----------- src/mesa/swrast/s_aalinetemp.h | 2 +- src/mesa/tnl/t_context.c | 2 +- 8 files changed, 5 insertions(+), 41 deletions(-) (limited to 'src/mesa/main/mtypes.h') diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 9bff74294d..3d6af38057 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -171,7 +171,6 @@ i915CreateContext(const __GLcontextModes * mesaVis, ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; driInitExtensions(ctx, i915_extensions, GL_FALSE); diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 9d04358e4f..a53f120a81 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -569,7 +569,7 @@ i915_update_fog(GLcontext * ctx) GLboolean enabled; GLboolean try_pixel_fog; - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Current) { /* Pull in static fog state from program */ mode = ctx->FragmentProgram._Current->FogOption; enabled = (mode != GL_NONE); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index 0d66935ad2..2af839b803 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -386,27 +386,6 @@ intelDrawPixels(GLcontext * ctx, if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) { - /* - * We don't want the i915 texenv program to be applied to DrawPixels. - * This is really just a performance optimization (mesa will other- - * wise happily run the fragment program on each pixel in the image). - */ - struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current; - /* can't just set current frag prog to 0 here as on buffer resize - we'll get new state checks which will segfault. Remains a hack. */ - ctx->FragmentProgram._Current = NULL; - ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE; - ctx->FragmentProgram._Active = GL_FALSE; - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); - ctx->FragmentProgram._Current = fpSave; - ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - ctx->FragmentProgram._Active = GL_TRUE; - _swrast_InvalidateState(ctx, _NEW_PROGRAM); - } - else { - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); - } + _swrast_DrawPixels(ctx, x, y, width, height, format, type, + unpack, pixels); } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index ea52b26f0f..8299628218 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1226,7 +1226,6 @@ _mesa_initialize_context(GLcontext *ctx, ctx->FragmentProgram._MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL); - ctx->FragmentProgram._UseTexEnvProgram = ctx->FragmentProgram._MaintainTexEnvProgram; ctx->VertexProgram._MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index a17bf9c7b0..25dee52ad0 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2014,8 +2014,6 @@ struct gl_fragment_program_state /** Should fixed-function texturing be implemented with a fragment prog? */ GLboolean _MaintainTexEnvProgram; - GLboolean _UseTexEnvProgram; - GLboolean _Active; /**< Use internal texenv program? */ /** Program to emulate fixed-function texture env/combine (see above) */ struct gl_fragment_program *_TexEnvProgram; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 3c111759d2..718cd99847 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -254,17 +254,6 @@ update_program(GLcontext *ctx) _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); } - /* XXX: get rid of _Active flag. - */ -#if 1 - ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; - if (ctx->FragmentProgram._MaintainTexEnvProgram && - !ctx->FragmentProgram._Enabled) { - if (ctx->FragmentProgram._UseTexEnvProgram) - ctx->FragmentProgram._Active = GL_TRUE; - } -#endif - /* Let the driver know what's happening: */ if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) { diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index ca08203d83..42ffe9f20c 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -76,7 +76,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) ATTRIB_LOOP_BEGIN GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0 - && !ctx->FragmentProgram._Active) { + && !ctx->FragmentProgram._Current) { /* texcoord w/ divide by Q */ const GLuint unit = attr - FRAG_ATTRIB_TEX0; const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]); diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index ce37dc0428..fdf4534b36 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -140,7 +140,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) /* fixed-function fog */ RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); } - else if (ctx->FragmentProgram._Active || ctx->FragmentProgram._Current) { + else if (ctx->FragmentProgram._Current) { struct gl_fragment_program *fp = ctx->FragmentProgram._Current; if (fp) { if (fp->FogOption != GL_NONE || (fp->Base.InputsRead & FRAG_BIT_FOGC)) { -- cgit v1.2.3