diff options
author | Nicolai Hähnle <nhaehnle@gmail.com> | 2009-10-07 20:39:22 +0200 |
---|---|---|
committer | Nicolai Hähnle <nhaehnle@gmail.com> | 2009-10-07 20:39:22 +0200 |
commit | 5b4c0b864a25fa193e7ba828cf5ce483ca05bd4e (patch) | |
tree | f462528c24889bee0665451e9e32664ecf2add3c | |
parent | 3f5a316f36e2d376104640033c8bcefef3810ef4 (diff) | |
parent | 9fde81bb20bbfd2f8da80749cb84d890843a7bc2 (diff) |
Merge branch 'mesa_7_6_branch'
-rw-r--r-- | docs/relnotes-7.6.1.html | 1 | ||||
-rw-r--r-- | progs/tests/random.c | 2 | ||||
-rw-r--r-- | progs/xdemos/pbdemo.c | 17 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/glx_api.c | 46 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.c | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/x11/fakeglx.c | 45 | ||||
-rw-r--r-- | src/mesa/drivers/x11/xmesaP.h | 3 | ||||
-rw-r--r-- | src/mesa/shader/shader_api.c | 31 | ||||
-rw-r--r-- | src/mesa/swrast/s_depth.c | 4 |
10 files changed, 115 insertions, 43 deletions
diff --git a/docs/relnotes-7.6.1.html b/docs/relnotes-7.6.1.html index d69af7aec26..52a4728133e 100644 --- a/docs/relnotes-7.6.1.html +++ b/docs/relnotes-7.6.1.html @@ -42,6 +42,7 @@ tbd <li>GLSL sqrt(0) returned unpredictable results <li>Fixed default texture binding bug when a bound texture was deleted. <li>r300: Work around an issue with very large fragment programs on R500. +<li>Fake glXQueryDrawable() didn't return good values (bug 24320) </ul> </body> diff --git a/progs/tests/random.c b/progs/tests/random.c index 4023674c05f..604b4d4088c 100644 --- a/progs/tests/random.c +++ b/progs/tests/random.c @@ -257,11 +257,11 @@ RandomPrimitive(void) Vcount++; for (i = 0; i < len; i++) { + int k = RandomInt(9); Vbuffer[Vcount].v[0] = RandomFloat(-3, 3); Vbuffer[Vcount].v[1] = RandomFloat(-3, 3); Vbuffer[Vcount].v[2] = RandomFloat(-3, 3); Vbuffer[Vcount].v[3] = RandomFloat(-3, 3); - int k = RandomInt(9); switch (k) { case 0: glVertex2fv(Vbuffer[Vcount].v); diff --git a/progs/xdemos/pbdemo.c b/progs/xdemos/pbdemo.c index 7db0017b33e..2573209336c 100644 --- a/progs/xdemos/pbdemo.c +++ b/progs/xdemos/pbdemo.c @@ -143,7 +143,7 @@ MakePbuffer( Display *dpy, int screen, int width, int height ) /* Create the pbuffer using first fbConfig in the list that works. */ for (i=0;i<nConfigs;i++) { - pBuffer = CreatePbuffer(dpy, screen, fbConfigs[i], width, height, preserve, largest); + pBuffer = CreatePbuffer(dpy, screen, fbConfigs[i], width, height, largest, preserve); if (pBuffer) { gFBconfig = fbConfigs[i]; gWidth = width; @@ -210,6 +210,21 @@ Setup(int width, int height) return 0; } + /* Test drawable queries */ + { + unsigned int v; + glXQueryDrawable( gDpy, gPBuffer, GLX_WIDTH, &v); + printf("GLX_WIDTH = %u\n", v); + glXQueryDrawable( gDpy, gPBuffer, GLX_HEIGHT, &v); + printf("GLX_HEIGHT = %u\n", v); + glXQueryDrawable( gDpy, gPBuffer, GLX_PRESERVED_CONTENTS, &v); + printf("GLX_PRESERVED_CONTENTS = %u\n", v); + glXQueryDrawable( gDpy, gPBuffer, GLX_LARGEST_PBUFFER, &v); + printf("GLX_LARGEST_PBUFFER = %u\n", v); + glXQueryDrawable( gDpy, gPBuffer, GLX_FBCONFIG_ID, &v); + printf("GLX_FBCONFIG_ID = %u\n", v); + } + /* Get corresponding XVisualInfo */ visInfo = GetVisualFromFBConfig(gDpy, gScreen, gFBconfig); if (!visInfo) { diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c index 6cd7ede31cf..556eefb1b17 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_api.c +++ b/src/gallium/state_trackers/glx/xlib/glx_api.c @@ -1309,12 +1309,14 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, Bool -glXQueryExtension( Display *dpy, int *errorb, int *event ) +glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) { /* Mesa's GLX isn't really an X extension but we try to act like one. */ (void) dpy; - (void) errorb; - (void) event; + if (errorBase) + *errorBase = 0; + if (eventBase) + *eventBase = 0; return True; } @@ -1990,32 +1992,42 @@ glXCreatePbuffer( Display *dpy, GLXFBConfig config, break; case GLX_PRESERVED_CONTENTS: attrib++; - preserveContents = *attrib; /* ignored */ + preserveContents = *attrib; break; case GLX_LARGEST_PBUFFER: attrib++; - useLargest = *attrib; /* ignored */ + useLargest = *attrib; break; default: return 0; } } - /* not used at this time */ - (void) useLargest; - (void) preserveContents; - if (width == 0 || height == 0) return 0; + if (width > MAX_WIDTH || height > MAX_HEIGHT) { + /* If allocation would have failed and GLX_LARGEST_PBUFFER is set, + * allocate the largest possible buffer. + */ + if (useLargest) { + width = MAX_WIDTH; + height = MAX_HEIGHT; + } + } + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - if (xmbuf) + if (xmbuf) { + xmbuf->largestPbuffer = useLargest; + xmbuf->preservedContents = preserveContents; return (GLXPbuffer) xmbuf->drawable; - else + } + else { return 0; + } } @@ -2033,22 +2045,26 @@ void glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, unsigned int *value ) { + GLuint width, height; XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); if (!xmbuf) return; + /* make sure buffer's dimensions are up to date */ + xmesa_get_window_size(dpy, xmbuf, &width, &height); + switch (attribute) { case GLX_WIDTH: - *value = xmesa_buffer_width(xmbuf); + *value = width; break; case GLX_HEIGHT: - *value = xmesa_buffer_width(xmbuf); + *value = height; break; case GLX_PRESERVED_CONTENTS: - *value = True; + *value = xmbuf->preservedContents; break; case GLX_LARGEST_PBUFFER: - *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); + *value = xmbuf->largestPbuffer; break; case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index 957002ddd55..c76dfb31d2b 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -228,7 +228,7 @@ get_drawable_size( Display *dpy, Drawable d, uint *width, uint *height ) * \param width returns width in pixels * \param height returns height in pixels */ -static void +void xmesa_get_window_size(Display *dpy, XMesaBuffer b, GLuint *width, GLuint *height) { diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index ce97a3ec768..d24971ca1c7 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -323,6 +323,9 @@ struct xmesa_buffer { Colormap cmap; /* the X colormap */ BufferType type; /* window, pixmap, pbuffer or glxwindow */ + GLboolean largestPbuffer; /**< for pbuffers */ + GLboolean preservedContents; /**< for pbuffers */ + XImage *tempImage; unsigned long selectedEvents;/* for pbuffers only */ @@ -370,6 +373,10 @@ extern XMesaBuffer xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis); extern void +xmesa_get_window_size(Display *dpy, XMesaBuffer b, + GLuint *width, GLuint *height); + +extern void xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer); extern void diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index 6449dc88b0d..525db3b7cb7 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -1637,12 +1637,14 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, static Bool -Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) +Fake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) { /* Mesa's GLX isn't really an X extension but we try to act like one. */ (void) dpy; - (void) errorb; - (void) event; + if (errorBase) + *errorBase = 0; + if (eventBase) + *eventBase = 0; return True; } @@ -2349,32 +2351,42 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, break; case GLX_PRESERVED_CONTENTS: attrib++; - preserveContents = *attrib; /* ignored */ + preserveContents = *attrib; break; case GLX_LARGEST_PBUFFER: attrib++; - useLargest = *attrib; /* ignored */ + useLargest = *attrib; break; default: return 0; } } - /* not used at this time */ - (void) useLargest; - (void) preserveContents; - if (width == 0 || height == 0) return 0; + if (width > MAX_WIDTH || height > MAX_HEIGHT) { + /* If allocation would have failed and GLX_LARGEST_PBUFFER is set, + * allocate the largest possible buffer. + */ + if (useLargest) { + width = MAX_WIDTH; + height = MAX_HEIGHT; + } + } + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - if (xmbuf) + if (xmbuf) { + xmbuf->largestPbuffer = useLargest; + xmbuf->preservedContents = preserveContents; return (GLXPbuffer) xmbuf->frontxrb->pixmap; - else + } + else { return 0; + } } @@ -2396,6 +2408,9 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, if (!xmbuf) return; + /* make sure buffer's dimensions are up to date */ + xmesa_check_and_update_buffer_size(NULL, xmbuf); + switch (attribute) { case GLX_WIDTH: *value = xmbuf->mesa_buffer.Width; @@ -2404,10 +2419,10 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, *value = xmbuf->mesa_buffer.Height; break; case GLX_PRESERVED_CONTENTS: - *value = True; + *value = xmbuf->preservedContents; break; case GLX_LARGEST_PBUFFER: - *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + *value = xmbuf->largestPbuffer; break; case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; @@ -2764,10 +2779,10 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un switch (attribute) { case GLX_PRESERVED_CONTENTS_SGIX: - *value = True; + *value = xmbuf->preservedContents; break; case GLX_LARGEST_PBUFFER_SGIX: - *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + *value = xmbuf->largestPbuffer; break; case GLX_WIDTH_SGIX: *value = xmbuf->mesa_buffer.Width; diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h index 25db55862e6..3ffd7661e35 100644 --- a/src/mesa/drivers/x11/xmesaP.h +++ b/src/mesa/drivers/x11/xmesaP.h @@ -212,6 +212,9 @@ struct xmesa_buffer { XMesaDisplay *display; BufferType type; /* window, pixmap, pbuffer or glxwindow */ + GLboolean largestPbuffer; /**< for pbuffers */ + GLboolean preservedContents; /**< for pbuffers */ + struct xmesa_renderbuffer *frontxrb; /* front color renderbuffer */ struct xmesa_renderbuffer *backxrb; /* back color renderbuffer */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 6b19b4c46b3..ce196493231 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1706,8 +1706,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, /* we'll ignore extra data below */ } else { - /* non-array: count must be one */ - if (count != 1) { + /* non-array: count must be at most one; count == 0 is handled by the loop below */ + if (count > 1) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(uniform is not an array)"); return; @@ -1884,20 +1884,27 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, GLboolean transpose, const GLfloat *values) { GLuint mat, row, col; - GLuint dst = index + offset, src = 0; + GLuint src = 0; + const struct gl_program_parameter * param = &program->Parameters->Parameters[index]; + const GLint slots = (param->Size + 3) / 4; + const GLint typeSize = sizeof_glsl_type(param->DataType); GLint nr, nc; /* check that the number of rows, columns is correct */ - get_matrix_dims(program->Parameters->Parameters[index].DataType, &nr, &nc); + get_matrix_dims(param->DataType, &nr, &nc); if (rows != nr || cols != nc) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(matrix size mismatch)"); return; } - if (index + offset > program->Parameters->Size) { - /* out of bounds! */ - return; + if (param->Size <= typeSize) { + /* non-array: count must be at most one; count == 0 is handled by the loop below */ + if (count > 1) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUniformMatrix(uniform is not an array)"); + return; + } } /* @@ -1911,7 +1918,12 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, /* each matrix: */ for (col = 0; col < cols; col++) { - GLfloat *v = program->Parameters->ParameterValues[dst]; + GLfloat *v; + if (offset >= slots) { + /* Ignore writes beyond the end of (the used part of) an array */ + return; + } + v = program->Parameters->ParameterValues[index + offset]; for (row = 0; row < rows; row++) { if (transpose) { v[row] = values[src + row * cols + col]; @@ -1920,7 +1932,8 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, v[row] = values[src + col * rows + row]; } } - dst++; + + offset++; } src += rows * cols; /* next matrix */ diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index 1a428fb1a28..17e00dda4ff 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -1238,6 +1238,7 @@ _swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb, if (!rb) { /* really only doing this to prevent FP exceptions later */ _mesa_bzero(depth, n * sizeof(GLfloat)); + return; } ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT); @@ -1300,7 +1301,8 @@ _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb, { if (!rb) { /* really only doing this to prevent FP exceptions later */ - _mesa_bzero(depth, n * sizeof(GLfloat)); + _mesa_bzero(depth, n * sizeof(GLuint)); + return; } ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT); |