blob: 933f62c96c7f6eaaaa7a3a9b7c6f6f2b174889bf [file] [log] [blame]
/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_span.c,v 1.4 2002/11/05 17:46:07 tsi Exp $ */
#include "gamma_context.h"
#include "gamma_lock.h"
#include "colormac.h"
#include "swrast/swrast.h"
#define DBG 0
#define LOCAL_VARS \
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); \
gammaScreenPtr gammascrn = gmesa->gammaScreen; \
__DRIscreenPrivate *sPriv = gmesa->driScreen; \
__DRIdrawablePrivate *dPriv = gmesa->driDrawable; \
GLuint pitch = sPriv->fbWidth * gammascrn->cpp; \
GLuint height = dPriv->h; \
char *buf = (char *)(sPriv->pFB + \
gmesa->drawOffset + \
(dPriv->x * gammascrn->cpp) + \
(dPriv->y * pitch)); \
GLuint p; \
(void) buf; (void) p
/* FIXME! Depth/Stencil read/writes don't work ! */
#define LOCAL_DEPTH_VARS \
gammaScreenPtr gammascrn = gmesa->gammaScreen; \
__DRIdrawablePrivate *dPriv = gmesa->driDrawable; \
__DRIscreenPrivate *sPriv = gmesa->driScreen; \
GLuint pitch = gammascrn->depthPitch; \
GLuint height = dPriv->h; \
char *buf = (char *)(sPriv->pFB + \
gammascrn->depthOffset + \
dPriv->x * gammascrn->cpp + \
dPriv->y * pitch)
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
#define Y_FLIP( _y ) (height - _y - 1)
#define HW_LOCK() \
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); \
FLUSH_DMA_BUFFER(gmesa); \
gammaGetLock( gmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); \
GAMMAHW_LOCK( gmesa );
#define HW_UNLOCK() GAMMAHW_UNLOCK( gmesa )
/* ================================================================
* Color buffer
*/
/* 16 bit, RGB565 color spanline and pixel functions
*/
#define INIT_MONO_PIXEL(p, color) \
p = PACK_COLOR_565( color[0], color[1], color[2] )
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
(((int)g & 0xfc) << 3) | \
(((int)b & 0xf8) >> 3))
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
rgba[0] = (p >> 8) & 0xf8; \
rgba[1] = (p >> 3) & 0xfc; \
rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 0xff; \
if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \
} while (0)
#define TAG(x) gamma##x##_RGB565
#include "spantmp.h"
/* 32 bit, ARGB8888 color spanline and pixel functions
*/
#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p, color) \
p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
(g << 8) | \
(r << 16) | \
(a << 24) )
#define WRITE_PIXEL( _x, _y, p ) \
*(GLuint *)(buf + _x*4 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
rgba[0] = (p >> 16) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 0) & 0xff; \
rgba[3] = (p >> 24) & 0xff; \
} while (0)
#define TAG(x) gamma##x##_ARGB8888
#include "spantmp.h"
/* 16 bit depthbuffer functions.
*/
#define VALUE_TYPE GLushort
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
#define TAG(x) gamma##x##_16
#include "depthtmp.h"
#if 0 /* Unused */
/* 32 bit depthbuffer functions.
*/
#define VALUE_TYPE GLuint
#define WRITE_DEPTH( _x, _y, d ) \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch);
#define TAG(x) gamma##x##_32
#include "depthtmp.h"
#endif
/* 24/8 bit interleaved depth/stencil functions
*/
#define VALUE_TYPE GLuint
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xff; \
tmp |= (d) & 0xffffff00; \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
}
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & ~0xff;
#define TAG(x) gamma##x##_24_8
#include "depthtmp.h"
#if 0
#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
tmp &= 0xffffff00; \
tmp |= d & 0xff; \
*(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
}
#define READ_STENCIL( d, _x, _y ) \
d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
#define TAG(x) gamma##x##_24_8
#include "stenciltmp.h"
static void gammaReadRGBASpan8888( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4])
{
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
gammaScreenPtr gammascrn = gmesa->gammaScreen;
u_int32_t dwords1, dwords2, i = 0;
char *src = (char *)rgba[0];
GLuint read = n * gammascrn->cpp; /* Number of bytes we are expecting */
u_int32_t data;
FLUSH_DMA_BUFFER(gmesa);
CHECK_DMA_BUFFER(gmesa, 16);
WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode & ~(LBReadSrcEnable | LBReadDstEnable));
WRITE(gmesa->buf, ColorDDAMode, ColorDDAEnable);
WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);
WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode & ~FBReadSrcEnable) | FBReadDstEnable | FBDataTypeColor);
WRITE(gmesa->buf, FilterMode, 0x200); /* Pass FBColorData */
WRITE(gmesa->buf, FBWriteMode, FBW_UploadColorData | FBWriteModeDisable);
WRITE(gmesa->buf, StartXSub, (x+n)<<16);
WRITE(gmesa->buf, StartXDom, x<<16);
WRITE(gmesa->buf, StartY, y<<16);
WRITE(gmesa->buf, GLINTCount, 1);
WRITE(gmesa->buf, dXDom, 0<<16);
WRITE(gmesa->buf, dXSub, 0<<16);
WRITE(gmesa->buf, dY, 1<<16);
WRITE(gmesa->buf, Render, PrimitiveTrapezoid);
FLUSH_DMA_BUFFER(gmesa);
moredata:
dwords1 = *(volatile u_int32_t*)(void *)(((u_int8_t*)gammascrn->regions[0].map) + (GlintOutFIFOWords));
dwords2 = *(volatile u_int32_t*)(void *)(((u_int8_t*)gammascrn->regions[2].map) + (GlintOutFIFOWords));
if (dwords1) {
memcpy(src, (char*)gammascrn->regions[1].map + 0x1000, dwords1 << 2);
src += dwords1 << 2;
read -= dwords1 << 2;
}
if (dwords2) {
memcpy(src, (char*)gammascrn->regions[3].map + 0x1000, dwords2 << 2);
src += dwords2 << 2;
read -= dwords2 << 2;
}
if (read)
goto moredata;
done:
CHECK_DMA_BUFFER(gmesa, 6);
WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode);
WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
WRITE(gmesa->buf, FilterMode, 0x400);
}
#endif
static void gammaSetBuffer( GLcontext *ctx,
GLframebuffer *colorBuffer,
GLuint bufferBit )
{
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
switch ( bufferBit ) {
case BUFFER_BIT_FRONT_LEFT:
gmesa->readOffset = 0;
break;
case BUFFER_BIT_BACK_LEFT:
gmesa->readOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp;
break;
default:
_mesa_problem(ctx, "Unexpected buffer 0x%x in gammaSetBuffer()", bufferBit);
}
}
void gammaDDInitSpanFuncs( GLcontext *ctx )
{
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
swdd->SetBuffer = gammaSetBuffer;
switch ( gmesa->gammaScreen->cpp ) {
case 2:
swdd->WriteRGBASpan = gammaWriteRGBASpan_RGB565;
swdd->WriteRGBSpan = gammaWriteRGBSpan_RGB565;
swdd->WriteMonoRGBASpan = gammaWriteMonoRGBASpan_RGB565;
swdd->WriteRGBAPixels = gammaWriteRGBAPixels_RGB565;
swdd->WriteMonoRGBAPixels = gammaWriteMonoRGBAPixels_RGB565;
swdd->ReadRGBASpan = gammaReadRGBASpan_RGB565;
swdd->ReadRGBAPixels = gammaReadRGBAPixels_RGB565;
break;
case 4:
swdd->WriteRGBASpan = gammaWriteRGBASpan_ARGB8888;
swdd->WriteRGBSpan = gammaWriteRGBSpan_ARGB8888;
swdd->WriteMonoRGBASpan = gammaWriteMonoRGBASpan_ARGB8888;
swdd->WriteRGBAPixels = gammaWriteRGBAPixels_ARGB8888;
swdd->WriteMonoRGBAPixels = gammaWriteMonoRGBAPixels_ARGB8888;
#if 1
swdd->ReadRGBASpan = gammaReadRGBASpan_ARGB8888;
#else
swdd->ReadRGBASpan = gammaReadRGBASpan8888;
#endif
swdd->ReadRGBAPixels = gammaReadRGBAPixels_ARGB8888;
break;
default:
break;
}
switch ( gmesa->glCtx->Visual.depthBits ) {
case 16:
swdd->ReadDepthSpan = gammaReadDepthSpan_16;
swdd->WriteDepthSpan = gammaWriteDepthSpan_16;
swdd->ReadDepthPixels = gammaReadDepthPixels_16;
swdd->WriteDepthPixels = gammaWriteDepthPixels_16;
break;
case 24:
swdd->ReadDepthSpan = gammaReadDepthSpan_24_8;
swdd->WriteDepthSpan = gammaWriteDepthSpan_24_8;
swdd->ReadDepthPixels = gammaReadDepthPixels_24_8;
swdd->WriteDepthPixels = gammaWriteDepthPixels_24_8;
#if 0
swdd->ReadStencilSpan = gammaReadStencilSpan_24_8;
swdd->WriteStencilSpan = gammaWriteStencilSpan_24_8;
swdd->ReadStencilPixels = gammaReadStencilPixels_24_8;
swdd->WriteStencilPixels = gammaWriteStencilPixels_24_8;
#endif
break;
default:
break;
}
}