Use _swrast_get_values() which does clipping.
/* Read span of current frame buffer pixels */
if (span->arrayMask & SPAN_XY) {
/* array of x/y pixel coords */
- rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y,
- framebuffer);
+ _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
+ framebuffer, 4 * sizeof(GLchan));
}
else {
/* horizontal run of pixels */
#include "s_depth.h"
#include "s_context.h"
+#include "s_span.h"
/**
/* read depth values from buffer, test, write back */
if (rb->DataType == GL_UNSIGNED_SHORT) {
GLushort zbuffer[MAX_WIDTH];
- rb->GetValues(ctx, rb, count, x, y, zbuffer);
+ _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort));
depth_test_span16(ctx, count, zbuffer, z, mask );
rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
}
else {
GLuint zbuffer[MAX_WIDTH];
ASSERT(rb->DataType == GL_UNSIGNED_INT);
- rb->GetValues(ctx, rb, count, x, y, zbuffer);
+ _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint));
depth_test_span32(ctx, count, zbuffer, z, mask );
rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
}
/* get 16-bit values */
GLushort zbuffer16[MAX_WIDTH], *zbuffer;
if (span->arrayMask & SPAN_XY) {
- rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer16);
+ _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
+ zbuffer16, sizeof(GLushort));
zbuffer = zbuffer16;
}
else {
/* get 32-bit values */
GLuint zbuffer32[MAX_WIDTH], *zbuffer;
if (span->arrayMask & SPAN_XY) {
- rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer32);
+ _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
+ zbuffer32, sizeof(GLuint));
zbuffer = zbuffer32;
}
else {
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
_swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span );
-extern void
-_swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb,
- GLint n, GLint x, GLint y, GLuint depth[] );
-
-
extern void
_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
GLint n, GLint x, GLint y, GLfloat depth[] );
/* Read dest values from frame buffer */
if (span->arrayMask & SPAN_XY) {
- rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, dest);
+ _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
+ dest, sizeof(GLuint));
}
else {
rb->GetRow(ctx, rb, span->end, span->x, span->y, dest);
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
if (span->arrayMask & SPAN_XY) {
- rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, dest);
+ _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
+ dest, 4 * sizeof(GLchan));
}
else {
_swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, dest);
ASSERT(span->arrayMask & SPAN_RGBA);
if (span->arrayMask & SPAN_XY) {
- rb->GetValues(ctx, rb, n, span->array->x, span->array->y, dest);
+ _swrast_get_values(ctx, rb, n, span->array->x, span->array->y,
+ dest, 4 * sizeof(GLchan));
}
else {
_swrast_read_rgba_span(ctx, rb, n, span->x, span->y, dest);
GLuint i;
ASSERT(span->arrayMask & SPAN_INDEX);
- ASSERT(span->end < MAX_WIDTH);
+ ASSERT(span->end <= MAX_WIDTH);
ASSERT(rb->DataType == GL_UNSIGNED_INT);
if (span->arrayMask & SPAN_XY) {
- rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, dest);
+ _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
+ dest, sizeof(GLuint));
}
else {
_swrast_read_index_span(ctx, rb, span->end, span->x, span->y, dest);
}
}
}
+
+
+/**
+ * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
+ * reading values outside the buffer bounds.
+ * We can use this for reading any format/type of renderbuffer.
+ * \param valueSize is the size in bytes of each value put into the
+ * values array.
+ */
+void
+_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ void *values, GLuint valueSize)
+{
+ GLuint i, inCount = 0, inStart = 0;
+
+ for (i = 0; i < count; i++) {
+ if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) {
+ /* inside */
+ if (inCount == 0)
+ inStart = i;
+ inCount++;
+ }
+ else {
+ if (inCount > 0) {
+ /* read [inStart, inStart + inCount) */
+ rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
+ (GLubyte *) values + inStart * valueSize);
+ inCount = 0;
+ }
+ }
+ }
+ if (inCount > 0) {
+ /* read last values */
+ rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
+ (GLubyte *) values + inStart * valueSize);
+ }
+}
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y, GLuint indx[] );
+extern void
+_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ void *values, GLuint valueSize);
+
#endif
#include "s_context.h"
#include "s_depth.h"
#include "s_stencil.h"
+#include "s_span.h"
GLuint i;
/* save the current mask bits */
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
+ _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte));
/* apply the depth test */
_swrast_depth_test_span(ctx, span);
GLstencil stencil[MAX_WIDTH];
GLubyte origMask[MAX_WIDTH];
- rb->GetValues(ctx, rb, n, x, y, stencil);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ _swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte));
- MEMCPY(origMask, mask, n * sizeof(GLubyte));
+ _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
(void) do_stencil_test(ctx, face, n, stencil, mask);
GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
GLuint i;
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
+ _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte));
_swrast_depth_test_span(ctx, span);