swrast: stop using Put/GetRow/Values() in swrast code
All color buffer rendering is now done by accessing mapped renderbuffer memory. We're now able to get rid of all the GetRow/PutRow stuff.
This commit is contained in:
@@ -557,6 +557,46 @@ swrast_fast_copy_pixels(struct gl_context *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find/map the renderbuffer that we'll be reading from.
|
||||||
|
* The swrast_render_start() function only maps the drawing buffers,
|
||||||
|
* not the read buffer.
|
||||||
|
*/
|
||||||
|
static struct gl_renderbuffer *
|
||||||
|
map_readbuffer(struct gl_context *ctx, GLenum type)
|
||||||
|
{
|
||||||
|
struct gl_framebuffer *fb = ctx->ReadBuffer;
|
||||||
|
struct gl_renderbuffer *rb;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case GL_COLOR:
|
||||||
|
rb = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
|
||||||
|
break;
|
||||||
|
case GL_DEPTH:
|
||||||
|
case GL_DEPTH_STENCIL:
|
||||||
|
rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
|
||||||
|
break;
|
||||||
|
case GL_STENCIL:
|
||||||
|
rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rb || rb->Map) {
|
||||||
|
/* no buffer, or buffer is mapped already, we're done */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->Driver.MapRenderbuffer(ctx, rb,
|
||||||
|
0, 0, rb->Width, rb->Height,
|
||||||
|
GL_MAP_READ_BIT,
|
||||||
|
&rb->Map, &rb->RowStrideBytes);
|
||||||
|
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do software-based glCopyPixels.
|
* Do software-based glCopyPixels.
|
||||||
* By time we get here, all parameters will have been error-checked.
|
* By time we get here, all parameters will have been error-checked.
|
||||||
@@ -567,6 +607,7 @@ _swrast_CopyPixels( struct gl_context *ctx,
|
|||||||
GLint destx, GLint desty, GLenum type )
|
GLint destx, GLint desty, GLenum type )
|
||||||
{
|
{
|
||||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||||
|
struct gl_renderbuffer *rb;
|
||||||
|
|
||||||
if (!_mesa_check_conditional_render(ctx))
|
if (!_mesa_check_conditional_render(ctx))
|
||||||
return; /* don't copy */
|
return; /* don't copy */
|
||||||
@@ -585,6 +626,7 @@ _swrast_CopyPixels( struct gl_context *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
swrast_render_start(ctx);
|
swrast_render_start(ctx);
|
||||||
|
rb = map_readbuffer(ctx, type);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GL_COLOR:
|
case GL_COLOR:
|
||||||
@@ -606,4 +648,9 @@ _swrast_CopyPixels( struct gl_context *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
swrast_render_finish(ctx);
|
swrast_render_finish(ctx);
|
||||||
|
|
||||||
|
if (rb) {
|
||||||
|
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||||
|
rb->Map = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
#include "main/glheader.h"
|
#include "main/glheader.h"
|
||||||
#include "main/colormac.h"
|
#include "main/colormac.h"
|
||||||
|
#include "main/format_pack.h"
|
||||||
|
#include "main/format_unpack.h"
|
||||||
#include "main/macros.h"
|
#include "main/macros.h"
|
||||||
#include "main/imports.h"
|
#include "main/imports.h"
|
||||||
#include "main/image.h"
|
#include "main/image.h"
|
||||||
@@ -1043,6 +1045,87 @@ shade_texture_span(struct gl_context *ctx, SWspan *span)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Put colors at x/y locations into a renderbuffer */
|
||||||
|
static void
|
||||||
|
put_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
|
GLuint count, const GLint x[], const GLint y[],
|
||||||
|
const void *values, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (mask[i]) {
|
||||||
|
GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]);
|
||||||
|
|
||||||
|
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||||
|
_mesa_pack_ubyte_rgba_row(rb->Format, 1,
|
||||||
|
(const GLubyte (*)[4]) values + i, dst);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(rb->DataType == GL_FLOAT);
|
||||||
|
_mesa_pack_float_rgba_row(rb->Format, count,
|
||||||
|
(const GLfloat (*)[4]) values + i, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Put row of colors into renderbuffer */
|
||||||
|
void
|
||||||
|
_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
|
GLuint count, GLint x, GLint y,
|
||||||
|
const void *values, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
GLubyte *dst = _swrast_pixel_address(rb, x, y);
|
||||||
|
|
||||||
|
if (!mask) {
|
||||||
|
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||||
|
_mesa_pack_ubyte_rgba_row(rb->Format, count,
|
||||||
|
(const GLubyte (*)[4]) values, dst);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(rb->DataType == GL_FLOAT);
|
||||||
|
_mesa_pack_float_rgba_row(rb->Format, count,
|
||||||
|
(const GLfloat (*)[4]) values, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const GLuint bpp = _mesa_get_format_bytes(rb->Format);
|
||||||
|
GLuint i, runLen, runStart;
|
||||||
|
/* We can't pass a 'mask' array to the _mesa_pack_rgba_row() functions
|
||||||
|
* so look for runs where mask=1...
|
||||||
|
*/
|
||||||
|
runLen = 0;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (mask[i]) {
|
||||||
|
if (runLen == 0)
|
||||||
|
runStart = i;
|
||||||
|
runLen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mask[i] || i == count - 1) {
|
||||||
|
/* might be the end of a run of pixels */
|
||||||
|
if (runLen > 0) {
|
||||||
|
if (rb->DataType == GL_UNSIGNED_BYTE) {
|
||||||
|
_mesa_pack_ubyte_rgba_row(rb->Format, runLen,
|
||||||
|
(const GLubyte (*)[4]) values + runStart,
|
||||||
|
dst + runStart * bpp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(rb->DataType == GL_FLOAT);
|
||||||
|
_mesa_pack_float_rgba_row(rb->Format, runLen,
|
||||||
|
(const GLfloat (*)[4]) values + runStart,
|
||||||
|
dst + runStart * bpp);
|
||||||
|
}
|
||||||
|
runLen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply all the per-fragment operations to a span.
|
* Apply all the per-fragment operations to a span.
|
||||||
@@ -1290,17 +1373,15 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
|
|||||||
|
|
||||||
if (span->arrayMask & SPAN_XY) {
|
if (span->arrayMask & SPAN_XY) {
|
||||||
/* array of pixel coords */
|
/* array of pixel coords */
|
||||||
ASSERT(rb->PutValues);
|
put_values(ctx, rb, span->end,
|
||||||
rb->PutValues(ctx, rb, span->end,
|
span->array->x, span->array->y,
|
||||||
span->array->x, span->array->y,
|
span->array->rgba, span->array->mask);
|
||||||
span->array->rgba, span->array->mask);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* horizontal run of pixels */
|
/* horizontal run of pixels */
|
||||||
ASSERT(rb->PutRow);
|
_swrast_put_row(ctx, rb, span->end, span->x, span->y,
|
||||||
rb->PutRow(ctx, rb, span->end, span->x, span->y,
|
span->array->rgba,
|
||||||
span->array->rgba,
|
span->writeAll ? NULL: span->array->mask);
|
||||||
span->writeAll ? NULL: span->array->mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!multiFragOutputs && numBuffers > 1) {
|
if (!multiFragOutputs && numBuffers > 1) {
|
||||||
@@ -1344,6 +1425,8 @@ _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GLint skip, length;
|
GLint skip, length;
|
||||||
|
GLubyte *src;
|
||||||
|
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
/* left edge clipping */
|
/* left edge clipping */
|
||||||
skip = -x;
|
skip = -x;
|
||||||
@@ -1372,7 +1455,6 @@ _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(rb);
|
ASSERT(rb);
|
||||||
ASSERT(rb->GetRow);
|
|
||||||
ASSERT(rb->_BaseFormat == GL_RGBA ||
|
ASSERT(rb->_BaseFormat == GL_RGBA ||
|
||||||
rb->_BaseFormat == GL_RGB ||
|
rb->_BaseFormat == GL_RGB ||
|
||||||
rb->_BaseFormat == GL_RG ||
|
rb->_BaseFormat == GL_RG ||
|
||||||
@@ -1382,70 +1464,69 @@ _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
|
|||||||
rb->_BaseFormat == GL_LUMINANCE_ALPHA ||
|
rb->_BaseFormat == GL_LUMINANCE_ALPHA ||
|
||||||
rb->_BaseFormat == GL_ALPHA);
|
rb->_BaseFormat == GL_ALPHA);
|
||||||
|
|
||||||
if (rb->DataType == dstType) {
|
assert(rb->Map);
|
||||||
rb->GetRow(ctx, rb, length, x + skip, y,
|
|
||||||
(GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType));
|
src = _swrast_pixel_address(rb, x + skip, y);
|
||||||
|
|
||||||
|
if (dstType == GL_UNSIGNED_BYTE) {
|
||||||
|
_mesa_unpack_ubyte_rgba_row(rb->Format, length, src,
|
||||||
|
(GLubyte (*)[4]) rgba + skip);
|
||||||
|
}
|
||||||
|
else if (dstType == GL_FLOAT) {
|
||||||
|
_mesa_unpack_rgba_row(rb->Format, length, src,
|
||||||
|
(GLfloat (*)[4]) rgba + skip);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GLuint temp[MAX_WIDTH * 4];
|
_mesa_problem(ctx, "unexpected type in _swrast_read_rgba_span()");
|
||||||
rb->GetRow(ctx, rb, length, x + skip, y, temp);
|
|
||||||
_mesa_convert_colors(rb->DataType, temp,
|
|
||||||
dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType),
|
|
||||||
length, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
|
* Get colors at x/y positions with clipping.
|
||||||
* reading values outside the buffer bounds.
|
* \param type type of values to return
|
||||||
* We can use this for reading any format/type of renderbuffer.
|
|
||||||
* \param valueSize is the size in bytes of each value (pixel) put into the
|
|
||||||
* values array.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
get_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
get_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
GLuint count, const GLint x[], const GLint y[],
|
GLuint count, const GLint x[], const GLint y[],
|
||||||
void *values, GLuint valueSize)
|
void *values, GLenum type)
|
||||||
{
|
{
|
||||||
GLuint i, inCount = 0, inStart = 0;
|
GLuint i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if (x[i] >= 0 && y[i] >= 0 &&
|
if (x[i] >= 0 && y[i] >= 0 &&
|
||||||
x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
|
x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
|
||||||
/* inside */
|
/* inside */
|
||||||
if (inCount == 0)
|
const GLubyte *src = _swrast_pixel_address(rb, x[i], y[i]);
|
||||||
inStart = i;
|
|
||||||
inCount++;
|
if (type == GL_UNSIGNED_BYTE) {
|
||||||
}
|
_mesa_unpack_ubyte_rgba_row(rb->Format, 1, src,
|
||||||
else {
|
(GLubyte (*)[4]) values + i);
|
||||||
if (inCount > 0) {
|
}
|
||||||
/* read [inStart, inStart + inCount) */
|
else if (type == GL_FLOAT) {
|
||||||
rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
|
_mesa_unpack_rgba_row(rb->Format, 1, src,
|
||||||
(GLubyte *) values + inStart * valueSize);
|
(GLfloat (*)[4]) values + i);
|
||||||
inCount = 0;
|
}
|
||||||
|
else {
|
||||||
|
_mesa_problem(ctx, "unexpected type in get_values()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (inCount > 0) {
|
|
||||||
/* read last values */
|
|
||||||
rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
|
|
||||||
(GLubyte *) values + inStart * valueSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for gl_renderbuffer::GetRow() which does clipping.
|
* Get row of colors with clipping.
|
||||||
* \param valueSize size of each value (pixel) in bytes
|
* \param type type of values to return
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
GLuint count, GLint x, GLint y,
|
GLuint count, GLint x, GLint y,
|
||||||
GLvoid *values, GLuint valueSize)
|
GLvoid *values, GLenum type)
|
||||||
{
|
{
|
||||||
GLint skip = 0;
|
GLint skip = 0;
|
||||||
|
GLubyte *src;
|
||||||
|
|
||||||
if (y < 0 || y >= (GLint) rb->Height)
|
if (y < 0 || y >= (GLint) rb->Height)
|
||||||
return; /* above or below */
|
return; /* above or below */
|
||||||
@@ -1466,7 +1547,19 @@ get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
|||||||
count -= skip;
|
count -= skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);
|
src = _swrast_pixel_address(rb, x, y);
|
||||||
|
|
||||||
|
if (type == GL_UNSIGNED_BYTE) {
|
||||||
|
_mesa_unpack_ubyte_rgba_row(rb->Format, count, src,
|
||||||
|
(GLubyte (*)[4]) values + skip);
|
||||||
|
}
|
||||||
|
else if (type == GL_FLOAT) {
|
||||||
|
_mesa_unpack_rgba_row(rb->Format, count, src,
|
||||||
|
(GLfloat (*)[4]) values + skip);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_mesa_problem(ctx, "unexpected type in get_row()");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1479,7 +1572,6 @@ void *
|
|||||||
_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
SWspan *span)
|
SWspan *span)
|
||||||
{
|
{
|
||||||
const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);
|
|
||||||
void *rbPixels;
|
void *rbPixels;
|
||||||
|
|
||||||
/* Point rbPixels to a temporary space */
|
/* Point rbPixels to a temporary space */
|
||||||
@@ -1488,11 +1580,11 @@ _swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
|||||||
/* Get destination values from renderbuffer */
|
/* Get destination values from renderbuffer */
|
||||||
if (span->arrayMask & SPAN_XY) {
|
if (span->arrayMask & SPAN_XY) {
|
||||||
get_values(ctx, rb, span->end, span->array->x, span->array->y,
|
get_values(ctx, rb, span->end, span->array->x, span->array->y,
|
||||||
rbPixels, pixelSize);
|
rbPixels, span->array->ChanType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
get_row(ctx, rb, span->end, span->x, span->y,
|
get_row(ctx, rb, span->end, span->x, span->y,
|
||||||
rbPixels, pixelSize);
|
rbPixels, span->array->ChanType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rbPixels;
|
return rbPixels;
|
||||||
|
@@ -203,6 +203,11 @@ extern void
|
|||||||
_swrast_read_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
_swrast_read_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
GLuint n, GLint x, GLint y, GLvoid *rgba);
|
GLuint n, GLint x, GLint y, GLvoid *rgba);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
|
GLuint count, GLint x, GLint y,
|
||||||
|
const void *values, const GLubyte *mask);
|
||||||
|
|
||||||
extern void *
|
extern void *
|
||||||
_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
|
||||||
SWspan *span);
|
SWspan *span);
|
||||||
|
@@ -342,14 +342,11 @@ map_attachment(struct gl_context *ctx,
|
|||||||
}
|
}
|
||||||
else if (rb) {
|
else if (rb) {
|
||||||
/* Map ordinary renderbuffer */
|
/* Map ordinary renderbuffer */
|
||||||
/* XXX don't map color buffers yet */
|
|
||||||
if (buffer == BUFFER_DEPTH || buffer == BUFFER_STENCIL) {
|
|
||||||
ctx->Driver.MapRenderbuffer(ctx, rb,
|
ctx->Driver.MapRenderbuffer(ctx, rb,
|
||||||
0, 0, rb->Width, rb->Height,
|
0, 0, rb->Width, rb->Height,
|
||||||
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
|
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
|
||||||
&rb->Map, &rb->RowStrideBytes);
|
&rb->Map, &rb->RowStrideBytes);
|
||||||
assert(rb->Map);
|
assert(rb->Map);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,10 +370,7 @@ unmap_attachment(struct gl_context *ctx,
|
|||||||
}
|
}
|
||||||
else if (rb) {
|
else if (rb) {
|
||||||
/* unmap ordinary renderbuffer */
|
/* unmap ordinary renderbuffer */
|
||||||
/* XXX don't map color buffers yet */
|
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||||
if (buffer == BUFFER_DEPTH || buffer == BUFFER_STENCIL) {
|
|
||||||
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rb->Map = NULL;
|
rb->Map = NULL;
|
||||||
|
@@ -157,7 +157,7 @@ _swrast_culltriangle( struct gl_context *ctx,
|
|||||||
span.intTex[0] += span.intTexStep[0]; \
|
span.intTex[0] += span.intTexStep[0]; \
|
||||||
span.intTex[1] += span.intTexStep[1]; \
|
span.intTex[1] += span.intTexStep[1]; \
|
||||||
} \
|
} \
|
||||||
rb->PutRow(ctx, rb, span.end, span.x, span.y, rgba, NULL);
|
_swrast_put_row(ctx, rb, span.end, span.x, span.y, rgba, NULL);
|
||||||
|
|
||||||
#include "s_tritemp.h"
|
#include "s_tritemp.h"
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ _swrast_culltriangle( struct gl_context *ctx,
|
|||||||
span.intTex[1] += span.intTexStep[1]; \
|
span.intTex[1] += span.intTexStep[1]; \
|
||||||
span.z += span.zStep; \
|
span.z += span.zStep; \
|
||||||
} \
|
} \
|
||||||
rb->PutRow(ctx, rb, span.end, span.x, span.y, rgba, span.array->mask);
|
_swrast_put_row(ctx, rb, span.end, span.x, span.y, rgba, span.array->mask);
|
||||||
|
|
||||||
#include "s_tritemp.h"
|
#include "s_tritemp.h"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user