summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Hähnle <nhaehnle@gmail.com>2009-10-07 20:39:22 +0200
committerNicolai Hähnle <nhaehnle@gmail.com>2009-10-07 20:39:22 +0200
commit5b4c0b864a25fa193e7ba828cf5ce483ca05bd4e (patch)
treef462528c24889bee0665451e9e32664ecf2add3c
parent3f5a316f36e2d376104640033c8bcefef3810ef4 (diff)
parent9fde81bb20bbfd2f8da80749cb84d890843a7bc2 (diff)
Merge branch 'mesa_7_6_branch'
-rw-r--r--docs/relnotes-7.6.1.html1
-rw-r--r--progs/tests/random.c2
-rw-r--r--progs/xdemos/pbdemo.c17
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c46
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h7
-rw-r--r--src/mesa/drivers/x11/fakeglx.c45
-rw-r--r--src/mesa/drivers/x11/xmesaP.h3
-rw-r--r--src/mesa/shader/shader_api.c31
-rw-r--r--src/mesa/swrast/s_depth.c4
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);