diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-01-22 03:34:14 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-01-22 03:34:14 +0000 |
commit | 6bfaf4e0b6bafba31fc6476c7dbbd4ed706020b9 (patch) | |
tree | f394dda45182f5f957250585f2ac691ed215045e /lib/mesa | |
parent | 3ea0fb060bacfa7a2f0555c9905b40cc71655840 (diff) |
fix some things which got broken in merge
Diffstat (limited to 'lib/mesa')
32 files changed, 10523 insertions, 38 deletions
diff --git a/lib/mesa/m4/.gitignore b/lib/mesa/m4/.gitignore index 702496c41..38066ddf7 100644 --- a/lib/mesa/m4/.gitignore +++ b/lib/mesa/m4/.gitignore @@ -3,8 +3,3 @@ ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4 -libtool.m4 -ltoptions.m4 -ltsugar.m4 -ltversion.m4 -lt~obsolete.m4 diff --git a/lib/mesa/src/gallium/winsys/panfrost/drm/Makefile.am b/lib/mesa/src/gallium/winsys/panfrost/drm/Makefile.am index a0047b3a8..7a836288b 100644 --- a/lib/mesa/src/gallium/winsys/panfrost/drm/Makefile.am +++ b/lib/mesa/src/gallium/winsys/panfrost/drm/Makefile.am @@ -31,36 +31,3 @@ noinst_LTLIBRARIES = libpanfrostdrm.la libpanfrostdrm_la_SOURCES = $(C_SOURCES) EXTRA_DIST = meson.build -# Copyright © 2014 Broadco -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -include Makefile.sources -include $(top_srcdir)/src/gallium/Automake.inc - -AM_CFLAGS = \ - -I$(top_srcdir)/src/gallium/drivers \ - $(GALLIUM_WINSYS_CFLAGS) - -noinst_LTLIBRARIES = libpanfrostdrm.la - -libpanfrostdrm_la_SOURCES = $(C_SOURCES) - -EXTRA_DIST = meson.build diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_buffer_objects.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_buffer_objects.c new file mode 100644 index 000000000..2b76305dd --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_buffer_objects.c @@ -0,0 +1,238 @@ +/* + * Copyright 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "main/imports.h" +#include "main/mtypes.h" +#include "main/bufferobj.h" + +#include "radeon_common.h" +#include "radeon_buffer_objects.h" + +struct radeon_buffer_object * +get_radeon_buffer_object(struct gl_buffer_object *obj) +{ + return (struct radeon_buffer_object *) obj; +} + +static struct gl_buffer_object * +radeonNewBufferObject(struct gl_context * ctx, + GLuint name) +{ + struct radeon_buffer_object *obj = CALLOC_STRUCT(radeon_buffer_object); + + _mesa_initialize_buffer_object(ctx, &obj->Base, name); + + obj->bo = NULL; + + return &obj->Base; +} + +/** + * Called via glDeleteBuffersARB(). + */ +static void +radeonDeleteBufferObject(struct gl_context * ctx, + struct gl_buffer_object *obj) +{ + struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + int i; + + for (i = 0; i < MAP_COUNT; i++) { + if (obj->Mappings[i].Pointer) { + radeon_bo_unmap(radeon_obj->bo); + } + } + + if (radeon_obj->bo) { + radeon_bo_unref(radeon_obj->bo); + } + + _mesa_delete_buffer_object(ctx, obj); +} + + +/** + * Allocate space for and store data in a buffer object. Any data that was + * previously stored in the buffer object is lost. If data is NULL, + * memory will be allocated, but no copy will occur. + * Called via ctx->Driver.BufferData(). + * \return GL_TRUE for success, GL_FALSE if out of memory + */ +static GLboolean +radeonBufferData(struct gl_context * ctx, + GLenum target, + GLsizeiptrARB size, + const GLvoid * data, + GLenum usage, + GLbitfield storageFlags, + struct gl_buffer_object *obj) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + + radeon_obj->Base.Size = size; + radeon_obj->Base.Usage = usage; + radeon_obj->Base.StorageFlags = storageFlags; + + if (radeon_obj->bo != NULL) { + radeon_bo_unref(radeon_obj->bo); + radeon_obj->bo = NULL; + } + + if (size != 0) { + radeon_obj->bo = radeon_bo_open(radeon->radeonScreen->bom, + 0, + size, + ctx->Const.MinMapBufferAlignment, + RADEON_GEM_DOMAIN_GTT, + 0); + + if (!radeon_obj->bo) + return GL_FALSE; + + if (data != NULL) { + radeon_bo_map(radeon_obj->bo, GL_TRUE); + + memcpy(radeon_obj->bo->ptr, data, size); + + radeon_bo_unmap(radeon_obj->bo); + } + } + return GL_TRUE; +} + +/** + * Replace data in a subrange of buffer object. If the data range + * specified by size + offset extends beyond the end of the buffer or + * if data is NULL, no copy is performed. + * Called via glBufferSubDataARB(). + */ +static void +radeonBufferSubData(struct gl_context * ctx, + GLintptrARB offset, + GLsizeiptrARB size, + const GLvoid * data, + struct gl_buffer_object *obj) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + + if (radeon_bo_is_referenced_by_cs(radeon_obj->bo, radeon->cmdbuf.cs)) { + radeon_firevertices(radeon); + } + + radeon_bo_map(radeon_obj->bo, GL_TRUE); + + memcpy(radeon_obj->bo->ptr + offset, data, size); + + radeon_bo_unmap(radeon_obj->bo); +} + +/** + * Called via glGetBufferSubDataARB() + */ +static void +radeonGetBufferSubData(struct gl_context * ctx, + GLintptrARB offset, + GLsizeiptrARB size, + GLvoid * data, + struct gl_buffer_object *obj) +{ + struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + + radeon_bo_map(radeon_obj->bo, GL_FALSE); + + memcpy(data, radeon_obj->bo->ptr + offset, size); + + radeon_bo_unmap(radeon_obj->bo); +} + +/** + * Called via glMapBuffer() and glMapBufferRange() + */ +static void * +radeonMapBufferRange(struct gl_context * ctx, + GLintptr offset, GLsizeiptr length, + GLbitfield access, struct gl_buffer_object *obj, + gl_map_buffer_index index) +{ + struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + const GLboolean write_only = + (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == GL_MAP_WRITE_BIT; + + if (write_only) { + ctx->Driver.Flush(ctx); + } + + if (radeon_obj->bo == NULL) { + obj->Mappings[index].Pointer = NULL; + return NULL; + } + + obj->Mappings[index].Offset = offset; + obj->Mappings[index].Length = length; + obj->Mappings[index].AccessFlags = access; + + radeon_bo_map(radeon_obj->bo, write_only); + + obj->Mappings[index].Pointer = radeon_obj->bo->ptr + offset; + return obj->Mappings[index].Pointer; +} + + +/** + * Called via glUnmapBufferARB() + */ +static GLboolean +radeonUnmapBuffer(struct gl_context * ctx, + struct gl_buffer_object *obj, + gl_map_buffer_index index) +{ + struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + + if (radeon_obj->bo != NULL) { + radeon_bo_unmap(radeon_obj->bo); + } + + obj->Mappings[index].Pointer = NULL; + obj->Mappings[index].Offset = 0; + obj->Mappings[index].Length = 0; + + return GL_TRUE; +} + +void +radeonInitBufferObjectFuncs(struct dd_function_table *functions) +{ + functions->NewBufferObject = radeonNewBufferObject; + functions->DeleteBuffer = radeonDeleteBufferObject; + functions->BufferData = radeonBufferData; + functions->BufferSubData = radeonBufferSubData; + functions->GetBufferSubData = radeonGetBufferSubData; + functions->MapBufferRange = radeonMapBufferRange; + functions->UnmapBuffer = radeonUnmapBuffer; +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_buffer_objects.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_buffer_objects.h new file mode 100644 index 000000000..d68196082 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_buffer_objects.h @@ -0,0 +1,52 @@ +/* + * Copyright 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_BUFFER_OBJECTS_H +#define RADEON_BUFFER_OBJECTS_H + +#include "main/mtypes.h" + +struct radeon_bo; + +/** + * Radeon vertex/pixel buffer object, derived from Mesa's gl_buffer_object. + */ +struct radeon_buffer_object +{ + struct gl_buffer_object Base; + struct radeon_bo *bo; +}; + +struct radeon_buffer_object * +get_radeon_buffer_object(struct gl_buffer_object *obj); + +/** + * Hook the bufferobject implementation into mesa: + */ +void radeonInitBufferObjectFuncs(struct dd_function_table *functions); + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_chipset.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_chipset.h new file mode 100644 index 000000000..023c12c79 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_chipset.h @@ -0,0 +1,41 @@ +#ifndef _RADEON_CHIPSET_H +#define _RADEON_CHIPSET_H + +/* General chip classes: + * r100 includes R100, RV100, RV200, RS100, RS200, RS250. + * r200 includes R200, RV250, RV280, RS300. + * (RS* denotes IGP) + */ + +enum { +#define CHIPSET(id, name, family) PCI_CHIP_##name = id, +#if defined(RADEON_R100) +#include "pci_ids/radeon_pci_ids.h" +#elif defined(RADEON_R200) +#include "pci_ids/r200_pci_ids.h" +#endif +#undef CHIPSET +}; + +enum { +#if defined(RADEON_R100) + CHIP_FAMILY_R100, + CHIP_FAMILY_RV100, + CHIP_FAMILY_RS100, + CHIP_FAMILY_RV200, + CHIP_FAMILY_RS200, +#elif defined(RADEON_R200) + CHIP_FAMILY_R200, + CHIP_FAMILY_RV250, + CHIP_FAMILY_RS300, + CHIP_FAMILY_RV280, +#endif + CHIP_FAMILY_LAST +}; + +#define RADEON_CHIPSET_TCL (1 << 0) /* tcl support - any radeon */ +#define RADEON_CHIPSET_BROKEN_STENCIL (1 << 1) /* r100 stencil bug */ +#define R200_CHIPSET_YCBCR_BROKEN (1 << 2) /* r200 ycbcr bug */ +#define RADEON_CHIPSET_DEPTH_ALWAYS_TILED (1 << 3) /* M7 and R200s */ + +#endif /* _RADEON_CHIPSET_H */ diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_cmdbuf.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_cmdbuf.h new file mode 100644 index 000000000..da179a7e3 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_cmdbuf.h @@ -0,0 +1,107 @@ +#ifndef COMMON_CMDBUF_H +#define COMMON_CMDBUF_H + +GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); +void rcommonInitCmdBuf(radeonContextPtr rmesa); +void rcommonDestroyCmdBuf(radeonContextPtr rmesa); + +void rcommonBeginBatch(radeonContextPtr rmesa, + int n, + const char *file, + const char *function, + int line); + +/* +r6/r7 : code here moved */ + +#define CP_PACKET2 (2 << 30) +#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) +#define CP_PACKET0_ONE(reg, n) (RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2)) +#define CP_PACKET3(pkt, n) (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + +/** + * Every function writing to the command buffer needs to declare this + * to get the necessary local variables. + */ +#define BATCH_LOCALS(rmesa) \ + const radeonContextPtr b_l_rmesa = rmesa + +/** + * Prepare writing n dwords to the command buffer. Does not cause automatic + * state emits. + */ +#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, __FILE__, __func__, __LINE__) + +/** + * Write one dword to the command buffer. + */ +#define OUT_BATCH(data) \ + do { \ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\ + } while(0) + +/** + * Write a relocated dword to the command buffer. + */ +#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ + do { \ + int __offset = (offset); \ + if (0 && __offset) { \ + fprintf(stderr, "(%s:%s:%d) offset : %d\n", \ + __FILE__, __func__, __LINE__, __offset); \ + } \ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, __offset); \ + radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \ + bo, rd, wd, flags); \ + } while(0) + + +/** + * Write n dwords from ptr to the command buffer. + */ +#define OUT_BATCH_TABLE(ptr,n) \ + do { \ + radeon_cs_write_table(b_l_rmesa->cmdbuf.cs, (ptr), (n));\ + } while(0) + +/** + * Finish writing dwords to the command buffer. + * The number of (direct or indirect) OUT_BATCH calls between the previous + * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. + */ +#define END_BATCH() \ + do { \ + radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __func__, __LINE__);\ + } while(0) + +/** + * After the last END_BATCH() of rendering, this indicates that flushing + * the command buffer now is okay. + */ +#define COMMIT_BATCH() \ + do { \ + } while(0) + + +/** Single register write to command buffer; requires 2 dwords. */ +#define OUT_BATCH_REGVAL(reg, val) \ + OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \ + OUT_BATCH((val)) + +/** Continuous register range write to command buffer; requires 1 dword, + * expects count dwords afterwards for register contents. */ +#define OUT_BATCH_REGSEQ(reg, count) \ + OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count))) + +/* +r6/r7 : code here moved */ + +/* Fire the buffered vertices no matter what. + */ +static inline void radeon_firevertices(radeonContextPtr radeon) +{ + if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) + radeon->glCtx.Driver.Flush(&radeon->glCtx); /* +r6/r7 */ +} + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.c new file mode 100644 index 000000000..a3bf00b09 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.c @@ -0,0 +1,727 @@ +/************************************************************************** + +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + +/* + - Scissor implementation + - buffer swap/copy ioctls + - finish/flush + - state emission + - cmdbuffer management +*/ + +#include <errno.h> +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/enums.h" +#include "main/fbobject.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "drivers/common/meta.h" + +#include "radeon_common.h" +#include "radeon_drm.h" +#include "radeon_queryobj.h" + +/** + * Enable verbose debug output for emit code. + * 0 no output + * 1 most output + * 2 also print state alues + */ +#define RADEON_CMDBUF 0 + +/* ============================================================= + * Scissoring + */ + +/** + * Update cliprects and scissors. + */ +void radeonSetCliprects(radeonContextPtr radeon) +{ + __DRIdrawable *const drawable = radeon_get_drawable(radeon); + __DRIdrawable *const readable = radeon_get_readable(radeon); + + if(drawable == NULL && readable == NULL) + return; + + struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate; + struct radeon_framebuffer *const read_rfb = readable->driverPrivate; + + if ((draw_rfb->base.Width != drawable->w) || + (draw_rfb->base.Height != drawable->h)) { + _mesa_resize_framebuffer(&radeon->glCtx, &draw_rfb->base, + drawable->w, drawable->h); + } + + if (drawable != readable) { + if ((read_rfb->base.Width != readable->w) || + (read_rfb->base.Height != readable->h)) { + _mesa_resize_framebuffer(&radeon->glCtx, &read_rfb->base, + readable->w, readable->h); + } + } + + if (radeon->state.scissor.enabled) + radeonUpdateScissor(&radeon->glCtx); + +} + + + +void radeonUpdateScissor( struct gl_context *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint x = ctx->Scissor.ScissorArray[0].X, y = ctx->Scissor.ScissorArray[0].Y; + GLsizei w = ctx->Scissor.ScissorArray[0].Width, h = ctx->Scissor.ScissorArray[0].Height; + int x1, y1, x2, y2; + int min_x, min_y, max_x, max_y; + + if (!ctx->DrawBuffer) + return; + min_x = min_y = 0; + max_x = ctx->DrawBuffer->Width - 1; + max_y = ctx->DrawBuffer->Height - 1; + + if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + } else { + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + + } + + rmesa->state.scissor.rect.x1 = CLAMP(x1, min_x, max_x); + rmesa->state.scissor.rect.y1 = CLAMP(y1, min_y, max_y); + rmesa->state.scissor.rect.x2 = CLAMP(x2, min_x, max_x); + rmesa->state.scissor.rect.y2 = CLAMP(y2, min_y, max_y); + + if (rmesa->vtbl.update_scissor) + rmesa->vtbl.update_scissor(ctx); +} + +/* ============================================================= + * Scissoring + */ + +void radeonScissor(struct gl_context *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (ctx->Scissor.EnableFlags) { + /* We don't pipeline cliprect changes */ + radeon_firevertices(radeon); + radeonUpdateScissor(ctx); + } +} + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +uint32_t radeonGetAge(radeonContextPtr radeon) +{ + drm_radeon_getparam_t gp; + int ret; + uint32_t age; + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&age; + ret = drmCommandWriteRead(radeon->radeonScreen->driScreen->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __func__, + ret); + exit(1); + } + + return age; +} + +void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL, + *rrbColor = NULL; + uint32_t offset = 0; + + + if (!fb) { + /* this can happen during the initial context initialization */ + return; + } + + /* radeons only handle 1 color draw so far */ + if (fb->_NumColorDrawBuffers != 1) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); + return; + } + + /* Do this here, note core Mesa, since this function is called from + * many places within the driver. + */ + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ + _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer); + } + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + /* this may occur when we're called by glBindFrameBuffer() during + * the process of someone setting up renderbuffers, etc. + */ + /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ + return; + } + + if (fb->Name) { + ;/* do something depthy/stencily TODO */ + } + + /* none */ + if (fb->Name == 0) { + if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + radeon->front_cliprects = GL_TRUE; + } else { + rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + radeon->front_cliprects = GL_FALSE; + } + } else { + /* user FBO in theory */ + struct radeon_renderbuffer *rrb; + rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]); + if (rrb) { + offset = rrb->draw_offset; + rrbColor = rrb; + } + } + + if (rrbColor == NULL) + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); + else + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); + + + if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) { + rrbDepth = radeon_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); + if (rrbDepth && rrbDepth->bo) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE); + } + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); + rrbDepth = NULL; + } + + if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) { + rrbStencil = radeon_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer); + if (rrbStencil && rrbStencil->bo) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + if (!rrbDepth) + rrbDepth = rrbStencil; + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); + if (ctx->Driver.Enable != NULL) + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + else + ctx->NewState |= _NEW_STENCIL; + } + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; + + /* + * Update depth test state + */ + if (ctx->Driver.Enable) { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, + (ctx->Depth.Test && fb->Visual.depthBits > 0)); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, + (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); + } else { + ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); + } + + _mesa_reference_renderbuffer(&radeon->state.depth.rb, &rrbDepth->base.Base); + _mesa_reference_renderbuffer(&radeon->state.color.rb, &rrbColor->base.Base); + radeon->state.color.draw_offset = offset; + + ctx->NewState |= _NEW_VIEWPORT; + + /* Set state we know depends on drawable parameters: + */ + radeonUpdateScissor(ctx); + radeon->NewGLState |= _NEW_SCISSOR; + + if (ctx->Driver.DepthRange) + ctx->Driver.DepthRange(ctx); + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; +} + +/** + * Called via glDrawBuffer. + */ +void radeonDrawBuffer(struct gl_context *ctx) +{ + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "%s\n", __func__); + + if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer)) { + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + /* If we might be front-buffer rendering on this buffer for + * the first time, invalidate our DRI drawable so we'll ask + * for new buffers (including the fake front) before we start + * rendering again. + */ + radeon_update_renderbuffers(radeon->driContext, + radeon->driContext->driDrawablePriv, + GL_FALSE); + } + + radeon_draw_buffer(ctx, ctx->DrawBuffer); +} + +void radeonReadBuffer( struct gl_context *ctx, GLenum mode ) +{ + if (_mesa_is_front_buffer_reading(ctx->ReadBuffer)) { + struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); + radeon_update_renderbuffers(rmesa->driContext, + rmesa->driContext->driReadablePriv, GL_FALSE); + } + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ + if (ctx->ReadBuffer == ctx->DrawBuffer) { + /* This will update FBO completeness status. + * A framebuffer will be incomplete if the GL_READ_BUFFER setting + * refers to a missing renderbuffer. Calling glReadBuffer can set + * that straight and can make the drawing buffer complete. + */ + radeon_draw_buffer(ctx, ctx->DrawBuffer); + } +} + +void radeon_window_moved(radeonContextPtr radeon) +{ + /* Cliprects has to be updated before doing anything else */ + radeonSetCliprects(radeon); +} + +void radeon_viewport(struct gl_context *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + __DRIcontext *driContext = radeon->driContext; + void (*old_viewport)(struct gl_context *ctx); + + if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { + if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer)) { + ctx->Driver.Flush(ctx); + } + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv, GL_FALSE); + if (driContext->driDrawablePriv != driContext->driReadablePriv) + radeon_update_renderbuffers(driContext, driContext->driReadablePriv, GL_FALSE); + } + + old_viewport = ctx->Driver.Viewport; + ctx->Driver.Viewport = NULL; + radeon_window_moved(radeon); + radeon_draw_buffer(ctx, radeon->glCtx.DrawBuffer); + ctx->Driver.Viewport = old_viewport; +} + +static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state) +{ + int i, j, reg, count; + int dwords; + uint32_t packet0; + if (!radeon_is_debug_enabled(RADEON_STATE, RADEON_VERBOSE) ) + return; + + dwords = state->check(&radeon->glCtx, state); + + fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size); + + if (state->cmd && radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) { + if (dwords > state->cmd_size) + dwords = state->cmd_size; + for (i = 0; i < dwords;) { + packet0 = state->cmd[i]; + reg = (packet0 & 0x1FFF) << 2; + count = ((packet0 & 0x3FFF0000) >> 16) + 1; + fprintf(stderr, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n", + state->name, i, reg, count); + ++i; + for (j = 0; j < count && i < dwords; j++) { + fprintf(stderr, " %s[%d]: 0x%04x = %08x\n", + state->name, i, reg, state->cmd[i]); + reg += 4; + ++i; + } + } + } +} + +/** + * Count total size for next state emit. + **/ +GLuint radeonCountStateEmitSize(radeonContextPtr radeon) +{ + struct radeon_state_atom *atom; + GLuint dwords = 0; + /* check if we are going to emit full state */ + + if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) { + if (!radeon->hw.is_dirty) + goto out; + foreach(atom, &radeon->hw.atomlist) { + if (atom->dirty) { + const GLuint atom_size = atom->check(&radeon->glCtx, atom); + dwords += atom_size; + if (RADEON_CMDBUF && atom_size) { + radeon_print_state_atom(radeon, atom); + } + } + } + } else { + foreach(atom, &radeon->hw.atomlist) { + const GLuint atom_size = atom->check(&radeon->glCtx, atom); + dwords += atom_size; + if (RADEON_CMDBUF && atom_size) { + radeon_print_state_atom(radeon, atom); + } + + } + } +out: + radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %u\n", __func__, dwords); + return dwords; +} + +static inline void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state_atom *atom) +{ + BATCH_LOCALS(radeon); + int dwords; + + dwords = atom->check(&radeon->glCtx, atom); + if (dwords) { + + radeon_print_state_atom(radeon, atom); + + if (atom->emit) { + atom->emit(&radeon->glCtx, atom); + } else { + BEGIN_BATCH(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); + END_BATCH(); + } + atom->dirty = GL_FALSE; + + } else { + radeon_print(RADEON_STATE, RADEON_VERBOSE, " skip state %s\n", atom->name); + } + +} + +static inline void radeonEmitAtoms(radeonContextPtr radeon, GLboolean emitAll) +{ + struct radeon_state_atom *atom; + + /* Emit actual atoms */ + if (radeon->hw.all_dirty || emitAll) { + foreach(atom, &radeon->hw.atomlist) + radeon_emit_atom( radeon, atom ); + } else { + foreach(atom, &radeon->hw.atomlist) { + if ( atom->dirty ) + radeon_emit_atom( radeon, atom ); + } + } + + COMMIT_BATCH(); +} + +void radeonEmitState(radeonContextPtr radeon) +{ + radeon_print(RADEON_STATE, RADEON_NORMAL, "%s\n", __func__); + + if (radeon->vtbl.pre_emit_state) + radeon->vtbl.pre_emit_state(radeon); + + /* this code used to return here but now it emits zbs */ + if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) + return; + + if (!radeon->cmdbuf.cs->cdw) { + if (RADEON_DEBUG & RADEON_STATE) + fprintf(stderr, "Begin reemit state\n"); + + radeonEmitAtoms(radeon, GL_TRUE); + } else { + + if (RADEON_DEBUG & RADEON_STATE) + fprintf(stderr, "Begin dirty state\n"); + + radeonEmitAtoms(radeon, GL_FALSE); + } + + radeon->hw.is_dirty = GL_FALSE; + radeon->hw.all_dirty = GL_FALSE; +} + + +void radeonFlush(struct gl_context *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (RADEON_DEBUG & RADEON_IOCTL) + fprintf(stderr, "%s %d\n", __func__, radeon->cmdbuf.cs->cdw); + + /* okay if we have no cmds in the buffer && + we have no DMA flush && + we have no DMA buffer allocated. + then no point flushing anything at all. + */ + if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved)) + goto flush_front; + + if (radeon->dma.flush) + radeon->dma.flush( ctx ); + + if (radeon->cmdbuf.cs->cdw) + rcommonFlushCmdBuf(radeon, __func__); + +flush_front: + if (_mesa_is_winsys_fbo(ctx->DrawBuffer) && radeon->front_buffer_dirty) { + __DRIscreen *const screen = radeon->radeonScreen->driScreen; + + if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2) + && (screen->dri2.loader->flushFrontBuffer != NULL)) { + __DRIdrawable * drawable = radeon_get_drawable(radeon); + + /* We set the dirty bit in radeon_prepare_render() if we're + * front buffer rendering once we get there. + */ + radeon->front_buffer_dirty = GL_FALSE; + + screen->dri2.loader->flushFrontBuffer(drawable, drawable->loaderPrivate); + } + } +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +void radeonFinish(struct gl_context * ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct radeon_renderbuffer *rrb; + int i; + + if (ctx->Driver.Flush) + ctx->Driver.Flush(ctx); /* +r6/r7 */ + + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + struct radeon_renderbuffer *rrb; + rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]); + if (rrb && rrb->bo) + radeon_bo_wait(rrb->bo); + } + rrb = radeon_get_depthbuffer(radeon); + if (rrb && rrb->bo) + radeon_bo_wait(rrb->bo); +} + +/* cmdbuffer */ +/** + * Send the current command buffer via ioctl to the hardware. + */ +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) +{ + int ret = 0; + + if (rmesa->cmdbuf.flushing) { + fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); + exit(-1); + } + rmesa->cmdbuf.flushing = 1; + + if (RADEON_DEBUG & RADEON_IOCTL) { + fprintf(stderr, "%s from %s\n", __func__, caller); + } + + radeonEmitQueryEnd(&rmesa->glCtx); + + if (rmesa->cmdbuf.cs->cdw) { + ret = radeon_cs_emit(rmesa->cmdbuf.cs); + rmesa->hw.all_dirty = GL_TRUE; + } + radeon_cs_erase(rmesa->cmdbuf.cs); + rmesa->cmdbuf.flushing = 0; + + if (!rmesa->vtbl.revalidate_all_buffers(&rmesa->glCtx)) + fprintf(stderr,"failed to revalidate buffers\n"); + + return ret; +} + +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) +{ + int ret; + + radeonReleaseDmaRegions(rmesa); + + ret = rcommonFlushCmdBufLocked(rmesa, caller); + + if (ret) { + fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to " + "parse or rejected command stream. See dmesg " + "for more info.\n", ret); + exit(ret); + } + + return ret; +} + +/** + * Make sure that enough space is available in the command buffer + * by flushing if necessary. + * + * \param dwords The number of dwords we need to be free on the command buffer + */ +GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) +{ + if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size + || radeon_cs_need_flush(rmesa->cmdbuf.cs)) { + /* If we try to flush empty buffer there is too big rendering operation. */ + assert(rmesa->cmdbuf.cs->cdw); + rcommonFlushCmdBuf(rmesa, caller); + return GL_TRUE; + } + return GL_FALSE; +} + +void rcommonInitCmdBuf(radeonContextPtr rmesa) +{ + GLuint size; + struct drm_radeon_gem_info mminfo = { 0 }; + int fd = rmesa->radeonScreen->driScreen->fd; + + /* Initialize command buffer */ + size = 256 * driQueryOptioni(&rmesa->optionCache, + "command_buffer_size"); + if (size < 2 * rmesa->hw.max_state_size) { + size = 2 * rmesa->hw.max_state_size + 65535; + } + if (size > 64 * 256) + size = 64 * 256; + + radeon_print(RADEON_CS, RADEON_VERBOSE, + "sizeof(drm_r300_cmd_header_t)=%zd\n", sizeof(drm_r300_cmd_header_t)); + radeon_print(RADEON_CS, RADEON_VERBOSE, + "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", sizeof(drm_radeon_cmd_buffer_t)); + radeon_print(RADEON_CS, RADEON_VERBOSE, + "Allocating %d bytes command buffer (max state is %d bytes)\n", + size * 4, rmesa->hw.max_state_size * 4); + + rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); + if (rmesa->cmdbuf.csm == NULL) { + /* FIXME: fatal error */ + return; + } + rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); + assert(rmesa->cmdbuf.cs != NULL); + rmesa->cmdbuf.size = size; + + radeon_cs_space_set_flush(rmesa->cmdbuf.cs, + (void (*)(void *))rmesa->glCtx.Driver.Flush, &rmesa->glCtx); + + + if (!drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, + &mminfo, sizeof(mminfo))) { + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, + mminfo.vram_visible); + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, + mminfo.gart_size); + } +} + +/** + * Destroy the command buffer + */ +void rcommonDestroyCmdBuf(radeonContextPtr rmesa) +{ + radeon_cs_destroy(rmesa->cmdbuf.cs); + radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); +} + +void rcommonBeginBatch(radeonContextPtr rmesa, int n, + const char *file, + const char *function, + int line) +{ + radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); + + radeon_print(RADEON_CS, RADEON_VERBOSE, "BEGIN_BATCH(%d) at %d, from %s:%i\n", + n, rmesa->cmdbuf.cs->cdw, function, line); + +} + +void radeonUserClear(struct gl_context *ctx, GLuint mask) +{ + _mesa_meta_Clear(ctx, mask); +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h new file mode 100644 index 000000000..a39b9360e --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common.h @@ -0,0 +1,87 @@ +#ifndef COMMON_MISC_H +#define COMMON_MISC_H + +#include "radeon_common_context.h" +#include "radeon_dma.h" +#include "radeon_texture.h" + +void radeonUserClear(struct gl_context *ctx, GLuint mask); +void radeonSetCliprects(radeonContextPtr radeon); +void radeonUpdateScissor( struct gl_context *ctx ); +void radeonScissor(struct gl_context *ctx); + +extern uint32_t radeonGetAge(radeonContextPtr radeon); + +void radeonFlush(struct gl_context *ctx); +void radeonFinish(struct gl_context * ctx); +void radeonEmitState(radeonContextPtr radeon); +GLuint radeonCountStateEmitSize(radeonContextPtr radeon); + +void radeon_clear_tris(struct gl_context *ctx, GLbitfield mask); + +void radeon_window_moved(radeonContextPtr radeon); +void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb); +void radeonDrawBuffer(struct gl_context *ctx); +void radeonReadBuffer( struct gl_context *ctx, GLenum mode ); +void radeon_viewport(struct gl_context *ctx); +void radeon_fbo_init(struct radeon_context *radeon); +void +radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, + struct radeon_bo *bo); +struct radeon_renderbuffer * +radeon_create_renderbuffer(mesa_format format, __DRIdrawable *driDrawPriv); + +void +radeonReadPixels(struct gl_context * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels); + +static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb; + radeon_print(RADEON_MEMORY, RADEON_TRACE, + "%s(rb %p)\n", + __func__, (void *) rb); + if (rrb && rrb->base.Base.ClassID == RADEON_RB_CLASS) + return rrb; + else + return NULL; +} + +static inline struct radeon_renderbuffer *radeon_get_renderbuffer(struct gl_framebuffer *fb, int att_index) +{ + radeon_print(RADEON_MEMORY, RADEON_TRACE, + "%s(fb %p, index %d)\n", + __func__, (void *) fb, att_index); + + if (att_index >= 0) + return radeon_renderbuffer(fb->Attachment[att_index].Renderbuffer); + else + return NULL; +} + +static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) +{ + struct radeon_renderbuffer *rrb; + rrb = radeon_renderbuffer(rmesa->state.depth.rb); + if (!rrb) + return NULL; + + return rrb; +} + +static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) +{ + struct radeon_renderbuffer *rrb; + + rrb = radeon_renderbuffer(rmesa->state.color.rb); + if (!rrb) + return NULL; + return rrb; +} + +#include "radeon_cmdbuf.h" + + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_common_context.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common_context.c new file mode 100644 index 000000000..689304aa4 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common_context.c @@ -0,0 +1,652 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "radeon_common.h" +#include "util/xmlpool.h" /* for symbolic values of enum-type options */ +#include "utils.h" +#include "drivers/common/meta.h" +#include "main/context.h" +#include "main/framebuffer.h" +#include "main/fbobject.h" +#include "main/renderbuffer.h" +#include "main/state.h" +#include "util/simple_list.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" + +#ifndef RADEON_DEBUG +int RADEON_DEBUG = (0); +#endif + + +static const char* get_chip_family_name(int chip_family) +{ + switch(chip_family) { +#if defined(RADEON_R100) + case CHIP_FAMILY_R100: return "R100"; + case CHIP_FAMILY_RV100: return "RV100"; + case CHIP_FAMILY_RS100: return "RS100"; + case CHIP_FAMILY_RV200: return "RV200"; + case CHIP_FAMILY_RS200: return "RS200"; +#elif defined(RADEON_R200) + case CHIP_FAMILY_R200: return "R200"; + case CHIP_FAMILY_RV250: return "RV250"; + case CHIP_FAMILY_RS300: return "RS300"; + case CHIP_FAMILY_RV280: return "RV280"; +#endif + default: return "unknown"; + } +} + +const char *const radeonVendorString = "Mesa Project"; + +/* Return complete renderer string. + */ +const char *radeonGetRendererString(radeonScreenPtr radeonScreen) +{ + static char buffer[128]; + char hardwarename[32]; + + GLuint agp_mode = (radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : + radeonScreen->AGPMode; + + snprintf(hardwarename, sizeof(hardwarename), "%s (%s %04X)", +#if defined(RADEON_R100) + "R100", +#elif defined(RADEON_R200) + "R200", +#endif + get_chip_family_name(radeonScreen->chip_family), + radeonScreen->device_id); + + driGetRendererString(buffer, hardwarename, agp_mode); + + strcat(buffer, " DRI2"); + + return buffer; +} + + +/* Return various strings for glGetString(). + */ +static const GLubyte *radeonGetString(struct gl_context * ctx, GLenum name) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + switch (name) { + case GL_VENDOR: + return (GLubyte *) radeonVendorString; + + case GL_RENDERER: + return (GLubyte *) radeonGetRendererString(radeon->radeonScreen); + + default: + return NULL; + } +} + +/* Initialize the driver's misc functions. + */ +static void radeonInitDriverFuncs(struct dd_function_table *functions) +{ + functions->GetString = radeonGetString; +} + +/** + * Create and initialize all common fields of the context, + * including the Mesa context itself. + */ +GLboolean radeonInitContext(radeonContextPtr radeon, + gl_api api, + struct dd_function_table* functions, + const struct gl_config * glVisual, + __DRIcontext * driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreen *sPriv = driContextPriv->driScreenPriv; + radeonScreenPtr screen = (radeonScreenPtr) (sPriv->driverPrivate); + struct gl_context* ctx; + struct gl_context* shareCtx; + int fthrottle_mode; + + /* Fill in additional standard functions. */ + radeonInitDriverFuncs(functions); + + radeon->radeonScreen = screen; + /* Allocate and initialize the Mesa context */ + if (sharedContextPrivate) + shareCtx = &((radeonContextPtr)sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + + if (!_mesa_initialize_context(&radeon->glCtx, api, + glVisual, shareCtx, + functions)) + return GL_FALSE; + + ctx = &radeon->glCtx; + driContextPriv->driverPrivate = radeon; + + _mesa_meta_init(ctx); + + /* DRI fields */ + radeon->driContext = driContextPriv; + + /* Setup IRQs */ + fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); + radeon->iw.irq_seq = -1; + radeon->irqsEmitted = 0; + radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && + radeon->radeonScreen->irq); + + radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + if (!radeon->do_irqs) + fprintf(stderr, + "IRQ's not enabled, falling back to %s: %d %d\n", + radeon->do_usleeps ? "usleeps" : "busy waits", + fthrottle_mode, radeon->radeonScreen->irq); + + radeon->texture_depth = driQueryOptioni (&radeon->optionCache, + "texture_depth"); + if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) + radeon->texture_depth = (glVisual == NULL || glVisual->rgbBits > 16) ? + DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; + + radeon->texture_row_align = 32; + radeon->texture_rect_row_align = 64; + radeon->texture_compressed_row_align = 32; + + radeon_init_dma(radeon); + + /* _mesa_initialize_context calls _mesa_init_queryobj which + * initializes all of the counter sizes to 64. The counters on r100 + * and r200 are only 32-bits for occlusion queries. Those are the + * only counters, so set the other sizes to zero. + */ + radeon->glCtx.Const.QueryCounterBits.SamplesPassed = 32; + + radeon->glCtx.Const.QueryCounterBits.TimeElapsed = 0; + radeon->glCtx.Const.QueryCounterBits.Timestamp = 0; + radeon->glCtx.Const.QueryCounterBits.PrimitivesGenerated = 0; + radeon->glCtx.Const.QueryCounterBits.PrimitivesWritten = 0; + radeon->glCtx.Const.QueryCounterBits.VerticesSubmitted = 0; + radeon->glCtx.Const.QueryCounterBits.PrimitivesSubmitted = 0; + radeon->glCtx.Const.QueryCounterBits.VsInvocations = 0; + radeon->glCtx.Const.QueryCounterBits.TessPatches = 0; + radeon->glCtx.Const.QueryCounterBits.TessInvocations = 0; + radeon->glCtx.Const.QueryCounterBits.GsInvocations = 0; + radeon->glCtx.Const.QueryCounterBits.GsPrimitives = 0; + radeon->glCtx.Const.QueryCounterBits.FsInvocations = 0; + radeon->glCtx.Const.QueryCounterBits.ComputeInvocations = 0; + radeon->glCtx.Const.QueryCounterBits.ClInPrimitives = 0; + radeon->glCtx.Const.QueryCounterBits.ClOutPrimitives = 0; + + return GL_TRUE; +} + + + +/** + * Destroy the command buffer and state atoms. + */ +static void radeon_destroy_atom_list(radeonContextPtr radeon) +{ + struct radeon_state_atom *atom; + + foreach(atom, &radeon->hw.atomlist) { + free(atom->cmd); + free(atom->lastcmd); + } + +} + +/** + * Cleanup common context fields. + * Called by r200DestroyContext + */ +void radeonDestroyContext(__DRIcontext *driContextPriv ) +{ +#ifdef RADEON_BO_TRACK + FILE *track; +#endif + GET_CURRENT_CONTEXT(ctx); + radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; + radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; + + assert(radeon); + + _mesa_meta_free(&radeon->glCtx); + + if (radeon == current) { + _mesa_make_current(NULL, NULL, NULL); + } + + radeon_firevertices(radeon); + if (!is_empty_list(&radeon->dma.reserved)) { + rcommonFlushCmdBuf( radeon, __func__ ); + } + + radeonFreeDmaRegions(radeon); + radeonReleaseArrays(&radeon->glCtx, ~0); + if (radeon->vtbl.free_context) + radeon->vtbl.free_context(&radeon->glCtx); + _swsetup_DestroyContext( &radeon->glCtx ); + _tnl_DestroyContext( &radeon->glCtx ); + _vbo_DestroyContext( &radeon->glCtx ); + _swrast_DestroyContext( &radeon->glCtx ); + + /* free atom list */ + /* free the Mesa context data */ + _mesa_free_context_data(&radeon->glCtx, true); + + /* free the option cache */ + driDestroyOptionCache(&radeon->optionCache); + + rcommonDestroyCmdBuf(radeon); + + radeon_destroy_atom_list(radeon); + +#ifdef RADEON_BO_TRACK + track = fopen("/tmp/tracklog", "w"); + if (track) { + radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); + fclose(track); + } +#endif + free(radeon); +} + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean radeonUnbindContext(__DRIcontext * driContextPriv) +{ + radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; + + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "%s ctx %p\n", __func__, + &radeon->glCtx); + + /* Unset current context and dispath table */ + _mesa_make_current(NULL, NULL, NULL); + + return GL_TRUE; +} + + +static unsigned +radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) +{ + return _mesa_get_format_bytes(rb->base.Base.Format) * 8; +} + +/* + * Check if drawable has been invalidated by dri2InvalidateDrawable(). + * Update renderbuffers if so. This prevents a client from accessing + * a backbuffer that has a swap pending but not yet completed. + * + * See intel_prepare_render for equivalent code in intel driver. + * + */ +void radeon_prepare_render(radeonContextPtr radeon) +{ + __DRIcontext *driContext = radeon->driContext; + __DRIdrawable *drawable; + __DRIscreen *screen; + + screen = driContext->driScreenPriv; + if (!screen->dri2.loader) + return; + + drawable = driContext->driDrawablePriv; + if (drawable->dri2.stamp != driContext->dri2.draw_stamp) { + if (drawable->lastStamp != drawable->dri2.stamp) + radeon_update_renderbuffers(driContext, drawable, GL_FALSE); + + /* Intel driver does the equivalent of this, no clue if it is needed:*/ + radeon_draw_buffer(&radeon->glCtx, radeon->glCtx.DrawBuffer); + + driContext->dri2.draw_stamp = drawable->dri2.stamp; + } + + drawable = driContext->driReadablePriv; + if (drawable->dri2.stamp != driContext->dri2.read_stamp) { + if (drawable->lastStamp != drawable->dri2.stamp) + radeon_update_renderbuffers(driContext, drawable, GL_FALSE); + driContext->dri2.read_stamp = drawable->dri2.stamp; + } + + /* If we're currently rendering to the front buffer, the rendering + * that will happen next will probably dirty the front buffer. So + * mark it as dirty here. + */ + if (_mesa_is_front_buffer_drawing(radeon->glCtx.DrawBuffer)) + radeon->front_buffer_dirty = GL_TRUE; +} + +void +radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + GLboolean front_only) +{ + unsigned int attachments[10]; + __DRIbuffer *buffers = NULL; + __DRIscreen *screen; + struct radeon_renderbuffer *rb; + int i, count; + struct radeon_framebuffer *draw; + radeonContextPtr radeon; + char *regname; + struct radeon_bo *depth_bo = NULL, *bo; + + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); + + draw = drawable->driverPrivate; + screen = context->driScreenPriv; + radeon = (radeonContextPtr) context->driverPrivate; + + /* Set this up front, so that in case our buffers get invalidated + * while we're getting new buffers, we don't clobber the stamp and + * thus ignore the invalidate. */ + drawable->lastStamp = drawable->dri2.stamp; + + if (screen->dri2.loader + && (screen->dri2.loader->base.version > 2) + && (screen->dri2.loader->getBuffersWithFormat != NULL)) { + struct radeon_renderbuffer *depth_rb; + struct radeon_renderbuffer *stencil_rb; + + i = 0; + if ((front_only || _mesa_is_front_buffer_drawing(&draw->base) || + _mesa_is_front_buffer_reading(&draw->base) || + !draw->color_rb[1]) + && draw->color_rb[0]) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); + } + + if (!front_only) { + if (draw->color_rb[1]) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]); + } + + depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); + stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); + + if ((depth_rb != NULL) && (stencil_rb != NULL)) { + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + attachments[i++] = radeon_bits_per_pixel(depth_rb); + } else if (depth_rb != NULL) { + attachments[i++] = __DRI_BUFFER_DEPTH; + attachments[i++] = radeon_bits_per_pixel(depth_rb); + } else if (stencil_rb != NULL) { + attachments[i++] = __DRI_BUFFER_STENCIL; + attachments[i++] = radeon_bits_per_pixel(stencil_rb); + } + } + + buffers = screen->dri2.loader->getBuffersWithFormat(drawable, + &drawable->w, + &drawable->h, + attachments, i / 2, + &count, + drawable->loaderPrivate); + } else if (screen->dri2.loader) { + i = 0; + if (draw->color_rb[0]) + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (!front_only) { + if (draw->color_rb[1]) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) + attachments[i++] = __DRI_BUFFER_DEPTH; + if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) + attachments[i++] = __DRI_BUFFER_STENCIL; + } + + buffers = screen->dri2.loader->getBuffers(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + } + + if (buffers == NULL) + return; + + for (i = 0; i < count; i++) { + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + rb = draw->color_rb[0]; + regname = "dri2 front buffer"; + break; + case __DRI_BUFFER_FAKE_FRONT_LEFT: + rb = draw->color_rb[0]; + regname = "dri2 fake front buffer"; + break; + case __DRI_BUFFER_BACK_LEFT: + rb = draw->color_rb[1]; + regname = "dri2 back buffer"; + break; + case __DRI_BUFFER_DEPTH: + rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); + regname = "dri2 depth buffer"; + break; + case __DRI_BUFFER_DEPTH_STENCIL: + rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); + regname = "dri2 depth / stencil buffer"; + break; + case __DRI_BUFFER_STENCIL: + rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); + regname = "dri2 stencil buffer"; + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + + if (rb == NULL) + continue; + + if (rb->bo) { + uint32_t name = radeon_gem_name_bo(rb->bo); + if (name == buffers[i].name) + continue; + } + + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, + "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", + regname, buffers[i].name, buffers[i].attachment, + buffers[i].cpp, buffers[i].pitch); + + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->base.Base.Width = drawable->w; + rb->base.Base.Height = drawable->h; + rb->has_surface = 0; + + if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "(reusing depth buffer as stencil)\n"); + bo = depth_bo; + radeon_bo_ref(bo); + } else { + uint32_t tiling_flags = 0, pitch = 0; + int ret; + + bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + + if (bo == NULL) { + fprintf(stderr, "failed to attach %s %d\n", + regname, buffers[i].name); + continue; + } + + ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch); + if (ret) { + fprintf(stderr, + "failed to get tiling for %s %d\n", + regname, buffers[i].name); + radeon_bo_unref(bo); + bo = NULL; + continue; + } else { + if (tiling_flags & RADEON_TILING_MACRO) + bo->flags |= RADEON_BO_FLAGS_MACRO_TILE; + if (tiling_flags & RADEON_TILING_MICRO) + bo->flags |= RADEON_BO_FLAGS_MICRO_TILE; + } + } + + if (buffers[i].attachment == __DRI_BUFFER_DEPTH) { + if (draw->base.Visual.depthBits == 16) + rb->cpp = 2; + depth_bo = bo; + } + + radeon_renderbuffer_set_bo(rb, bo); + radeon_bo_unref(bo); + + if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { + rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); + if (rb != NULL) { + struct radeon_bo *stencil_bo = NULL; + + if (rb->bo) { + uint32_t name = radeon_gem_name_bo(rb->bo); + if (name == buffers[i].name) + continue; + } + + stencil_bo = bo; + radeon_bo_ref(stencil_bo); + radeon_renderbuffer_set_bo(rb, stencil_bo); + radeon_bo_unref(stencil_bo); + } + } + } + + driUpdateFramebufferSize(&radeon->glCtx, drawable); +} + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, + __DRIdrawable * driDrawPriv, + __DRIdrawable * driReadPriv) +{ + radeonContextPtr radeon; + GET_CURRENT_CONTEXT(curCtx); + struct gl_framebuffer *drfb, *readfb; + + if (driContextPriv) + radeon = (radeonContextPtr)driContextPriv->driverPrivate; + else + radeon = NULL; + /* According to the glXMakeCurrent() man page: "Pending commands to + * the previous context, if any, are flushed before it is released." + * But only flush if we're actually changing contexts. + */ + + if ((radeonContextPtr)curCtx && (radeonContextPtr)curCtx != radeon) { + _mesa_flush(curCtx); + } + + if (!driContextPriv) { + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "%s ctx is null\n", __func__); + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + + if(driDrawPriv == NULL && driReadPriv == NULL) { + drfb = _mesa_create_framebuffer(&radeon->glCtx.Visual); + readfb = drfb; + } + else { + drfb = driDrawPriv->driverPrivate; + readfb = driReadPriv->driverPrivate; + } + + if(driDrawPriv) + radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE); + if (driDrawPriv != driReadPriv) + radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE); + _mesa_reference_renderbuffer(&radeon->state.color.rb, + &(radeon_get_renderbuffer(drfb, BUFFER_BACK_LEFT)->base.Base)); + _mesa_reference_renderbuffer(&radeon->state.depth.rb, + &(radeon_get_renderbuffer(drfb, BUFFER_DEPTH)->base.Base)); + + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __func__, &radeon->glCtx, drfb, readfb); + + if(driDrawPriv) + driUpdateFramebufferSize(&radeon->glCtx, driDrawPriv); + if (driReadPriv != driDrawPriv) + driUpdateFramebufferSize(&radeon->glCtx, driReadPriv); + + _mesa_make_current(&radeon->glCtx, drfb, readfb); + if (driDrawPriv == NULL && driReadPriv == NULL) + _mesa_reference_framebuffer(&drfb, NULL); + + _mesa_update_state(&radeon->glCtx); + + if (radeon->glCtx.DrawBuffer == drfb) { + if(driDrawPriv != NULL) { + radeon_window_moved(radeon); + } + + radeon_draw_buffer(&radeon->glCtx, drfb); + } + + + if (RADEON_DEBUG & RADEON_DRI) + fprintf(stderr, "End %s\n", __func__); + + return GL_TRUE; +} + diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_common_context.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common_context.h new file mode 100644 index 000000000..bd7343f40 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_common_context.h @@ -0,0 +1,503 @@ + +#ifndef COMMON_CONTEXT_H +#define COMMON_CONTEXT_H + +#include "math/m_vector.h" +#include "tnl/t_context.h" +#include "main/colormac.h" + +#include "radeon_screen.h" +#include "radeon_debug.h" +#include "radeon_drm.h" +#include "dri_util.h" +#include "tnl/t_vertex.h" +#include "swrast/s_context.h" + +struct radeon_context; + +#include "radeon_bo_gem.h" +#include "radeon_cs_gem.h" + +/* This union is used to avoid warnings/miscompilation + with float to uint32_t casts due to strict-aliasing */ +typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; + +struct radeon_context; +typedef struct radeon_context radeonContextRec; +typedef struct radeon_context *radeonContextPtr; + + +#define TEX_0 0x1 +#define TEX_1 0x2 +#define TEX_2 0x4 +#define TEX_3 0x8 +#define TEX_4 0x10 +#define TEX_5 0x20 + +/* Rasterizing fallbacks */ +/* See correponding strings in r200_swtcl.c */ +#define RADEON_FALLBACK_TEXTURE 0x0001 +#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +#define RADEON_FALLBACK_STENCIL 0x0004 +#define RADEON_FALLBACK_RENDER_MODE 0x0008 +#define RADEON_FALLBACK_BLEND_EQ 0x0010 +#define RADEON_FALLBACK_BLEND_FUNC 0x0020 +#define RADEON_FALLBACK_DISABLE 0x0040 +#define RADEON_FALLBACK_BORDER_MODE 0x0080 +#define RADEON_FALLBACK_DEPTH_BUFFER 0x0100 +#define RADEON_FALLBACK_STENCIL_BUFFER 0x0200 + +#define R200_FALLBACK_TEXTURE 0x01 +#define R200_FALLBACK_DRAW_BUFFER 0x02 +#define R200_FALLBACK_STENCIL 0x04 +#define R200_FALLBACK_RENDER_MODE 0x08 +#define R200_FALLBACK_DISABLE 0x10 +#define R200_FALLBACK_BORDER_MODE 0x20 + +#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ +#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ +#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ +#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ +#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ +#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ +#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ +#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ +#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */ + +/* The blit width for texture uploads + */ +#define BLIT_WIDTH_BYTES 1024 + +/* Use the templated vertex format: + */ +#define COLOR_IS_RGBA +#define TAG(x) radeon##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +#define RADEON_RB_CLASS 0xdeadbeef + +struct radeon_renderbuffer +{ + struct swrast_renderbuffer base; + + struct radeon_bo *bo; + unsigned int cpp; + /* unsigned int offset; */ + unsigned int pitch; + + struct radeon_bo *map_bo; + GLbitfield map_mode; + int map_x, map_y, map_w, map_h; + int map_pitch; + void *map_buffer; + + uint32_t draw_offset; /* FBO */ + /* boo Xorg 6.8.2 compat */ + int has_surface; + + GLuint pf_pending; /**< sequence number of pending flip */ + __DRIdrawable *dPriv; +}; + +struct radeon_framebuffer +{ + struct gl_framebuffer base; + + struct radeon_renderbuffer *color_rb[2]; +}; + + +struct radeon_colorbuffer_state { + int roundEnable; + struct gl_renderbuffer *rb; + uint32_t draw_offset; /* offset into color renderbuffer - FBOs */ +}; + +struct radeon_depthbuffer_state { + struct gl_renderbuffer *rb; +}; + +struct radeon_scissor_state { + drm_clip_rect_t rect; + GLboolean enabled; +}; + +struct radeon_state_atom { + struct radeon_state_atom *next, *prev; + const char *name; /* for debug */ + int cmd_size; /* size in bytes */ + GLuint idx; + GLuint is_tcl; + GLuint *cmd; /* one or more cmd's */ + GLuint *lastcmd; /* one or more cmd's */ + GLboolean dirty; /* dirty-mark in emit_state_list */ + int (*check) (struct gl_context *, struct radeon_state_atom *atom); /* is this state active? */ + void (*emit) (struct gl_context *, struct radeon_state_atom *atom); +}; + +struct radeon_hw_state { + /* Head of the linked list of state atoms. */ + struct radeon_state_atom atomlist; + int max_state_size; /* Number of bytes necessary for a full state emit. */ + int max_post_flush_size; /* Number of bytes necessary for post flushing emits */ + GLboolean is_dirty, all_dirty; +}; + + +/* Texture related */ +typedef struct _radeon_texture_image radeon_texture_image; + + +/** + * This is a subclass of swrast_texture_image since we use swrast + * for software fallback rendering. + */ +struct _radeon_texture_image { + struct swrast_texture_image base; + + /** + * If mt != 0, the image is stored in hardware format in the + * given mipmap tree. In this case, base.Data may point into the + * mapping of the buffer object that contains the mipmap tree. + * + * If mt == 0, the image is stored in normal memory pointed to + * by base.Data. + */ + struct _radeon_mipmap_tree *mt; + struct radeon_bo *bo; + GLboolean used_as_render_target; +}; + + +static inline radeon_texture_image *get_radeon_texture_image(struct gl_texture_image *image) +{ + return (radeon_texture_image*)image; +} + + +typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; + +#define RADEON_TXO_MICRO_TILE (1 << 3) + +/* Texture object in locally shared texture space. + */ +struct radeon_tex_obj { + struct gl_texture_object base; + struct _radeon_mipmap_tree *mt; + + /** + * This is true if we've verified that the mipmap tree above is complete + * and so on. + */ + GLboolean validated; + /* Minimum LOD to be used during rendering */ + unsigned minLod; + /* Miximum LOD to be used during rendering */ + unsigned maxLod; + + GLuint override_offset; + GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ + GLuint tile_bits; /* hw texture tile bits used on this texture */ + struct radeon_bo *bo; + + GLuint pp_txfilter; /* hardware register values */ + GLuint pp_txformat; + GLuint pp_txformat_x; + GLuint pp_txsize; /* npot only */ + GLuint pp_txpitch; /* npot only */ + GLuint pp_border_color; + GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ + + GLboolean border_fallback; +}; + +static inline radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) +{ + return (radeonTexObj*)texObj; +} + +/* occlusion query */ +struct radeon_query_object { + struct gl_query_object Base; + struct radeon_bo *bo; + int curr_offset; + GLboolean emitted_begin; + + /* Double linked list of not flushed query objects */ + struct radeon_query_object *prev, *next; +}; + +/* Need refcounting on dma buffers: + */ +struct radeon_dma_buffer { + int refcount; /* the number of retained regions in buf */ + drmBufPtr buf; +}; + +struct radeon_aos { + struct radeon_bo *bo; /** Buffer object where vertex data is stored */ + int offset; /** Offset into buffer object, in bytes */ + int components; /** Number of components per vertex */ + int stride; /** Stride in dwords (may be 0 for repeating) */ + int count; /** Number of vertices */ +}; + +#define DMA_BO_FREE_TIME 100 + +struct radeon_dma_bo { + struct radeon_dma_bo *next, *prev; + struct radeon_bo *bo; + int expire_counter; +}; + +struct radeon_dma { + /* Active dma region. Allocations for vertices and retained + * regions come from here. Also used for emitting random vertices, + * these may be flushed by calling flush_current(); + */ + struct radeon_dma_bo free; + struct radeon_dma_bo wait; + struct radeon_dma_bo reserved; + size_t current_used; /** Number of bytes allocated and forgotten about */ + size_t current_vertexptr; /** End of active vertex region */ + size_t minimum_size; + + /** + * If current_vertexptr != current_used then flush must be non-zero. + * flush must be called before non-active vertex allocations can be + * performed. + */ + void (*flush) (struct gl_context *); +}; + +/* radeon_swtcl.c + */ +struct radeon_swtcl_info { + + GLuint RenderIndex; + GLuint vertex_size; + GLubyte *verts; + + /* Fallback rasterization functions + */ + GLuint hw_primitive; + GLenum render_primitive; + GLuint numverts; + + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + + GLuint emit_prediction; + struct radeon_bo *bo; +}; + +#define RADEON_MAX_AOS_ARRAYS 16 +struct radeon_tcl_info { + struct radeon_aos aos[RADEON_MAX_AOS_ARRAYS]; + GLuint aos_count; + struct radeon_bo *elt_dma_bo; /** Buffer object that contains element indices */ + int elt_dma_offset; /** Offset into this buffer object, in bytes */ +}; + +struct radeon_ioctl { + GLuint vertex_offset; + GLuint vertex_max; + struct radeon_bo *bo; + GLuint vertex_size; +}; + +#define RADEON_MAX_PRIMS 64 + +struct radeon_prim { + GLuint start; + GLuint end; + GLuint prim; +}; + +static inline GLuint radeonPackColor(GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (cpp) { + case 2: + return PACK_COLOR_565(r, g, b); + case 4: + return PACK_COLOR_8888(a, r, g, b); + default: + return 0; + } +} + +#define MAX_CMD_BUF_SZ (16*1024) + +#define MAX_DMA_BUF_SZ (64*1024) + +struct radeon_store { + GLuint statenr; + GLuint primnr; + char cmd_buf[MAX_CMD_BUF_SZ]; + int cmd_used; + int elts_start; +}; + +typedef void (*radeon_tri_func) (radeonContextPtr, + radeonVertex *, + radeonVertex *, radeonVertex *); + +typedef void (*radeon_line_func) (radeonContextPtr, + radeonVertex *, radeonVertex *); + +typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); + +#define RADEON_MAX_BOS 32 +struct radeon_state { + struct radeon_colorbuffer_state color; + struct radeon_depthbuffer_state depth; + struct radeon_scissor_state scissor; +}; + +/** + * This structure holds the command buffer while it is being constructed. + * + * The first batch of commands in the buffer is always the state that needs + * to be re-emitted when the context is lost. This batch can be skipped + * otherwise. + */ +struct radeon_cmdbuf { + struct radeon_cs_manager *csm; + struct radeon_cs *cs; + int size; /** # of dwords total */ + unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ +}; + +struct radeon_context { + struct gl_context glCtx; /**< base class, must be first */ + __DRIcontext *driContext; /* DRI context */ + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + + /* Texture object bookkeeping + */ + int texture_depth; + float initialMaxAnisotropy; + uint32_t texture_row_align; + uint32_t texture_rect_row_align; + uint32_t texture_compressed_row_align; + + struct radeon_dma dma; + struct radeon_hw_state hw; + /* Rasterization and vertex state: + */ + GLuint TclFallback; + GLuint Fallback; + GLuint NewGLState; + GLbitfield64 tnl_index_bitset; /* index of bits for last tnl_install_attrs */ + + /* Drawable information */ + unsigned int lastStamp; + + /* Busy waiting */ + GLuint do_usleeps; + GLuint do_irqs; + GLuint irqsEmitted; + drm_radeon_irq_wait_t iw; + + /* Derived state - for r300 only */ + struct radeon_state state; + + struct radeon_swtcl_info swtcl; + struct radeon_tcl_info tcl; + /* Configuration cache + */ + driOptionCache optionCache; + + struct radeon_cmdbuf cmdbuf; + + struct radeon_debug debug; + + drm_clip_rect_t fboRect; + GLboolean front_cliprects; + + /** + * Set if rendering has occurred to the drawable's front buffer. + * + * This is used in the DRI2 case to detect that glFlush should also copy + * the contents of the fake front buffer to the real front buffer. + */ + GLboolean front_buffer_dirty; + + struct { + struct radeon_query_object *current; + struct radeon_state_atom queryobj; + } query; + + struct { + void (*swtcl_flush)(struct gl_context *ctx, uint32_t offset); + void (*pre_emit_state)(radeonContextPtr rmesa); + void (*fallback)(struct gl_context *ctx, GLuint bit, GLboolean mode); + void (*free_context)(struct gl_context *ctx); + void (*emit_query_finish)(radeonContextPtr radeon); + void (*update_scissor)(struct gl_context *ctx); + unsigned (*check_blit)(mesa_format mesa_format, uint32_t dst_pitch); + unsigned (*blit)(struct gl_context *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + mesa_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + mesa_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y); + unsigned (*is_format_renderable)(mesa_format mesa_format); + GLboolean (*revalidate_all_buffers)(struct gl_context *ctx); + } vtbl; +}; + +static inline radeonContextPtr RADEON_CONTEXT(struct gl_context *ctx) +{ + return (radeonContextPtr) ctx; +} + +static inline __DRIdrawable* radeon_get_drawable(radeonContextPtr radeon) +{ + return radeon->driContext->driDrawablePriv; +} + +static inline __DRIdrawable* radeon_get_readable(radeonContextPtr radeon) +{ + return radeon->driContext->driReadablePriv; +} + +extern const char *const radeonVendorString; + +const char *radeonGetRendererString(radeonScreenPtr radeonScreen); + +GLboolean radeonInitContext(radeonContextPtr radeon, + gl_api api, + struct dd_function_table* functions, + const struct gl_config * glVisual, + __DRIcontext * driContextPriv, + void *sharedContextPrivate); + +void radeonCleanupContext(radeonContextPtr radeon); +GLboolean radeonUnbindContext(__DRIcontext * driContextPriv); +void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + GLboolean front_only); +GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, + __DRIdrawable * driDrawPriv, + __DRIdrawable * driReadPriv); +extern void radeonDestroyContext(__DRIcontext * driContextPriv); +void radeon_prepare_render(radeonContextPtr radeon); + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c new file mode 100644 index 000000000..91f86a96b --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.c @@ -0,0 +1,108 @@ +/* + * Copyright © 2009 Pauli Nieminen + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Pauli Nieminen <suokkos@gmail.com> + */ + +#include "util/debug.h" + +#include "radeon_common_context.h" +#include "radeon_debug.h" + +#include <stdarg.h> +#include <stdio.h> + +static const struct debug_control debug_control[] = { + {"fall", RADEON_FALLBACKS}, + {"tex", RADEON_TEXTURE}, + {"ioctl", RADEON_IOCTL}, + {"verts", RADEON_VERTS}, + {"render", RADEON_RENDER}, + {"swrender", RADEON_SWRENDER}, + {"state", RADEON_STATE}, + {"shader", RADEON_SHADER}, + {"vfmt", RADEON_VFMT}, + {"vtxf", RADEON_VFMT}, + {"dri", RADEON_DRI}, + {"dma", RADEON_DMA}, + {"sanity", RADEON_SANITY}, + {"sync", RADEON_SYNC}, + {"pixel", RADEON_PIXEL}, + {"mem", RADEON_MEMORY}, + {"cs", RADEON_CS}, + {"allmsg", ~RADEON_SYNC}, /* avoid the term "sync" because the parser uses strstr */ + {NULL, 0} +}; + +radeon_debug_type_t radeon_enabled_debug_types; + +void radeon_init_debug(void) +{ + radeon_enabled_debug_types = parse_debug_string(getenv("RADEON_DEBUG"), debug_control); + + radeon_enabled_debug_types |= RADEON_GENERAL; +} + +void _radeon_debug_add_indent(void) +{ + GET_CURRENT_CONTEXT(ctx); + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + const size_t length = sizeof(radeon->debug.indent) + / sizeof(radeon->debug.indent[0]); + if (radeon->debug.indent_depth < length - 1) { + radeon->debug.indent[radeon->debug.indent_depth] = '\t'; + ++radeon->debug.indent_depth; + } +} + +void _radeon_debug_remove_indent(void) +{ + GET_CURRENT_CONTEXT(ctx); + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (radeon->debug.indent_depth > 0) { + radeon->debug.indent[radeon->debug.indent_depth] = '\0'; + --radeon->debug.indent_depth; + } +} + +void _radeon_print(const radeon_debug_type_t type, + const radeon_debug_level_t level, + const char* message, + ...) +{ + va_list values; + + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + // FIXME: Make this multi thread safe + if (radeon->debug.indent_depth) + fprintf(stderr, "%s", radeon->debug.indent); + } + va_start( values, message ); + vfprintf(stderr, message, values); + va_end( values ); +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.h new file mode 100644 index 000000000..df2f1abfb --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_debug.h @@ -0,0 +1,167 @@ +/* + * Copyright © 2009 Pauli Nieminen + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Pauli Nieminen <suokkos@gmail.com> + */ + +#ifndef RADEON_DEBUG_H_INCLUDED +#define RADEON_DEBUG_H_INCLUDED + +#include <stdlib.h> + +typedef enum radeon_debug_levels { + RADEON_CRITICAL = 0, /* Only errors */ + RADEON_IMPORTANT = 1, /* Important warnings and messages */ + RADEON_NORMAL = 2, /* Normal log messages usefull for debugging */ + RADEON_VERBOSE = 3, /* Extra details to debugging */ + RADEON_TRACE = 4 /* Log about everything that happens */ +} radeon_debug_level_t; + +/** + * Compile time option to change level of debugging compiled to dri driver. + * Selecting critical level is not recommended because perfromance gains are + * going to minimal but you will lose a lot of important warnings in case of + * errors. + */ +#ifndef RADEON_DEBUG_LEVEL +# ifdef DEBUG +# define RADEON_DEBUG_LEVEL RADEON_TRACE +# else +# define RADEON_DEBUG_LEVEL RADEON_VERBOSE +# endif +#endif + +typedef enum radeon_debug_types { + RADEON_TEXTURE = 0x00001, + RADEON_STATE = 0x00002, + RADEON_IOCTL = 0x00004, + RADEON_RENDER = 0x00008, + RADEON_SWRENDER = 0x00010, + RADEON_FALLBACKS = 0x00020, + RADEON_VFMT = 0x00040, + RADEON_SHADER = 0x00080, + RADEON_CS = 0x00100, + RADEON_DRI = 0x00200, + RADEON_DMA = 0x00400, + RADEON_SANITY = 0x00800, + RADEON_SYNC = 0x01000, + RADEON_PIXEL = 0x02000, + RADEON_MEMORY = 0x04000, + RADEON_VERTS = 0x08000, + RADEON_GENERAL = 0x10000 /* Used for errors and warnings */ +} radeon_debug_type_t; + +#define RADEON_MAX_INDENT 5 + +struct radeon_debug { + size_t indent_depth; + char indent[RADEON_MAX_INDENT]; +}; + +extern radeon_debug_type_t radeon_enabled_debug_types; + +/** + * Compabibility layer for old debug code + **/ +#define RADEON_DEBUG radeon_enabled_debug_types + +static inline int radeon_is_debug_enabled(const radeon_debug_type_t type, + const radeon_debug_level_t level) +{ + return RADEON_DEBUG_LEVEL >= level + && (type & radeon_enabled_debug_types); +} + +extern void _radeon_print(const radeon_debug_type_t type, + const radeon_debug_level_t level, + const char* message, + ...) PRINTFLIKE(3, 4); +/** + * Print out debug message if channel specified by type is enabled + * and compile time debugging level is at least as high as level parameter + */ +#define radeon_print(type, level, ...) do { \ + const radeon_debug_level_t _debug_level = (level); \ + const radeon_debug_type_t _debug_type = (type); \ + /* Compile out if level of message is too high */ \ + if (radeon_is_debug_enabled(type, level)) { \ + _radeon_print(_debug_type, _debug_level, \ + __VA_ARGS__); \ + } \ +} while(0) + +/** + * printf style function for writing error messages. + */ +#define radeon_error(...) do { \ + radeon_print(RADEON_GENERAL, RADEON_CRITICAL, \ + __VA_ARGS__); \ +} while(0) + +/** + * printf style function for writing warnings. + */ +#define radeon_warning(...) do { \ + radeon_print(RADEON_GENERAL, RADEON_IMPORTANT, \ + __VA_ARGS__); \ +} while(0) + +extern void radeon_init_debug(void); +extern void _radeon_debug_add_indent(void); +extern void _radeon_debug_remove_indent(void); + +static inline void radeon_debug_add_indent(void) +{ + if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) { + _radeon_debug_add_indent(); + } +} +static inline void radeon_debug_remove_indent(void) +{ + if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) { + _radeon_debug_remove_indent(); + } +} + + +/* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html . + I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble + with other compilers ... GLUE! +*/ +#define WARN_ONCE(...) do { \ + static int __warn_once=1; \ + if(__warn_once){ \ + radeon_warning("*********************************WARN_ONCE*********************************\n"); \ + radeon_warning("File %s function %s line %d\n", \ + __FILE__, __func__, __LINE__); \ + radeon_warning(__VA_ARGS__);\ + radeon_warning("***************************************************************************\n"); \ + __warn_once=0;\ + } \ + } while(0) + + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_dma.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_dma.c new file mode 100644 index 000000000..99c73d6ff --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_dma.c @@ -0,0 +1,511 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include <errno.h> +#include "radeon_common.h" +#include "radeon_fog.h" +#include "util/simple_list.h" + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ + : "0" (nr), \ + "D" ((long)dst), \ + "S" ((long)src) ); \ +} while (0) +#else +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int j; \ + for ( j = 0 ; j < nr ; j++ ) \ + dst[j] = ((int *)src)[j]; \ + dst += nr; \ +} while (0) +#endif + +void radeonEmitVec4(uint32_t *out, const GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & RADEON_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __func__, count, stride, (void *)out, (void *)data); + + if (stride == 4) + COPY_DWORDS(out, data, count); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out++; + data += stride; + } +} + +void radeonEmitVec8(uint32_t *out, const GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & RADEON_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __func__, count, stride, (void *)out, (void *)data); + + if (stride == 8) + COPY_DWORDS(out, data, count * 2); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out += 2; + data += stride; + } +} + +void radeonEmitVec12(uint32_t *out, const GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & RADEON_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __func__, count, stride, (void *)out, (void *)data); + + if (stride == 12) { + COPY_DWORDS(out, data, count * 3); + } + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out[2] = *(int *)(data + 8); + out += 3; + data += stride; + } +} + +void radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & RADEON_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __func__, count, stride, (void *)out, (void *)data); + + if (stride == 16) + COPY_DWORDS(out, data, count * 4); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out[2] = *(int *)(data + 8); + out[3] = *(int *)(data + 12); + out += 4; + data += stride; + } +} + +void rcommon_emit_vector(struct gl_context * ctx, struct radeon_aos *aos, + const GLvoid * data, int size, int stride, int count) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + uint32_t *out; + + if (stride == 0) { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); + count = 1; + aos->stride = 0; + } else { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); + aos->stride = size; + } + + aos->components = size; + aos->count = count; + + radeon_bo_map(aos->bo, 1); + out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + switch (size) { + case 1: radeonEmitVec4(out, data, stride, count); break; + case 2: radeonEmitVec8(out, data, stride, count); break; + case 3: radeonEmitVec12(out, data, stride, count); break; + case 4: radeonEmitVec16(out, data, stride, count); break; + default: + assert(0); + break; + } + radeon_bo_unmap(aos->bo); +} + +void rcommon_emit_vecfog(struct gl_context *ctx, struct radeon_aos *aos, + GLvoid *data, int stride, int count) +{ + int i; + float *out; + int size = 1; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & RADEON_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __func__, count, stride); + + if (stride == 0) { + radeonAllocDmaRegion( rmesa, &aos->bo, &aos->offset, size * 4, 32 ); + count = 1; + aos->stride = 0; + } else { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); + aos->stride = size; + } + + aos->components = size; + aos->count = count; + + /* Emit the data */ + radeon_bo_map(aos->bo, 1); + out = (float*)((char*)aos->bo->ptr + aos->offset); + for (i = 0; i < count; i++) { + out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data ); + out++; + data += stride; + } + radeon_bo_unmap(aos->bo); +} + +void radeon_init_dma(radeonContextPtr rmesa) +{ + make_empty_list(&rmesa->dma.free); + make_empty_list(&rmesa->dma.wait); + make_empty_list(&rmesa->dma.reserved); + rmesa->dma.minimum_size = MAX_DMA_BUF_SZ; +} + +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) +{ + struct radeon_dma_bo *dma_bo = NULL; + /* we set minimum sizes to at least requested size + aligned to next 16 bytes. */ + if (size > rmesa->dma.minimum_size) + rmesa->dma.minimum_size = (size + 15) & (~15); + + radeon_print(RADEON_DMA, RADEON_NORMAL, "%s size %d minimum_size %zi\n", + __func__, size, rmesa->dma.minimum_size); + + if (is_empty_list(&rmesa->dma.free) + || last_elem(&rmesa->dma.free)->bo->size < size) { + dma_bo = CALLOC_STRUCT(radeon_dma_bo); + assert(dma_bo); + +again_alloc: + dma_bo->bo = radeon_bo_open(rmesa->radeonScreen->bom, + 0, rmesa->dma.minimum_size, 4, + RADEON_GEM_DOMAIN_GTT, 0); + + if (!dma_bo->bo) { + rcommonFlushCmdBuf(rmesa, __func__); + goto again_alloc; + } + insert_at_head(&rmesa->dma.reserved, dma_bo); + } else { + /* We push and pop buffers from end of list so we can keep + counter on unused buffers for later freeing them from + begin of list */ + dma_bo = last_elem(&rmesa->dma.free); + remove_from_list(dma_bo); + insert_at_head(&rmesa->dma.reserved, dma_bo); + } + + rmesa->dma.current_used = 0; + rmesa->dma.current_vertexptr = 0; + + if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs, + first_elem(&rmesa->dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0)) + fprintf(stderr,"failure to revalidate BOs - badness\n"); + + if (is_empty_list(&rmesa->dma.reserved)) { + /* Cmd buff have been flushed in radeon_revalidate_bos */ + goto again_alloc; + } + radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1); +} + +/* Allocates a region from rmesa->dma.current. If there isn't enough + * space in current, grab a new buffer (and discard what was left of current) + */ +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment) +{ + if (RADEON_DEBUG & RADEON_IOCTL) + fprintf(stderr, "%s %d\n", __func__, bytes); + + if (rmesa->dma.flush) + rmesa->dma.flush(&rmesa->glCtx); + + assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); + + alignment--; + rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; + + if (is_empty_list(&rmesa->dma.reserved) + || rmesa->dma.current_used + bytes > first_elem(&rmesa->dma.reserved)->bo->size) + radeonRefillCurrentDmaRegion(rmesa, bytes); + + *poffset = rmesa->dma.current_used; + *pbo = first_elem(&rmesa->dma.reserved)->bo; + radeon_bo_ref(*pbo); + + /* Always align to at least 16 bytes */ + rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; + rmesa->dma.current_vertexptr = rmesa->dma.current_used; + + assert(rmesa->dma.current_used <= first_elem(&rmesa->dma.reserved)->bo->size); +} + +void radeonFreeDmaRegions(radeonContextPtr rmesa) +{ + struct radeon_dma_bo *dma_bo; + struct radeon_dma_bo *temp; + if (RADEON_DEBUG & RADEON_DMA) + fprintf(stderr, "%s\n", __func__); + + foreach_s(dma_bo, temp, &rmesa->dma.free) { + remove_from_list(dma_bo); + radeon_bo_unref(dma_bo->bo); + free(dma_bo); + } + + foreach_s(dma_bo, temp, &rmesa->dma.wait) { + remove_from_list(dma_bo); + radeon_bo_unref(dma_bo->bo); + free(dma_bo); + } + + foreach_s(dma_bo, temp, &rmesa->dma.reserved) { + remove_from_list(dma_bo); + radeon_bo_unref(dma_bo->bo); + free(dma_bo); + } +} + +void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes) +{ + if (is_empty_list(&rmesa->dma.reserved)) + return; + + if (RADEON_DEBUG & RADEON_IOCTL) + fprintf(stderr, "%s %d\n", __func__, return_bytes); + rmesa->dma.current_used -= return_bytes; + rmesa->dma.current_vertexptr = rmesa->dma.current_used; +} + +static int radeon_bo_is_idle(struct radeon_bo* bo) +{ + uint32_t domain; + int ret = radeon_bo_is_busy(bo, &domain); + if (ret == -EINVAL) { + WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n" + "This may cause small performance drop for you.\n"); + } + return ret != -EBUSY; +} + +void radeonReleaseDmaRegions(radeonContextPtr rmesa) +{ + struct radeon_dma_bo *dma_bo; + struct radeon_dma_bo *temp; + const int expire_at = ++rmesa->dma.free.expire_counter + DMA_BO_FREE_TIME; + const int time = rmesa->dma.free.expire_counter; + + if (RADEON_DEBUG & RADEON_DMA) { + size_t free = 0, + wait = 0, + reserved = 0; + foreach(dma_bo, &rmesa->dma.free) + ++free; + + foreach(dma_bo, &rmesa->dma.wait) + ++wait; + + foreach(dma_bo, &rmesa->dma.reserved) + ++reserved; + + fprintf(stderr, "%s: free %zu, wait %zu, reserved %zu, minimum_size: %zu\n", + __func__, free, wait, reserved, rmesa->dma.minimum_size); + } + + /* move waiting bos to free list. + wait list provides gpu time to handle data before reuse */ + foreach_s(dma_bo, temp, &rmesa->dma.wait) { + if (dma_bo->expire_counter == time) { + WARN_ONCE("Leaking dma buffer object!\n"); + radeon_bo_unref(dma_bo->bo); + remove_from_list(dma_bo); + free(dma_bo); + continue; + } + /* free objects that are too small to be used because of large request */ + if (dma_bo->bo->size < rmesa->dma.minimum_size) { + radeon_bo_unref(dma_bo->bo); + remove_from_list(dma_bo); + free(dma_bo); + continue; + } + if (!radeon_bo_is_idle(dma_bo->bo)) { + break; + } + remove_from_list(dma_bo); + dma_bo->expire_counter = expire_at; + insert_at_tail(&rmesa->dma.free, dma_bo); + } + + /* move reserved to wait list */ + foreach_s(dma_bo, temp, &rmesa->dma.reserved) { + radeon_bo_unmap(dma_bo->bo); + /* free objects that are too small to be used because of large request */ + if (dma_bo->bo->size < rmesa->dma.minimum_size) { + radeon_bo_unref(dma_bo->bo); + remove_from_list(dma_bo); + free(dma_bo); + continue; + } + remove_from_list(dma_bo); + dma_bo->expire_counter = expire_at; + insert_at_tail(&rmesa->dma.wait, dma_bo); + } + + /* free bos that have been unused for some time */ + foreach_s(dma_bo, temp, &rmesa->dma.free) { + if (dma_bo->expire_counter != time) + break; + remove_from_list(dma_bo); + radeon_bo_unref(dma_bo->bo); + free(dma_bo); + } + +} + + +/* Flush vertices in the current dma region. + */ +void rcommon_flush_last_swtcl_prim( struct gl_context *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_dma *dma = &rmesa->dma; + + if (RADEON_DEBUG & RADEON_IOCTL) + fprintf(stderr, "%s\n", __func__); + dma->flush = NULL; + + radeon_bo_unmap(rmesa->swtcl.bo); + + if (!is_empty_list(&dma->reserved)) { + GLuint current_offset = dma->current_used; + + assert (dma->current_used + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + dma->current_vertexptr); + + if (dma->current_used != dma->current_vertexptr) { + dma->current_used = dma->current_vertexptr; + + rmesa->vtbl.swtcl_flush(ctx, current_offset); + } + rmesa->swtcl.numverts = 0; + } + radeon_bo_unref(rmesa->swtcl.bo); + rmesa->swtcl.bo = NULL; +} +/* Alloc space in the current dma region. + */ +void * +rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) +{ + GLuint bytes = vsize * nverts; + void *head; + if (RADEON_DEBUG & RADEON_IOCTL) + fprintf(stderr, "%s\n", __func__); + + if(is_empty_list(&rmesa->dma.reserved) + ||rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) { + if (rmesa->dma.flush) { + rmesa->dma.flush(&rmesa->glCtx); + } + + radeonRefillCurrentDmaRegion(rmesa, bytes); + + return NULL; + } + + if (!rmesa->dma.flush) { + /* if cmdbuf flushed DMA restart */ + rmesa->glCtx.Driver.NeedFlush |= FLUSH_STORED_VERTICES; + rmesa->dma.flush = rcommon_flush_last_swtcl_prim; + } + + assert( vsize == rmesa->swtcl.vertex_size * 4 ); + assert( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); + assert( rmesa->dma.current_used + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + rmesa->dma.current_vertexptr ); + + if (!rmesa->swtcl.bo) { + rmesa->swtcl.bo = first_elem(&rmesa->dma.reserved)->bo; + radeon_bo_ref(rmesa->swtcl.bo); + radeon_bo_map(rmesa->swtcl.bo, 1); + } + + head = (rmesa->swtcl.bo->ptr + rmesa->dma.current_vertexptr); + rmesa->dma.current_vertexptr += bytes; + rmesa->swtcl.numverts += nverts; + return head; +} + +void radeonReleaseArrays( struct gl_context *ctx, GLuint newinputs ) +{ + radeonContextPtr radeon = RADEON_CONTEXT( ctx ); + int i; + if (RADEON_DEBUG & RADEON_IOCTL) + fprintf(stderr, "%s\n", __func__); + + if (radeon->dma.flush) { + radeon->dma.flush(&radeon->glCtx); + } + for (i = 0; i < radeon->tcl.aos_count; i++) { + if (radeon->tcl.aos[i].bo) { + radeon_bo_unref(radeon->tcl.aos[i].bo); + radeon->tcl.aos[i].bo = NULL; + + } + } +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_dma.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_dma.h new file mode 100644 index 000000000..db7b84ebd --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_dma.h @@ -0,0 +1,60 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef RADEON_DMA_H +#define RADEON_DMA_H + +void radeonEmitVec4(uint32_t *out, const GLvoid * data, int stride, int count); +void radeonEmitVec8(uint32_t *out, const GLvoid * data, int stride, int count); +void radeonEmitVec12(uint32_t *out, const GLvoid * data, int stride, int count); +void radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count); + +void rcommon_emit_vector(struct gl_context * ctx, struct radeon_aos *aos, + const GLvoid * data, int size, int stride, int count); +void rcommon_emit_vecfog(struct gl_context *ctx, struct radeon_aos *aos, + GLvoid *data, int stride, int count); + +void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes); +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); +void radeon_init_dma(radeonContextPtr rmesa); +void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes); +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment); +void radeonReleaseDmaRegions(radeonContextPtr rmesa); + +void rcommon_flush_last_swtcl_prim(struct gl_context *ctx); + +void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); +void radeonFreeDmaRegions(radeonContextPtr rmesa); +void radeonReleaseArrays( struct gl_context *ctx, GLuint newinputs ); +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_fbo.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_fbo.c new file mode 100644 index 000000000..439b95bf7 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_fbo.c @@ -0,0 +1,893 @@ +/************************************************************************** + * + * Copyright 2008 Red Hat Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "main/imports.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "main/enums.h" +#include "main/fbobject.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/context.h" +#include "swrast/swrast.h" +#include "drivers/common/meta.h" + +#include "radeon_common.h" +#include "radeon_mipmap_tree.h" + +#define FILE_DEBUG_FLAG RADEON_TEXTURE +#define DBG(...) do { \ + if (RADEON_DEBUG & FILE_DEBUG_FLAG) \ + printf(__VA_ARGS__); \ +} while(0) + +static void +radeon_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(rb %p, rrb %p) \n", + __func__, rb, rrb); + + assert(rrb); + + if (rrb && rrb->bo) { + radeon_bo_unref(rrb->bo); + } + _mesa_delete_renderbuffer(ctx, rb); +} + +#if defined(RADEON_R100) +static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLuint ba, address = 0; + + ba = (y >> 4) * (rrb->pitch >> 6) + (x >> 4); + + address |= (x & 0x7) << 2; + address |= (y & 0x3) << 5; + address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; + address |= (ba & 3) << 8; + address |= (y & 0x8) << 7; + address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; + address |= (ba & ~0x3) << 10; + return address; +} + +static GLuint get_depth_z16(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLuint ba, address = 0; /* a[0] = 0 */ + + ba = (y / 16) * (rrb->pitch >> 6) + (x / 32); + + address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ + address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ + address |= (x & 0x8) << 4; /* a[7] = x[3] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11] = x[4] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + return address; +} +#endif + +#if defined(RADEON_R200) +static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLuint offset; + GLuint b; + offset = 0; + b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5)); + offset += (b >> 1) << 12; + offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11; + offset += ((y >> 2) & 0x3) << 9; + offset += ((x >> 2) & 0x1) << 8; + offset += ((x >> 3) & 0x3) << 6; + offset += ((y >> 1) & 0x1) << 5; + offset += ((x >> 1) & 0x1) << 4; + offset += (y & 0x1) << 3; + offset += (x & 0x1) << 2; + + return offset; +} + +static GLuint get_depth_z16(const struct radeon_renderbuffer *rrb, + GLint x, GLint y) +{ + GLuint offset; + GLuint b; + + offset = 0; + b = (((y >> 4) * (rrb->pitch >> 7) + (x >> 6))); + offset += (b >> 1) << 12; + offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11; + offset += ((y >> 2) & 0x3) << 9; + offset += ((x >> 3) & 0x1) << 8; + offset += ((x >> 4) & 0x3) << 6; + offset += ((x >> 2) & 0x1) << 5; + offset += ((y >> 1) & 0x1) << 4; + offset += ((x >> 1) & 0x1) << 3; + offset += (y & 0x1) << 2; + offset += (x & 0x1) << 1; + + return offset; +} +#endif + +static void +radeon_map_renderbuffer_s8z24(struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + uint32_t *untiled_s8z24_map, *tiled_s8z24_map; + int ret; + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; + uint32_t pitch = w * rrb->cpp; + + rrb->map_pitch = pitch; + + rrb->map_buffer = malloc(w * h * 4); + ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); + assert(!ret); + (void) ret; + untiled_s8z24_map = rrb->map_buffer; + tiled_s8z24_map = rrb->bo->ptr; + + for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) { + for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { + uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; + uint32_t src_offset = get_depth_z32(rrb, x + pix_x, flipped_y); + uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; + untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4]; + } + } + + radeon_bo_unmap(rrb->bo); + + *out_map = rrb->map_buffer; + *out_stride = rrb->map_pitch; +} + +static void +radeon_map_renderbuffer_z16(struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + uint16_t *untiled_z16_map, *tiled_z16_map; + int ret; + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; + uint32_t pitch = w * rrb->cpp; + + rrb->map_pitch = pitch; + + rrb->map_buffer = malloc(w * h * 2); + ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); + assert(!ret); + (void) ret; + + untiled_z16_map = rrb->map_buffer; + tiled_z16_map = rrb->bo->ptr; + + for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) { + for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { + uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; + uint32_t src_offset = get_depth_z16(rrb, x + pix_x, flipped_y); + uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; + untiled_z16_map[dst_offset/2] = tiled_z16_map[src_offset/2]; + } + } + + radeon_bo_unmap(rrb->bo); + + *out_map = rrb->map_buffer; + *out_stride = rrb->map_pitch; +} + +static void +radeon_map_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride, + bool flip_y) +{ + struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + GLubyte *map; + GLboolean ok; + int stride, flip_stride; + int ret; + int src_x, src_y; + + /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */ + assert((rb->Name == 0) == flip_y); + + if (!rrb || !rrb->bo) { + *out_map = NULL; + *out_stride = 0; + return; + } + + rrb->map_mode = mode; + rrb->map_x = x; + rrb->map_y = y; + rrb->map_w = w; + rrb->map_h = h; + rrb->map_pitch = rrb->pitch; + + ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp); + if (ok) { + if (rb->Name) { + src_x = x; + src_y = y; + } else { + src_x = x; + src_y = rrb->base.Base.Height - y - h; + } + + /* Make a temporary buffer and blit the current contents of the renderbuffer + * out to it. This gives us linear access to the buffer, instead of having + * to do detiling in software. + */ + + rrb->map_pitch = rrb->pitch; + + assert(!rrb->map_bo); + rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0, + rrb->map_pitch * h, 4, + RADEON_GEM_DOMAIN_GTT, 0); + + ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset, + rb->Format, rrb->pitch / rrb->cpp, + rb->Width, rb->Height, + src_x, src_y, + rrb->map_bo, 0, + rb->Format, rrb->map_pitch / rrb->cpp, + w, h, + 0, 0, + w, h, + GL_FALSE); + assert(ok); + + ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT)); + assert(!ret); + + map = rrb->map_bo->ptr; + + if (rb->Name) { + *out_map = map; + *out_stride = rrb->map_pitch; + } else { + *out_map = map + (h - 1) * rrb->map_pitch; + *out_stride = -rrb->map_pitch; + } + return; + } + + /* sw fallback flush stuff */ + if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + + if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) { + if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) { + radeon_map_renderbuffer_s8z24(rb, x, y, w, h, + mode, out_map, out_stride); + return; + } + if (rb->Format == MESA_FORMAT_Z_UNORM16) { + radeon_map_renderbuffer_z16(rb, x, y, w, h, + mode, out_map, out_stride); + return; + } + } + + ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); + assert(!ret); + (void) ret; + + map = rrb->bo->ptr; + stride = rrb->map_pitch; + + if (rb->Name == 0) { + y = rb->Height - 1 - y; + flip_stride = -stride; + } else { + flip_stride = stride; + map += rrb->draw_offset; + } + + map += x * rrb->cpp; + map += (int)y * stride; + + *out_map = map; + *out_stride = flip_stride; +} + +static void +radeon_unmap_renderbuffer_s8z24(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + + if (!rrb->map_buffer) + return; + + if (rrb->map_mode & GL_MAP_WRITE_BIT) { + uint32_t *untiled_s8z24_map = rrb->map_buffer; + uint32_t *tiled_s8z24_map; + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; + + radeon_bo_map(rrb->bo, 1); + + tiled_s8z24_map = rrb->bo->ptr; + + for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) { + for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) { + uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias; + uint32_t dst_offset = get_depth_z32(rrb, rrb->map_x + pix_x, flipped_y); + uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; + tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4]; + } + } + radeon_bo_unmap(rrb->bo); + } + free(rrb->map_buffer); + rrb->map_buffer = NULL; +} + +static void +radeon_unmap_renderbuffer_z16(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + + if (!rrb->map_buffer) + return; + + if (rrb->map_mode & GL_MAP_WRITE_BIT) { + uint16_t *untiled_z16_map = rrb->map_buffer; + uint16_t *tiled_z16_map; + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; + + radeon_bo_map(rrb->bo, 1); + + tiled_z16_map = rrb->bo->ptr; + + for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) { + for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) { + uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias; + uint32_t dst_offset = get_depth_z16(rrb, rrb->map_x + pix_x, flipped_y); + uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; + tiled_z16_map[dst_offset/2] = untiled_z16_map[src_offset/2]; + } + } + radeon_bo_unmap(rrb->bo); + } + free(rrb->map_buffer); + rrb->map_buffer = NULL; +} + + +static void +radeon_unmap_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + + if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) { + if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) { + radeon_unmap_renderbuffer_s8z24(ctx, rb); + return; + } + if (rb->Format == MESA_FORMAT_Z_UNORM16) { + radeon_unmap_renderbuffer_z16(ctx, rb); + return; + } + } + + if (!rrb->map_bo) { + if (rrb->bo) + radeon_bo_unmap(rrb->bo); + return; + } + + radeon_bo_unmap(rrb->map_bo); + + if (rrb->map_mode & GL_MAP_WRITE_BIT) { + GLboolean ok; + ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0, + rb->Format, rrb->map_pitch / rrb->cpp, + rrb->map_w, rrb->map_h, + 0, 0, + rrb->bo, rrb->draw_offset, + rb->Format, rrb->pitch / rrb->cpp, + rb->Width, rb->Height, + rrb->map_x, rrb->map_y, + rrb->map_w, rrb->map_h, + GL_FALSE); + assert(ok); + (void) ok; + } + + radeon_bo_unref(rrb->map_bo); + rrb->map_bo = NULL; +} + + +/** + * Called via glRenderbufferStorageEXT() to set the format and allocate + * storage for a user-created renderbuffer. + */ +static GLboolean +radeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct radeon_context *radeon = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + uint32_t size, pitch; + int cpp; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, rb %p) \n", + __func__, ctx, rb); + + assert(rb->Name != 0); + switch (internalFormat) { + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + rb->Format = _radeon_texformat_rgb565; + cpp = 2; + break; + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + rb->Format = _radeon_texformat_argb8888; + cpp = 4; + break; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + rb->Format = _radeon_texformat_argb8888; + cpp = 4; + break; + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + case GL_STENCIL_INDEX16_EXT: + /* alloc a depth+stencil buffer */ + rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT; + cpp = 4; + break; + case GL_DEPTH_COMPONENT16: + rb->Format = MESA_FORMAT_Z_UNORM16; + cpp = 2; + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + rb->Format = MESA_FORMAT_Z24_UNORM_X8_UINT; + cpp = 4; + break; + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT; + cpp = 4; + break; + default: + _mesa_problem(ctx, + "Unexpected format in radeon_alloc_renderbuffer_storage"); + return GL_FALSE; + } + + rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); + + if (ctx->Driver.Flush) + ctx->Driver.Flush(ctx); /* +r6/r7 */ + + if (rrb->bo) + radeon_bo_unref(rrb->bo); + + pitch = ((cpp * width + 63) & ~63) / cpp; + + if (RADEON_DEBUG & RADEON_MEMORY) + fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, + height, pitch); + + size = pitch * height * cpp; + rrb->pitch = pitch * cpp; + rrb->cpp = cpp; + rrb->bo = radeon_bo_open(radeon->radeonScreen->bom, + 0, + size, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + rb->Width = width; + rb->Height = height; + return GL_TRUE; +} + +static void +radeon_image_target_renderbuffer_storage(struct gl_context *ctx, + struct gl_renderbuffer *rb, + void *image_handle) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrb; + __DRIscreen *screen; + __DRIimage *image; + + screen = radeon->radeonScreen->driScreen; + image = screen->dri2.image->lookupEGLImage(screen, image_handle, + screen->loaderPrivate); + if (image == NULL) + return; + + rrb = radeon_renderbuffer(rb); + + if (ctx->Driver.Flush) + ctx->Driver.Flush(ctx); /* +r6/r7 */ + + if (rrb->bo) + radeon_bo_unref(rrb->bo); + rrb->bo = image->bo; + radeon_bo_ref(rrb->bo); + fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle, + image->width, image->pitch); + + rrb->cpp = image->cpp; + rrb->pitch = image->pitch * image->cpp; + + rb->Format = image->format; + rb->InternalFormat = image->internal_format; + rb->Width = image->width; + rb->Height = image->height; + rb->Format = image->format; + rb->_BaseFormat = _mesa_base_fbo_format(&radeon->glCtx, + image->internal_format); + rb->NeedsFinishRenderTexture = GL_TRUE; +} + +/** + * Called for each hardware renderbuffer when a _window_ is resized. + * Just update fields. + * Not used for user-created renderbuffers! + */ +static GLboolean +radeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + assert(rb->Name == 0); + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, rb %p) \n", + __func__, ctx, rb); + + + return GL_TRUE; +} + +/** Dummy function for gl_renderbuffer::AllocStorage() */ +static GLboolean +radeon_nop_alloc_storage(struct gl_context * ctx, + UNUSED struct gl_renderbuffer *rb, + UNUSED GLenum internalFormat, + UNUSED GLuint width, + UNUSED GLuint height) +{ + _mesa_problem(ctx, "radeon_op_alloc_storage should never be called."); + return GL_FALSE; +} + + +/** + * Create a renderbuffer for a window's color, depth and/or stencil buffer. + * Not used for user-created renderbuffers. + */ +struct radeon_renderbuffer * +radeon_create_renderbuffer(mesa_format format, __DRIdrawable *driDrawPriv) +{ + struct radeon_renderbuffer *rrb; + struct gl_renderbuffer *rb; + + rrb = CALLOC_STRUCT(radeon_renderbuffer); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s( rrb %p ) \n", + __func__, rrb); + + if (!rrb) + return NULL; + + rb = &rrb->base.Base; + + _mesa_init_renderbuffer(rb, 0); + rb->ClassID = RADEON_RB_CLASS; + rb->Format = format; + rb->_BaseFormat = _mesa_get_format_base_format(format); + rb->InternalFormat = _mesa_get_format_base_format(format); + + rrb->dPriv = driDrawPriv; + + rb->Delete = radeon_delete_renderbuffer; + rb->AllocStorage = radeon_alloc_window_storage; + + rrb->bo = NULL; + return rrb; +} + +static struct gl_renderbuffer * +radeon_new_renderbuffer(struct gl_context * ctx, GLuint name) +{ + struct radeon_renderbuffer *rrb; + struct gl_renderbuffer *rb; + + + rrb = CALLOC_STRUCT(radeon_renderbuffer); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, rrb %p) \n", + __func__, ctx, rrb); + + if (!rrb) + return NULL; + + rb = &rrb->base.Base; + + _mesa_init_renderbuffer(rb, name); + rb->ClassID = RADEON_RB_CLASS; + rb->Delete = radeon_delete_renderbuffer; + rb->AllocStorage = radeon_alloc_renderbuffer_storage; + + return rb; +} + +static void +radeon_bind_framebuffer(struct gl_context * ctx, GLenum target, + struct gl_framebuffer *fb, struct gl_framebuffer *fbread) +{ + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, fb %p, target %s) \n", + __func__, ctx, fb, + _mesa_enum_to_string(target)); + + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + radeon_draw_buffer(ctx, fb); + } + else { + /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ + } +} + +static void +radeon_framebuffer_renderbuffer(struct gl_context * ctx, + struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + + if (ctx->Driver.Flush) + ctx->Driver.Flush(ctx); /* +r6/r7 */ + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, fb %p, rb %p) \n", + __func__, ctx, fb, rb); + + _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb); + radeon_draw_buffer(ctx, fb); +} + +static GLboolean +radeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb, + struct gl_texture_image *texImage) +{ + struct gl_renderbuffer *rb = &rrb->base.Base; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, rrb %p, texImage %p, texFormat %s) \n", + __func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat)); + + rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat); + rrb->pitch = texImage->Width * rrb->cpp; + rb->Format = texImage->TexFormat; + rb->InternalFormat = texImage->InternalFormat; + rb->_BaseFormat = _mesa_get_format_base_format(rb->Format); + rb->Width = texImage->Width; + rb->Height = texImage->Height; + rb->Delete = radeon_delete_renderbuffer; + rb->AllocStorage = radeon_nop_alloc_storage; + + return GL_TRUE; +} + +static void +radeon_render_texture(struct gl_context * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_renderbuffer *rb = att->Renderbuffer; + struct gl_texture_image *newImage = rb->TexImage; + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + radeon_texture_image *radeon_image; + GLuint imageOffset; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, fb %p, rrb %p, att %p)\n", + __func__, ctx, fb, rrb, att); + + (void) fb; + + assert(newImage); + + radeon_image = (radeon_texture_image *)newImage; + + if (!radeon_image->mt) { + /* Fallback on drawing to a texture without a miptree. + */ + _swrast_render_texture(ctx, fb, att); + return; + } + + if (!radeon_update_wrapper(ctx, rrb, newImage)) { + _swrast_render_texture(ctx, fb, att); + return; + } + + DBG("Begin render texture tex=%u w=%d h=%d refcount=%d\n", + att->Texture->Name, newImage->Width, newImage->Height, + rb->RefCount); + + /* point the renderbufer's region to the texture image region */ + if (rrb->bo != radeon_image->mt->bo) { + if (rrb->bo) + radeon_bo_unref(rrb->bo); + rrb->bo = radeon_image->mt->bo; + radeon_bo_ref(rrb->bo); + } + + /* compute offset of the particular 2D image within the texture region */ + imageOffset = radeon_miptree_image_offset(radeon_image->mt, + att->CubeMapFace, + att->TextureLevel); + + if (att->Texture->Target == GL_TEXTURE_3D) { + imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride * + radeon_image->mt->levels[att->TextureLevel].height * + att->Zoffset; + } + + /* store that offset in the region, along with the correct pitch for + * the image we are rendering to */ + rrb->draw_offset = imageOffset; + rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride; + radeon_image->used_as_render_target = GL_TRUE; + + /* update drawing region, etc */ + radeon_draw_buffer(ctx, fb); +} + +static void +radeon_finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + struct gl_texture_image *image = rb->TexImage; + radeon_texture_image *radeon_image = (radeon_texture_image *)image; + + if (radeon_image) + radeon_image->used_as_render_target = GL_FALSE; + + if (ctx->Driver.Flush) + ctx->Driver.Flush(ctx); /* +r6/r7 */ +} +static void +radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + mesa_format mesa_format; + int i; + + for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) { + struct gl_renderbuffer_attachment *att; + if (i == -2) { + att = &fb->Attachment[BUFFER_DEPTH]; + } else if (i == -1) { + att = &fb->Attachment[BUFFER_STENCIL]; + } else { + att = &fb->Attachment[BUFFER_COLOR0 + i]; + } + + if (att->Type == GL_TEXTURE) { + mesa_format = att->Renderbuffer->TexImage->TexFormat; + } else { + /* All renderbuffer formats are renderable, but not sampable */ + continue; + } + + if (!radeon->vtbl.is_format_renderable(mesa_format)){ + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s: HW doesn't support format %s as output format of attachment %d\n", + __func__, _mesa_get_format_name(mesa_format), i); + return; + } + } +} + +void radeon_fbo_init(struct radeon_context *radeon) +{ + radeon->glCtx.Driver.NewRenderbuffer = radeon_new_renderbuffer; + radeon->glCtx.Driver.MapRenderbuffer = radeon_map_renderbuffer; + radeon->glCtx.Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer; + radeon->glCtx.Driver.BindFramebuffer = radeon_bind_framebuffer; + radeon->glCtx.Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer; + radeon->glCtx.Driver.RenderTexture = radeon_render_texture; + radeon->glCtx.Driver.FinishRenderTexture = radeon_finish_render_texture; + radeon->glCtx.Driver.ValidateFramebuffer = radeon_validate_framebuffer; + radeon->glCtx.Driver.BlitFramebuffer = _mesa_meta_and_swrast_BlitFramebuffer; + radeon->glCtx.Driver.EGLImageTargetRenderbufferStorage = + radeon_image_target_renderbuffer_storage; +} + + +void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, + struct radeon_bo *bo) +{ + struct radeon_bo *old; + old = rb->bo; + rb->bo = bo; + radeon_bo_ref(bo); + if (old) + radeon_bo_unref(old); +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_fog.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_fog.c new file mode 100644 index 000000000..d5c653703 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_fog.c @@ -0,0 +1,127 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VMware, Inc. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + +#include "c99_math.h" +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/mtypes.h" +#include "main/enums.h" +#include "main/macros.h" + +#include "radeon_screen.h" +#include "radeon_fog.h" + +/**********************************************************************/ +/* Fog blend factor computation for hw tcl */ +/* same calculation used as in t_vb_fog.c */ +/**********************************************************************/ + +#define FOG_EXP_TABLE_SIZE 256 +#define FOG_MAX (10.0) +#define EXP_FOG_MAX .0006595 +#define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE) +static GLfloat exp_table[FOG_EXP_TABLE_SIZE]; + +#if 1 +#define NEG_EXP( result, narg ) \ +do { \ + GLfloat f = (GLfloat) (narg * (1.0/FOG_INCR)); \ + GLint k = (GLint) f; \ + if (k > FOG_EXP_TABLE_SIZE-2) \ + result = (GLfloat) EXP_FOG_MAX; \ + else \ + result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]); \ +} while (0) +#else +#define NEG_EXP( result, narg ) \ +do { \ + result = exp(-narg); \ +} while (0) +#endif + + +/** + * Initialize the exp_table[] lookup table for approximating exp(). + */ +void +radeonInitStaticFogData( void ) +{ + GLfloat f = 0.0F; + GLint i = 0; + for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) { + exp_table[i] = (GLfloat) exp(-f); + } +} + +/** + * Compute per-vertex fog blend factors from fog coordinates by + * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function. + * Fog coordinates are distances from the eye (typically between the + * near and far clip plane distances). + * Note the fog (eye Z) coords may be negative so we use ABS(z) below. + * Fog blend factors are in the range [0,1]. + */ +float +radeonComputeFogBlendFactor( struct gl_context *ctx, GLfloat fogcoord ) +{ + GLfloat end = ctx->Fog.End; + GLfloat d, temp; + const GLfloat z = fabsf(fogcoord); + + switch (ctx->Fog.Mode) { + case GL_LINEAR: + if (ctx->Fog.Start == ctx->Fog.End) + d = 1.0F; + else + d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); + temp = (end - z) * d; + return CLAMP(temp, 0.0F, 1.0F); + break; + case GL_EXP: + d = ctx->Fog.Density; + NEG_EXP( temp, d * z ); + return temp; + break; + case GL_EXP2: + d = ctx->Fog.Density*ctx->Fog.Density; + NEG_EXP( temp, d * z * z ); + return temp; + break; + default: + _mesa_problem(ctx, "Bad fog mode in make_fog_coord"); + return 0; + } +} + diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_fog.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_fog.h new file mode 100644 index 000000000..ea2054641 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_fog.h @@ -0,0 +1,44 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VMware, Inc. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@vmware.com> + */ + +#ifndef RADEON_FOG_H +#define RADEON_FOG_H + +void +radeonInitStaticFogData( void ); + +float +radeonComputeFogBlendFactor( struct gl_context *ctx, GLfloat fogcoord ); + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_mipmap_tree.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_mipmap_tree.c new file mode 100644 index 000000000..8d01e21db --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_mipmap_tree.c @@ -0,0 +1,579 @@ +/* + * Copyright (C) 2009 Maciej Cencora. + * Copyright (C) 2008 Nicolai Haehnle. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_mipmap_tree.h" + +#include <errno.h> +#include <unistd.h> + +#include "main/teximage.h" +#include "main/texobj.h" +#include "main/enums.h" +#include "radeon_texture.h" +#include "radeon_tile.h" + +static unsigned get_aligned_compressed_row_stride( + mesa_format format, + unsigned width, + unsigned minStride) +{ + const unsigned blockBytes = _mesa_get_format_bytes(format); + unsigned blockWidth, blockHeight; + unsigned stride; + + _mesa_get_format_block_size(format, &blockWidth, &blockHeight); + + /* Count number of blocks required to store the given width. + * And then multiple it with bytes required to store a block. + */ + stride = (width + blockWidth - 1) / blockWidth * blockBytes; + + /* Round the given minimum stride to the next full blocksize. + * (minStride + blockBytes - 1) / blockBytes * blockBytes + */ + if ( stride < minStride ) + stride = (minStride + blockBytes - 1) / blockBytes * blockBytes; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s width %u, minStride %u, block(bytes %u, width %u):" + "stride %u\n", + __func__, width, minStride, + blockBytes, blockWidth, + stride); + + return stride; +} + +unsigned get_texture_image_size( + mesa_format format, + unsigned rowStride, + unsigned height, + unsigned depth, + unsigned tiling) +{ + if (_mesa_is_format_compressed(format)) { + unsigned blockWidth, blockHeight; + + _mesa_get_format_block_size(format, &blockWidth, &blockHeight); + + return rowStride * ((height + blockHeight - 1) / blockHeight) * depth; + } else if (tiling) { + /* Need to align height to tile height */ + unsigned tileWidth, tileHeight; + + get_tile_size(format, &tileWidth, &tileHeight); + tileHeight--; + + height = (height + tileHeight) & ~tileHeight; + } + + return rowStride * height * depth; +} + +unsigned get_texture_image_row_stride(radeonContextPtr rmesa, mesa_format format, unsigned width, unsigned tiling, GLuint target) +{ + if (_mesa_is_format_compressed(format)) { + return get_aligned_compressed_row_stride(format, width, rmesa->texture_compressed_row_align); + } else { + unsigned row_align; + + if (!_mesa_is_pow_two(width) || target == GL_TEXTURE_RECTANGLE) { + row_align = rmesa->texture_rect_row_align - 1; + } else if (tiling) { + unsigned tileWidth, tileHeight; + get_tile_size(format, &tileWidth, &tileHeight); + row_align = tileWidth * _mesa_get_format_bytes(format) - 1; + } else { + row_align = rmesa->texture_row_align - 1; + } + + return (_mesa_format_row_stride(format, width) + row_align) & ~row_align; + } +} + +/** + * Compute sizes and fill in offset and blit information for the given + * image (determined by \p face and \p level). + * + * \param curOffset points to the offset at which the image is to be stored + * and is updated by this function according to the size of the image. + */ +static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree *mt, + GLuint face, GLuint level, GLuint* curOffset) +{ + radeon_mipmap_level *lvl = &mt->levels[level]; + GLuint height; + + height = _mesa_next_pow_two_32(lvl->height); + + lvl->rowstride = get_texture_image_row_stride(rmesa, mt->mesaFormat, lvl->width, mt->tilebits, mt->target); + lvl->size = get_texture_image_size(mt->mesaFormat, lvl->rowstride, height, lvl->depth, mt->tilebits); + + assert(lvl->size > 0); + + lvl->faces[face].offset = *curOffset; + *curOffset += lvl->size; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p) level %d, face %d: rs:%d %dx%d at %d\n", + __func__, rmesa, + level, face, + lvl->rowstride, lvl->width, height, lvl->faces[face].offset); +} + +static void calculate_miptree_layout(radeonContextPtr rmesa, radeon_mipmap_tree *mt) +{ + GLuint curOffset, i, face, level; + + assert(1 << (mt->numLevels - 1) <= rmesa->glCtx.Const.MaxTextureSize); + + curOffset = 0; + for(face = 0; face < mt->faces; face++) { + + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); + } + } + + /* Note the required size in memory */ + mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, %p) total size %d\n", + __func__, rmesa, mt, mt->totalsize); +} + +/** + * Create a new mipmap tree, calculate its layout and allocate memory. + */ +radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, + GLenum target, mesa_format mesaFormat, GLuint baseLevel, GLuint numLevels, + GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits) +{ + radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); + + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p) new tree is %p.\n", + __func__, rmesa, mt); + + mt->mesaFormat = mesaFormat; + mt->refcount = 1; + mt->target = target; + mt->faces = _mesa_num_tex_faces(target); + mt->baseLevel = baseLevel; + mt->numLevels = numLevels; + mt->width0 = width0; + mt->height0 = height0; + mt->depth0 = depth0; + mt->tilebits = tilebits; + + calculate_miptree_layout(rmesa, mt); + + mt->bo = radeon_bo_open(rmesa->radeonScreen->bom, + 0, mt->totalsize, 1024, + RADEON_GEM_DOMAIN_VRAM, + 0); + + return mt; +} + +void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr) +{ + assert(!*ptr); + + mt->refcount++; + assert(mt->refcount > 0); + + *ptr = mt; +} + +void radeon_miptree_unreference(radeon_mipmap_tree **ptr) +{ + radeon_mipmap_tree *mt = *ptr; + if (!mt) + return; + + assert(mt->refcount > 0); + + mt->refcount--; + if (!mt->refcount) { + radeon_bo_unref(mt->bo); + free(mt); + } + + *ptr = 0; +} + +/** + * Calculate min and max LOD for the given texture object. + * @param[in] tObj texture object whose LOD values to calculate + * @param[out] pminLod minimal LOD + * @param[out] pmaxLod maximal LOD + */ +static void calculate_min_max_lod(struct gl_sampler_object *samp, struct gl_texture_object *tObj, + unsigned *pminLod, unsigned *pmaxLod) +{ + int minLod, maxLod; + /* Yes, this looks overly complicated, but it's all needed. + */ + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (samp->MinFilter == GL_NEAREST || samp->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + minLod = maxLod = tObj->BaseLevel; + } else { + minLod = tObj->BaseLevel + (GLint)(samp->MinLod); + minLod = MAX2(minLod, tObj->BaseLevel); + minLod = MIN2(minLod, tObj->MaxLevel); + maxLod = tObj->BaseLevel + (GLint)(samp->MaxLod + 0.5); + maxLod = MIN2(maxLod, tObj->MaxLevel); + maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxNumLevels - 1 + minLod); + maxLod = MAX2(maxLod, minLod); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + minLod = maxLod = 0; + break; + default: + return; + } + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p) target %s, min %d, max %d.\n", + __func__, tObj, + _mesa_enum_to_string(tObj->Target), + minLod, maxLod); + + /* save these values */ + *pminLod = minLod; + *pmaxLod = maxLod; +} + +/** + * Checks whether the given miptree can hold the given texture image at the + * given face and level. + */ +GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, + struct gl_texture_image *texImage) +{ + radeon_mipmap_level *lvl; + GLuint level = texImage->Level; + if (texImage->TexFormat != mt->mesaFormat) + return GL_FALSE; + + lvl = &mt->levels[level]; + if (!lvl->valid || + lvl->width != texImage->Width || + lvl->height != texImage->Height || + lvl->depth != texImage->Depth) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Checks whether the given miptree has the right format to store the given texture object. + */ +static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj) +{ + struct gl_texture_image *firstImage; + unsigned numLevels; + radeon_mipmap_level *mtBaseLevel; + + if (texObj->BaseLevel < mt->baseLevel) + return GL_FALSE; + + mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel]; + firstImage = texObj->Image[0][texObj->BaseLevel]; + numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxNumLevels); + + if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { + fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); + fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target); + fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat); + fprintf(stderr, "numLevels %d vs %d\n", mt->numLevels, numLevels); + fprintf(stderr, "width0 %d vs %d\n", mtBaseLevel->width, firstImage->Width); + fprintf(stderr, "height0 %d vs %d\n", mtBaseLevel->height, firstImage->Height); + fprintf(stderr, "depth0 %d vs %d\n", mtBaseLevel->depth, firstImage->Depth); + if (mt->target == texObj->Target && + mt->mesaFormat == firstImage->TexFormat && + mt->numLevels >= numLevels && + mtBaseLevel->width == firstImage->Width && + mtBaseLevel->height == firstImage->Height && + mtBaseLevel->depth == firstImage->Depth) { + fprintf(stderr, "MATCHED\n"); + } else { + fprintf(stderr, "NOT MATCHED\n"); + } + } + + return (mt->target == texObj->Target && + mt->mesaFormat == firstImage->TexFormat && + mt->numLevels >= numLevels && + mtBaseLevel->width == firstImage->Width && + mtBaseLevel->height == firstImage->Height && + mtBaseLevel->depth == firstImage->Depth); +} + +/** + * Try to allocate a mipmap tree for the given texture object. + * @param[in] rmesa radeon context + * @param[in] t radeon texture object + */ +void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) +{ + struct gl_texture_object *texObj = &t->base; + struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; + GLuint numLevels; + assert(!t->mt); + + if (!texImg) { + radeon_warning("%s(%p) No image in given texture object(%p).\n", + __func__, rmesa, t); + return; + } + + + numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxNumLevels); + + t->mt = radeon_miptree_create(rmesa, t->base.Target, + texImg->TexFormat, texObj->BaseLevel, + numLevels, texImg->Width, texImg->Height, + texImg->Depth, t->tile_bits); +} + +GLuint +radeon_miptree_image_offset(radeon_mipmap_tree *mt, + GLuint face, GLuint level) +{ + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) + return (mt->levels[level].faces[face].offset); + else + return mt->levels[level].faces[0].offset; +} + +/** + * Ensure that the given image is stored in the given miptree from now on. + */ +static void migrate_image_to_miptree(radeon_mipmap_tree *mt, + radeon_texture_image *image, + int face, int level) +{ + radeon_mipmap_level *dstlvl = &mt->levels[level]; + unsigned char *dest; + + assert(image->mt != mt); + assert(dstlvl->valid); + assert(dstlvl->width == image->base.Base.Width); + assert(dstlvl->height == image->base.Base.Height); + assert(dstlvl->depth == image->base.Base.Depth); + + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s miptree %p, image %p, face %d, level %d.\n", + __func__, mt, image, face, level); + + radeon_bo_map(mt->bo, GL_TRUE); + dest = mt->bo->ptr + dstlvl->faces[face].offset; + + if (image->mt) { + /* Format etc. should match, so we really just need a memcpy(). + * In fact, that memcpy() could be done by the hardware in many + * cases, provided that we have a proper memory manager. + */ + assert(mt->mesaFormat == image->base.Base.TexFormat); + + radeon_mipmap_level *srclvl = &image->mt->levels[image->base.Base.Level]; + + assert(image->base.Base.Level == level); + assert(srclvl->size == dstlvl->size); + assert(srclvl->rowstride == dstlvl->rowstride); + + radeon_bo_map(image->mt->bo, GL_FALSE); + + memcpy(dest, + image->mt->bo->ptr + srclvl->faces[face].offset, + dstlvl->size); + radeon_bo_unmap(image->mt->bo); + + radeon_miptree_unreference(&image->mt); + } + + radeon_bo_unmap(mt->bo); + + radeon_miptree_reference(mt, &image->mt); +} + +/** + * Filter matching miptrees, and select one with the most of data. + * @param[in] texObj radeon texture object + * @param[in] firstLevel first texture level to check + * @param[in] lastLevel last texture level to check + */ +static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, + unsigned firstLevel, + unsigned lastLevel) +{ + const unsigned numLevels = lastLevel - firstLevel + 1; + unsigned *mtSizes = calloc(numLevels, sizeof(unsigned)); + radeon_mipmap_tree **mts = calloc(numLevels, sizeof(radeon_mipmap_tree *)); + unsigned mtCount = 0; + unsigned maxMtIndex = 0; + radeon_mipmap_tree *tmp; + unsigned int level; + int i; + + for (level = firstLevel; level <= lastLevel; ++level) { + radeon_texture_image *img = get_radeon_texture_image(texObj->base.Image[0][level]); + unsigned found = 0; + // TODO: why this hack?? + if (!img) + break; + + if (!img->mt) + continue; + + for (i = 0; i < mtCount; ++i) { + if (mts[i] == img->mt) { + found = 1; + mtSizes[i] += img->mt->levels[img->base.Base.Level].size; + break; + } + } + + if (!found && radeon_miptree_matches_texture(img->mt, &texObj->base)) { + mtSizes[mtCount] = img->mt->levels[img->base.Base.Level].size; + mts[mtCount] = img->mt; + mtCount++; + } + } + + if (mtCount == 0) { + free(mtSizes); + free(mts); + return NULL; + } + + for (i = 1; i < mtCount; ++i) { + if (mtSizes[i] > mtSizes[maxMtIndex]) { + maxMtIndex = i; + } + } + + tmp = mts[maxMtIndex]; + free(mtSizes); + free(mts); + + return tmp; +} + +/** + * Validate texture mipmap tree. + * If individual images are stored in different mipmap trees + * use the mipmap tree that has the most of the correct data. + */ +int radeon_validate_texture_miptree(struct gl_context * ctx, + struct gl_sampler_object *samp, + struct gl_texture_object *texObj) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_mipmap_tree *dst_miptree; + + if (samp == &texObj->Sampler && (t->validated || t->image_override)) { + return GL_TRUE; + } + + calculate_min_max_lod(samp, &t->base, &t->minLod, &t->maxLod); + + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", + __func__, texObj ,t->minLod, t->maxLod); + + dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base._MaxLevel); + + radeon_miptree_unreference(&t->mt); + if (!dst_miptree) { + radeon_try_alloc_miptree(rmesa, t); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: No matching miptree found, allocated new one %p\n", + __func__, t->mt); + + } else { + radeon_miptree_reference(dst_miptree, &t->mt); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: Using miptree %p\n", __func__, t->mt); + } + + const unsigned faces = _mesa_num_tex_faces(texObj->Target); + unsigned face, level; + radeon_texture_image *img; + /* Validate only the levels that will actually be used during rendering */ + for (face = 0; face < faces; ++face) { + for (level = t->minLod; level <= t->maxLod; ++level) { + img = get_radeon_texture_image(texObj->Image[face][level]); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "Checking image level %d, face %d, mt %p ... ", + level, face, img->mt); + + if (img->mt != t->mt && !img->used_as_render_target) { + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "MIGRATING\n"); + + struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; + if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + migrate_image_to_miptree(t->mt, img, face, level); + } else + radeon_print(RADEON_TEXTURE, RADEON_TRACE, "OK\n"); + } + } + + t->validated = GL_TRUE; + + return GL_TRUE; +} + +uint32_t get_base_teximage_offset(radeonTexObj *texObj) +{ + if (!texObj->mt) { + return 0; + } else { + return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod); + } +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_mipmap_tree.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_mipmap_tree.h new file mode 100644 index 000000000..f919a581b --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_mipmap_tree.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __RADEON_MIPMAP_TREE_H_ +#define __RADEON_MIPMAP_TREE_H_ + +#include "radeon_common.h" + +typedef struct _radeon_mipmap_tree radeon_mipmap_tree; +typedef struct _radeon_mipmap_level radeon_mipmap_level; +typedef struct _radeon_mipmap_image radeon_mipmap_image; + +struct _radeon_mipmap_image { + GLuint offset; /** Offset of this image from the start of mipmap tree buffer, in bytes */ +}; + +struct _radeon_mipmap_level { + GLuint width; + GLuint height; + GLuint depth; + GLuint size; /** Size of each image, in bytes */ + GLuint rowstride; /** in bytes */ + GLuint valid; + radeon_mipmap_image faces[6]; +}; + +/* store the max possible in the miptree */ +#define RADEON_MIPTREE_MAX_TEXTURE_LEVELS 15 + +/** + * A mipmap tree contains texture images in the layout that the hardware + * expects. + * + * The meta-data of mipmap trees is immutable, i.e. you cannot change the + * layout on-the-fly; however, the texture contents (i.e. texels) can be + * changed. + */ +struct _radeon_mipmap_tree { + struct radeon_bo *bo; + GLuint refcount; + + GLuint totalsize; /** total size of the miptree, in bytes */ + + GLenum target; /** GL_TEXTURE_xxx */ + GLenum mesaFormat; /** MESA_FORMAT_xxx */ + GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */ + GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */ + GLuint numLevels; /** Number of mip levels stored in this mipmap tree */ + + GLuint width0; /** Width of baseLevel image */ + GLuint height0; /** Height of baseLevel image */ + GLuint depth0; /** Depth of baseLevel image */ + + GLuint tilebits; /** RADEON_TXO_xxx_TILE */ + + radeon_mipmap_level levels[RADEON_MIPTREE_MAX_TEXTURE_LEVELS]; +}; + +void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr); +void radeon_miptree_unreference(radeon_mipmap_tree **ptr); + +GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, + struct gl_texture_image *texImage); + +void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t); +GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, + GLuint face, GLuint level); +uint32_t get_base_teximage_offset(radeonTexObj *texObj); + +unsigned get_texture_image_row_stride(radeonContextPtr rmesa, mesa_format format, unsigned width, unsigned tiling, unsigned target); + +unsigned get_texture_image_size( + mesa_format format, + unsigned rowStride, + unsigned height, + unsigned depth, + unsigned tiling); + +radeon_mipmap_tree *radeon_miptree_create(radeonContextPtr rmesa, + GLenum target, mesa_format mesaFormat, GLuint baseLevel, GLuint numLevels, + GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits); +#endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_pixel_read.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_pixel_read.c new file mode 100644 index 000000000..e115b749d --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_pixel_read.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2010 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "stdint.h" +#include "main/bufferobj.h" +#include "main/enums.h" +#include "main/fbobject.h" +#include "main/image.h" +#include "main/readpix.h" +#include "main/state.h" + +#include "radeon_common_context.h" +#include "radeon_buffer_objects.h" +#include "radeon_debug.h" +#include "radeon_mipmap_tree.h" + +static mesa_format gl_format_and_type_to_mesa_format(GLenum format, GLenum type) +{ + switch (format) + { + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + return MESA_FORMAT_B5G6R5_UNORM; + case GL_UNSIGNED_SHORT_5_6_5_REV: + return MESA_FORMAT_R5G6B5_UNORM; + } + break; + case GL_RGBA: + switch (type) { + case GL_FLOAT: + return MESA_FORMAT_RGBA_FLOAT32; + case GL_UNSIGNED_SHORT_5_5_5_1: + return MESA_FORMAT_A1B5G5R5_UNORM; + case GL_UNSIGNED_INT_8_8_8_8: + return MESA_FORMAT_A8B8G8R8_UNORM; + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_INT_8_8_8_8_REV: + return MESA_FORMAT_R8G8B8A8_UNORM; + } + break; + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_SHORT_4_4_4_4: + return MESA_FORMAT_A4R4G4B4_UNORM; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return MESA_FORMAT_B4G4R4A4_UNORM; + case GL_UNSIGNED_SHORT_5_5_5_1: + return MESA_FORMAT_A1R5G5B5_UNORM; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return MESA_FORMAT_B5G5R5A1_UNORM; + case GL_UNSIGNED_INT_8_8_8_8: + return MESA_FORMAT_A8R8G8B8_UNORM; + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_INT_8_8_8_8_REV: + return MESA_FORMAT_B8G8R8A8_UNORM; + + } + break; + } + + return MESA_FORMAT_NONE; +} + +static GLboolean +do_blit_readpixels(struct gl_context * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + const struct radeon_renderbuffer *rrb = radeon_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + const mesa_format dst_format = gl_format_and_type_to_mesa_format(format, type); + unsigned dst_rowstride, dst_imagesize, aligned_rowstride, flip_y; + struct radeon_bo *dst_buffer; + GLint dst_x = 0, dst_y = 0; + intptr_t dst_offset; + + /* It's not worth if number of pixels to copy is really small */ + if (width * height < 100) { + return GL_FALSE; + } + + if (dst_format == MESA_FORMAT_NONE || + !radeon->vtbl.check_blit(dst_format, rrb->pitch / rrb->cpp) || !radeon->vtbl.blit) { + return GL_FALSE; + } + + if (ctx->_ImageTransferState || ctx->Color.ColorLogicOpEnabled) { + return GL_FALSE; + } + + if (pack->SwapBytes || pack->LsbFirst) { + return GL_FALSE; + } + + if (pack->RowLength > 0) { + dst_rowstride = pack->RowLength; + } else { + dst_rowstride = width; + } + + if (!_mesa_clip_copytexsubimage(ctx, &dst_x, &dst_y, &x, &y, &width, &height)) { + return GL_TRUE; + } + assert(x >= 0 && y >= 0); + + aligned_rowstride = get_texture_image_row_stride(radeon, dst_format, dst_rowstride, 0, GL_TEXTURE_2D); + dst_rowstride *= _mesa_get_format_bytes(dst_format); + if (_mesa_is_bufferobj(pack->BufferObj) && aligned_rowstride != dst_rowstride) + return GL_FALSE; + dst_imagesize = get_texture_image_size(dst_format, + aligned_rowstride, + height, 1, 0); + + if (!_mesa_is_bufferobj(pack->BufferObj)) + { + dst_buffer = radeon_bo_open(radeon->radeonScreen->bom, 0, dst_imagesize, 1024, RADEON_GEM_DOMAIN_GTT, 0); + dst_offset = 0; + } + else + { + dst_buffer = get_radeon_buffer_object(pack->BufferObj)->bo; + dst_offset = (intptr_t)pixels; + } + + /* Disable source Y flipping for FBOs */ + flip_y = _mesa_is_winsys_fbo(ctx->ReadBuffer); + if (pack->Invert) { + y = rrb->base.Base.Height - height - y; + flip_y = !flip_y; + } + + if (radeon->vtbl.blit(ctx, + rrb->bo, + rrb->draw_offset, + rrb->base.Base.Format, + rrb->pitch / rrb->cpp, + rrb->base.Base.Width, + rrb->base.Base.Height, + x, + y, + dst_buffer, + dst_offset, + dst_format, + aligned_rowstride / _mesa_get_format_bytes(dst_format), + width, + height, + 0, /* dst_x */ + 0, /* dst_y */ + width, + height, + flip_y)) + { + if (!_mesa_is_bufferobj(pack->BufferObj)) + { + radeon_bo_map(dst_buffer, 0); + copy_rows(pixels, dst_rowstride, dst_buffer->ptr, + aligned_rowstride, height, dst_rowstride); + radeon_bo_unmap(dst_buffer); + radeon_bo_unref(dst_buffer); + } + + return GL_TRUE; + } + + if (!_mesa_is_bufferobj(pack->BufferObj)) + radeon_bo_unref(dst_buffer); + + return GL_FALSE; +} + +void +radeonReadPixels(struct gl_context * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + radeon_prepare_render(radeon); + + if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels)) + return; + + /* Update Mesa state before calling _mesa_readpixels(). + * XXX this may not be needed since ReadPixels no longer uses the + * span code. + */ + radeon_print(RADEON_FALLBACKS, RADEON_NORMAL, + "Falling back to sw for ReadPixels (format %s, type %s)\n", + _mesa_enum_to_string(format), _mesa_enum_to_string(type)); + + if (ctx->NewState) + _mesa_update_state(ctx); + + _mesa_readpixels(ctx, x, y, width, height, format, type, pack, pixels); +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_queryobj.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_queryobj.c new file mode 100644 index 000000000..c75c1e03a --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_queryobj.c @@ -0,0 +1,217 @@ +/* + * Copyright © 2008-2009 Maciej Cencora <m.cencora@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Maciej Cencora <m.cencora@gmail.com> + * + */ +#include "radeon_common.h" +#include "radeon_queryobj.h" +#include "radeon_debug.h" + +#include "main/imports.h" +#include "main/queryobj.h" + +#include <inttypes.h> + +static void radeonQueryGetResult(struct gl_context *ctx, struct gl_query_object *q) +{ + struct radeon_query_object *query = (struct radeon_query_object *)q; + uint32_t *result; + int i; + + radeon_print(RADEON_STATE, RADEON_VERBOSE, + "%s: query id %d, result %d\n", + __func__, query->Base.Id, (int) query->Base.Result); + + radeon_bo_map(query->bo, GL_FALSE); + result = query->bo->ptr; + + query->Base.Result = 0; + for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) { + query->Base.Result += LE32_TO_CPU(result[i]); + radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i])); + } + + radeon_bo_unmap(query->bo); +} + +static struct gl_query_object * radeonNewQueryObject(struct gl_context *ctx, GLuint id) +{ + struct radeon_query_object *query; + + query = calloc(1, sizeof(struct radeon_query_object)); + + query->Base.Id = id; + query->Base.Result = 0; + query->Base.Active = GL_FALSE; + query->Base.Ready = GL_TRUE; + + radeon_print(RADEON_STATE, RADEON_VERBOSE,"%s: query id %d\n", __func__, query->Base.Id); + + return &query->Base; +} + +static void radeonDeleteQuery(struct gl_context *ctx, struct gl_query_object *q) +{ + struct radeon_query_object *query = (struct radeon_query_object *)q; + + radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __func__, q->Id); + + if (query->bo) { + radeon_bo_unref(query->bo); + } + + _mesa_delete_query(ctx, q); +} + +static void radeonWaitQuery(struct gl_context *ctx, struct gl_query_object *q) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_query_object *query = (struct radeon_query_object *)q; + + /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */ + if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) + ctx->Driver.Flush(ctx); + + radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __func__, q->Id, query->bo, query->curr_offset); + + radeonQueryGetResult(ctx, q); + + query->Base.Ready = GL_TRUE; +} + + +static void radeonBeginQuery(struct gl_context *ctx, struct gl_query_object *q) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_query_object *query = (struct radeon_query_object *)q; + + radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __func__, q->Id); + + assert(radeon->query.current == NULL); + + if (radeon->dma.flush) + radeon->dma.flush(&radeon->glCtx); + + if (!query->bo) { + query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, RADEON_QUERY_PAGE_SIZE, RADEON_QUERY_PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0); + } + query->curr_offset = 0; + + radeon->query.current = query; + + radeon->query.queryobj.dirty = GL_TRUE; + radeon->hw.is_dirty = GL_TRUE; +} + +void radeonEmitQueryEnd(struct gl_context *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_query_object *query = radeon->query.current; + + if (!query) + return; + + if (query->emitted_begin == GL_FALSE) + return; + + radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d, bo %p, offset %d\n", __func__, query->Base.Id, query->bo, query->curr_offset); + + radeon_cs_space_check_with_bo(radeon->cmdbuf.cs, + query->bo, + 0, RADEON_GEM_DOMAIN_GTT); + + radeon->vtbl.emit_query_finish(radeon); +} + +static void radeonEndQuery(struct gl_context *ctx, struct gl_query_object *q) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __func__, q->Id); + + if (radeon->dma.flush) + radeon->dma.flush(&radeon->glCtx); + radeonEmitQueryEnd(ctx); + + radeon->query.current = NULL; +} + +static void radeonCheckQuery(struct gl_context *ctx, struct gl_query_object *q) +{ + radeon_print(RADEON_STATE, RADEON_TRACE, "%s: query id %d\n", __func__, q->Id); +\ +#ifdef DRM_RADEON_GEM_BUSY + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + struct radeon_query_object *query = (struct radeon_query_object *)q; + uint32_t domain; + + /* Need to perform a flush, as per ARB_occlusion_query spec */ + if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) { + ctx->Driver.Flush(ctx); + } + + if (radeon_bo_is_busy(query->bo, &domain) == 0) { + radeonQueryGetResult(ctx, q); + query->Base.Ready = GL_TRUE; + } +#else + radeonWaitQuery(ctx, q); +#endif +} + +void radeonInitQueryObjFunctions(struct dd_function_table *functions) +{ + functions->NewQueryObject = radeonNewQueryObject; + functions->DeleteQuery = radeonDeleteQuery; + functions->BeginQuery = radeonBeginQuery; + functions->EndQuery = radeonEndQuery; + functions->CheckQuery = radeonCheckQuery; + functions->WaitQuery = radeonWaitQuery; +} + +int radeon_check_query_active(struct gl_context *ctx, struct radeon_state_atom *atom) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_query_object *query = radeon->query.current; + + if (!query || query->emitted_begin) + return 0; + return atom->cmd_size; +} + +void radeon_emit_queryobj(struct gl_context *ctx, struct radeon_state_atom *atom) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + BATCH_LOCALS(radeon); + int dwords; + + dwords = atom->check(ctx, atom); + + BEGIN_BATCH(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); + END_BATCH(); + + radeon->query.current->emitted_begin = GL_TRUE; +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_queryobj.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_queryobj.h new file mode 100644 index 000000000..a2e7724da --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_queryobj.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2008 Maciej Cencora <m.cencora@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Maciej Cencora <m.cencora@gmail.com> + * + */ + +#include "main/imports.h" +#include "util/simple_list.h" +#include "radeon_common_context.h" + +extern void radeonEmitQueryBegin(struct gl_context *ctx); +extern void radeonEmitQueryEnd(struct gl_context *ctx); + +extern void radeonInitQueryObjFunctions(struct dd_function_table *functions); + +#define RADEON_QUERY_PAGE_SIZE 4096 + +int radeon_check_query_active(struct gl_context *ctx, struct radeon_state_atom *atom); +void radeon_emit_queryobj(struct gl_context *ctx, struct radeon_state_atom *atom); + +static inline void radeon_init_query_stateobj(radeonContextPtr radeon, int SZ) +{ + radeon->query.queryobj.cmd_size = (SZ); + radeon->query.queryobj.cmd = calloc(SZ, sizeof(uint32_t)); + radeon->query.queryobj.name = "queryobj"; + radeon->query.queryobj.idx = 0; + radeon->query.queryobj.check = radeon_check_query_active; + radeon->query.queryobj.dirty = GL_FALSE; + radeon->query.queryobj.emit = radeon_emit_queryobj; + + radeon->hw.max_state_size += (SZ); + insert_at_tail(&radeon->hw.atomlist, &radeon->query.queryobj); +} + diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.c new file mode 100644 index 000000000..6345f2ce6 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.c @@ -0,0 +1,894 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/** + * \file radeon_screen.c + * Screen initialization functions for the Radeon driver. + * + * \author Kevin E. Martin <martin@valinux.com> + * \author Gareth Hughes <gareth@valinux.com> + */ + +#include <errno.h> +#include "main/glheader.h" +#include "main/imports.h" +#include "main/mtypes.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/fbobject.h" +#include "swrast/s_renderbuffer.h" + +#include "radeon_chipset.h" +#include "radeon_screen.h" +#include "radeon_common.h" +#include "radeon_common_context.h" +#if defined(RADEON_R100) +#include "radeon_context.h" +#include "radeon_tex.h" +#elif defined(RADEON_R200) +#include "r200_context.h" +#include "r200_tex.h" +#endif + +#include "utils.h" + +#include "GL/internal/dri_interface.h" + +/* Radeon configuration + */ +#include "util/xmlpool.h" + +#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \ +DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \ + DRI_CONF_DESC(en,"Size of command buffer (in KB)") \ + DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \ +DRI_CONF_OPT_END + +#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \ +DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \ + DRI_CONF_DESC(en,"Number of texture units used") \ +DRI_CONF_OPT_END + +#define DRI_CONF_HYPERZ(def) \ +DRI_CONF_OPT_BEGIN_B(hyperz, def) \ + DRI_CONF_DESC(en,"Use HyperZ to boost performance") \ +DRI_CONF_OPT_END + +#define DRI_CONF_TCL_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"TCL mode (Transformation, Clipping, Lighting)") \ + DRI_CONF_ENUM(0,"Use software TCL pipeline") \ + DRI_CONF_ENUM(1,"Use hardware TCL as first TCL pipeline stage") \ + DRI_CONF_ENUM(2,"Bypass the TCL pipeline") \ + DRI_CONF_ENUM(3,"Bypass the TCL pipeline with state-based machine code generated on-the-fly") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_NO_NEG_LOD_BIAS(def) \ +DRI_CONF_OPT_BEGIN_B(no_neg_lod_bias, def) \ + DRI_CONF_DESC(en,"Forbid negative texture LOD bias") \ +DRI_CONF_OPT_END + +#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \ +DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \ + DRI_CONF_DESC(en,"Initial maximum value for anisotropic texture filtering") \ +DRI_CONF_OPT_END + +#if defined(RADEON_R100) /* R100 */ +static const __DRIconfigOptionsExtension radeon_config_options = { + .base = { __DRI_CONFIG_OPTIONS, 1 }, + .xml = +DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN) + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_MAX_TEXTURE_UNITS(3,2,3) + DRI_CONF_HYPERZ("false") + DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) + DRI_CONF_SECTION_END + DRI_CONF_SECTION_QUALITY + DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) + DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0") + DRI_CONF_NO_NEG_LOD_BIAS("false") + DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) + DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) + DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) + DRI_CONF_SECTION_END +DRI_CONF_END +}; + +#elif defined(RADEON_R200) + +#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \ +DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \ + DRI_CONF_DESC(en,"Texture filtering quality vs. speed, AKA “brilinear” texture filtering") \ +DRI_CONF_OPT_END + +static const __DRIconfigOptionsExtension radeon_config_options = { + .base = { __DRI_CONFIG_OPTIONS, 1 }, + .xml = +DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN) + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_MAX_TEXTURE_UNITS(6,2,6) + DRI_CONF_HYPERZ("false") + DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) + DRI_CONF_SECTION_END + DRI_CONF_SECTION_QUALITY + DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) + DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0") + DRI_CONF_NO_NEG_LOD_BIAS("false") + DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) + DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) + DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) + DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0") + DRI_CONF_SECTION_END +DRI_CONF_END +}; +#endif + +static int +radeonGetParam(__DRIscreen *sPriv, int param, void *value) +{ + struct drm_radeon_info info = { 0 }; + + info.value = (uint64_t)(uintptr_t)value; + switch (param) { + case RADEON_PARAM_DEVICE_ID: + info.request = RADEON_INFO_DEVICE_ID; + break; + case RADEON_PARAM_NUM_GB_PIPES: + info.request = RADEON_INFO_NUM_GB_PIPES; + break; + case RADEON_PARAM_NUM_Z_PIPES: + info.request = RADEON_INFO_NUM_Z_PIPES; + break; + case RADEON_INFO_TILING_CONFIG: + info.request = RADEON_INFO_TILING_CONFIG; + break; + default: + return -EINVAL; + } + return drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info)); +} + +#if defined(RADEON_R100) +static const __DRItexBufferExtension radeonTexBufferExtension = { + .base = { __DRI_TEX_BUFFER, 3 }, + + .setTexBuffer = radeonSetTexBuffer, + .setTexBuffer2 = radeonSetTexBuffer2, + .releaseTexBuffer = NULL, +}; +#elif defined(RADEON_R200) +static const __DRItexBufferExtension r200TexBufferExtension = { + .base = { __DRI_TEX_BUFFER, 3 }, + + .setTexBuffer = r200SetTexBuffer, + .setTexBuffer2 = r200SetTexBuffer2, + .releaseTexBuffer = NULL, +}; +#endif + +static void +radeonDRI2Flush(__DRIdrawable *drawable) +{ + radeonContextPtr rmesa; + + rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate; + radeonFlush(&rmesa->glCtx); +} + +static const struct __DRI2flushExtensionRec radeonFlushExtension = { + .base = { __DRI2_FLUSH, 3 }, + + .flush = radeonDRI2Flush, + .invalidate = dri2InvalidateDrawable, +}; + +static __DRIimage * +radeon_create_image_from_name(__DRIscreen *screen, + int width, int height, int format, + int name, int pitch, void *loaderPrivate) +{ + __DRIimage *image; + radeonScreenPtr radeonScreen = screen->driverPrivate; + + if (name == 0) + return NULL; + + image = calloc(1, sizeof *image); + if (image == NULL) + return NULL; + + switch (format) { + case __DRI_IMAGE_FORMAT_RGB565: + image->format = MESA_FORMAT_B5G6R5_UNORM; + image->internal_format = GL_RGB; + image->data_type = GL_UNSIGNED_BYTE; + break; + case __DRI_IMAGE_FORMAT_XRGB8888: + image->format = MESA_FORMAT_B8G8R8X8_UNORM; + image->internal_format = GL_RGB; + image->data_type = GL_UNSIGNED_BYTE; + break; + case __DRI_IMAGE_FORMAT_ARGB8888: + image->format = MESA_FORMAT_B8G8R8A8_UNORM; + image->internal_format = GL_RGBA; + image->data_type = GL_UNSIGNED_BYTE; + break; + default: + free(image); + return NULL; + } + + image->data = loaderPrivate; + image->cpp = _mesa_get_format_bytes(image->format); + image->width = width; + image->pitch = pitch; + image->height = height; + + image->bo = radeon_bo_open(radeonScreen->bom, + (uint32_t)name, + image->pitch * image->height * image->cpp, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + + if (image->bo == NULL) { + free(image); + return NULL; + } + + return image; +} + +static __DRIimage * +radeon_create_image_from_renderbuffer(__DRIcontext *context, + int renderbuffer, void *loaderPrivate) +{ + __DRIimage *image; + radeonContextPtr radeon = context->driverPrivate; + struct gl_renderbuffer *rb; + struct radeon_renderbuffer *rrb; + + rb = _mesa_lookup_renderbuffer(&radeon->glCtx, renderbuffer); + if (!rb) { + _mesa_error(&radeon->glCtx, + GL_INVALID_OPERATION, "glRenderbufferExternalMESA"); + return NULL; + } + + rrb = radeon_renderbuffer(rb); + image = calloc(1, sizeof *image); + if (image == NULL) + return NULL; + + image->internal_format = rb->InternalFormat; + image->format = rb->Format; + image->cpp = rrb->cpp; + image->data_type = GL_UNSIGNED_BYTE; + image->data = loaderPrivate; + radeon_bo_ref(rrb->bo); + image->bo = rrb->bo; + + image->width = rb->Width; + image->height = rb->Height; + image->pitch = rrb->pitch / image->cpp; + + return image; +} + +static void +radeon_destroy_image(__DRIimage *image) +{ + radeon_bo_unref(image->bo); + free(image); +} + +static __DRIimage * +radeon_create_image(__DRIscreen *screen, + int width, int height, int format, + unsigned int use, + void *loaderPrivate) +{ + __DRIimage *image; + radeonScreenPtr radeonScreen = screen->driverPrivate; + + image = calloc(1, sizeof *image); + if (image == NULL) + return NULL; + + image->dri_format = format; + + switch (format) { + case __DRI_IMAGE_FORMAT_RGB565: + image->format = MESA_FORMAT_B5G6R5_UNORM; + image->internal_format = GL_RGB; + image->data_type = GL_UNSIGNED_BYTE; + break; + case __DRI_IMAGE_FORMAT_XRGB8888: + image->format = MESA_FORMAT_B8G8R8X8_UNORM; + image->internal_format = GL_RGB; + image->data_type = GL_UNSIGNED_BYTE; + break; + case __DRI_IMAGE_FORMAT_ARGB8888: + image->format = MESA_FORMAT_B8G8R8A8_UNORM; + image->internal_format = GL_RGBA; + image->data_type = GL_UNSIGNED_BYTE; + break; + default: + free(image); + return NULL; + } + + image->data = loaderPrivate; + image->cpp = _mesa_get_format_bytes(image->format); + image->width = width; + image->height = height; + image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp; + + image->bo = radeon_bo_open(radeonScreen->bom, + 0, + image->pitch * image->height * image->cpp, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + + if (image->bo == NULL) { + free(image); + return NULL; + } + + return image; +} + +static GLboolean +radeon_query_image(__DRIimage *image, int attrib, int *value) +{ + switch (attrib) { + case __DRI_IMAGE_ATTRIB_STRIDE: + *value = image->pitch * image->cpp; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_HANDLE: + *value = image->bo->handle; + return GL_TRUE; + case __DRI_IMAGE_ATTRIB_NAME: + radeon_gem_get_kernel_name(image->bo, (uint32_t *) value); + return GL_TRUE; + default: + return GL_FALSE; + } +} + +static const __DRIimageExtension radeonImageExtension = { + .base = { __DRI_IMAGE, 1 }, + + .createImageFromName = radeon_create_image_from_name, + .createImageFromRenderbuffer = radeon_create_image_from_renderbuffer, + .destroyImage = radeon_destroy_image, + .createImage = radeon_create_image, + .queryImage = radeon_query_image +}; + +static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) +{ + screen->device_id = device_id; + screen->chip_flags = 0; + switch ( device_id ) { +#if defined(RADEON_R100) + case PCI_CHIP_RN50_515E: + case PCI_CHIP_RN50_5969: + return -1; + + case PCI_CHIP_RADEON_LY: + case PCI_CHIP_RADEON_LZ: + case PCI_CHIP_RADEON_QY: + case PCI_CHIP_RADEON_QZ: + screen->chip_family = CHIP_FAMILY_RV100; + break; + + case PCI_CHIP_RS100_4136: + case PCI_CHIP_RS100_4336: + screen->chip_family = CHIP_FAMILY_RS100; + break; + + case PCI_CHIP_RS200_4137: + case PCI_CHIP_RS200_4337: + case PCI_CHIP_RS250_4237: + case PCI_CHIP_RS250_4437: + screen->chip_family = CHIP_FAMILY_RS200; + break; + + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + /* all original radeons (7200) presumably have a stencil op bug */ + screen->chip_family = CHIP_FAMILY_R100; + screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED; + break; + + case PCI_CHIP_RV200_QW: + case PCI_CHIP_RV200_QX: + case PCI_CHIP_RADEON_LW: + case PCI_CHIP_RADEON_LX: + screen->chip_family = CHIP_FAMILY_RV200; + screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED; + break; + +#elif defined(RADEON_R200) + case PCI_CHIP_R200_BB: + case PCI_CHIP_R200_QH: + case PCI_CHIP_R200_QL: + case PCI_CHIP_R200_QM: + screen->chip_family = CHIP_FAMILY_R200; + screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED; + break; + + case PCI_CHIP_RV250_If: + case PCI_CHIP_RV250_Ig: + case PCI_CHIP_RV250_Ld: + case PCI_CHIP_RV250_Lf: + case PCI_CHIP_RV250_Lg: + screen->chip_family = CHIP_FAMILY_RV250; + screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED; + break; + + case PCI_CHIP_RV280_4C6E: + case PCI_CHIP_RV280_5960: + case PCI_CHIP_RV280_5961: + case PCI_CHIP_RV280_5962: + case PCI_CHIP_RV280_5964: + case PCI_CHIP_RV280_5965: + case PCI_CHIP_RV280_5C61: + case PCI_CHIP_RV280_5C63: + screen->chip_family = CHIP_FAMILY_RV280; + screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED; + break; + + case PCI_CHIP_RS300_5834: + case PCI_CHIP_RS300_5835: + case PCI_CHIP_RS350_7834: + case PCI_CHIP_RS350_7835: + screen->chip_family = CHIP_FAMILY_RS300; + screen->chip_flags = RADEON_CHIPSET_DEPTH_ALWAYS_TILED; + break; +#endif + + default: + fprintf(stderr, "unknown chip id 0x%x, can't guess.\n", + device_id); + return -1; + } + + return 0; +} + +static int +radeonQueryRendererInteger(__DRIscreen *psp, int param, + unsigned int *value) +{ + radeonScreenPtr screen = (radeonScreenPtr)psp->driverPrivate; + + switch (param) { + case __DRI2_RENDERER_VENDOR_ID: + value[0] = 0x1002; + return 0; + case __DRI2_RENDERER_DEVICE_ID: + value[0] = screen->device_id; + return 0; + case __DRI2_RENDERER_ACCELERATED: + value[0] = 1; + return 0; + case __DRI2_RENDERER_VIDEO_MEMORY: { + struct drm_radeon_gem_info gem_info; + int retval; + memset(&gem_info, 0, sizeof(gem_info)); + + /* Get GEM info. */ + retval = drmCommandWriteRead(psp->fd, DRM_RADEON_GEM_INFO, &gem_info, + sizeof(gem_info)); + + if (retval) { + fprintf(stderr, "radeon: Failed to get MM info, error number %d\n", + retval); + return -1; + + } + /* XXX: Do we want to return vram_size or vram_visible ? */ + value[0] = gem_info.vram_size >> 20; + return 0; + } + case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE: + value[0] = 0; + return 0; + default: + return driQueryRendererIntegerCommon(psp, param, value); + } +} + +static int +radeonQueryRendererString(__DRIscreen *psp, int param, const char **value) +{ + radeonScreenPtr screen = (radeonScreenPtr)psp->driverPrivate; + + switch (param) { + case __DRI2_RENDERER_VENDOR_ID: + value[0] = radeonVendorString; + return 0; + case __DRI2_RENDERER_DEVICE_ID: + value[0] = radeonGetRendererString(screen); + return 0; + default: + return -1; + } +} + +static const __DRI2rendererQueryExtension radeonRendererQueryExtension = { + .base = { __DRI2_RENDERER_QUERY, 1 }, + + .queryInteger = radeonQueryRendererInteger, + .queryString = radeonQueryRendererString +}; + + +static const __DRIextension *radeon_screen_extensions[] = { + &dri2ConfigQueryExtension.base, +#if defined(RADEON_R100) + &radeonTexBufferExtension.base, +#elif defined(RADEON_R200) + &r200TexBufferExtension.base, +#endif + &radeonFlushExtension.base, + &radeonImageExtension.base, + &radeonRendererQueryExtension.base, + &dri2NoErrorExtension.base, + NULL +}; + +static radeonScreenPtr +radeonCreateScreen2(__DRIscreen *sPriv) +{ + radeonScreenPtr screen; + int ret; + uint32_t device_id = 0; + + /* Allocate the private area */ + screen = calloc(1, sizeof(*screen)); + if ( !screen ) { + fprintf(stderr, "%s: Could not allocate memory for screen structure", __func__); + fprintf(stderr, "leaving here\n"); + return NULL; + } + + radeon_init_debug(); + + /* parse information in __driConfigOptions */ + driParseOptionInfo (&screen->optionCache, radeon_config_options.xml); + + screen->chip_flags = 0; + + screen->irq = 1; + + ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id); + if (ret) { + free( screen ); + fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret); + return NULL; + } + + ret = radeon_set_screen_flags(screen, device_id); + if (ret == -1) { + free(screen); + return NULL; + } + + if (getenv("RADEON_NO_TCL")) + screen->chip_flags &= ~RADEON_CHIPSET_TCL; + + sPriv->extensions = radeon_screen_extensions; + + screen->driScreen = sPriv; + screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd); + if (screen->bom == NULL) { + free(screen); + return NULL; + } + return screen; +} + +/* Destroy the device specific screen private data struct. + */ +static void +radeonDestroyScreen( __DRIscreen *sPriv ) +{ + radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate; + + if (!screen) + return; + +#ifdef RADEON_BO_TRACK + radeon_tracker_print(&screen->bom->tracker, stderr); +#endif + radeon_bo_manager_gem_dtor(screen->bom); + + /* free all option information */ + driDestroyOptionInfo (&screen->optionCache); + + free( screen ); + sPriv->driverPrivate = NULL; +} + + +/* Initialize the driver specific screen private data. + */ +static GLboolean +radeonInitDriver( __DRIscreen *sPriv ) +{ + sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv ); + if ( !sPriv->driverPrivate ) { + radeonDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + + + +/** + * Create the Mesa framebuffer and renderbuffers for a given window/drawable. + * + * \todo This function (and its interface) will need to be updated to support + * pbuffers. + */ +static GLboolean +radeonCreateBuffer( __DRIscreen *driScrnPriv, + __DRIdrawable *driDrawPriv, + const struct gl_config *mesaVis, + GLboolean isPixmap ) +{ + radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate; + + const GLboolean swDepth = GL_FALSE; + const GLboolean swAlpha = GL_FALSE; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24; + mesa_format rgbFormat; + struct radeon_framebuffer *rfb; + + if (isPixmap) + return GL_FALSE; /* not implemented */ + + rfb = CALLOC_STRUCT(radeon_framebuffer); + if (!rfb) + return GL_FALSE; + + _mesa_initialize_window_framebuffer(&rfb->base, mesaVis); + + if (mesaVis->redBits == 5) + rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B5G6R5_UNORM : MESA_FORMAT_R5G6B5_UNORM; + else if (mesaVis->alphaBits == 0) + rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8X8_UNORM : MESA_FORMAT_X8R8G8B8_UNORM; + else + rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8A8_UNORM : MESA_FORMAT_A8R8G8B8_UNORM; + + /* front color renderbuffer */ + rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_attach_and_own_rb(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base.Base); + rfb->color_rb[0]->has_surface = 1; + + /* back color renderbuffer */ + if (mesaVis->doubleBufferMode) { + rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_attach_and_own_rb(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base.Base); + rfb->color_rb[1]->has_surface = 1; + } + + if (mesaVis->depthBits == 24) { + if (mesaVis->stencilBits == 8) { + struct radeon_renderbuffer *depthStencilRb = + radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT, driDrawPriv); + _mesa_attach_and_own_rb(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base.Base); + _mesa_attach_and_reference_rb(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base.Base); + depthStencilRb->has_surface = screen->depthHasSurface; + } else { + /* depth renderbuffer */ + struct radeon_renderbuffer *depth = + radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT, driDrawPriv); + _mesa_attach_and_own_rb(&rfb->base, BUFFER_DEPTH, &depth->base.Base); + depth->has_surface = screen->depthHasSurface; + } + } else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct radeon_renderbuffer *depth = + radeon_create_renderbuffer(MESA_FORMAT_Z_UNORM16, driDrawPriv); + _mesa_attach_and_own_rb(&rfb->base, BUFFER_DEPTH, &depth->base.Base); + depth->has_surface = screen->depthHasSurface; + } + + _swrast_add_soft_renderbuffers(&rfb->base, + GL_FALSE, /* color */ + swDepth, + swStencil, + swAccum, + swAlpha, + GL_FALSE /* aux */); + driDrawPriv->driverPrivate = (void *) rfb; + + return (driDrawPriv->driverPrivate != NULL); +} + + +static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb) +{ + struct radeon_renderbuffer *rb; + + rb = rfb->color_rb[0]; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = rfb->color_rb[1]; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } +} + +void +radeonDestroyBuffer(__DRIdrawable *driDrawPriv) +{ + struct radeon_framebuffer *rfb; + if (!driDrawPriv) + return; + + rfb = (void*)driDrawPriv->driverPrivate; + if (!rfb) + return; + radeon_cleanup_renderbuffers(rfb); + _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL); +} + +/** + * This is the driver specific part of the createNewScreen entry point. + * Called when using DRI2. + * + * \return the struct gl_config supported by this driver + */ +static const +__DRIconfig **radeonInitScreen2(__DRIscreen *psp) +{ + static const mesa_format formats[3] = { + MESA_FORMAT_B5G6R5_UNORM, + MESA_FORMAT_B8G8R8X8_UNORM, + MESA_FORMAT_B8G8R8A8_UNORM + }; + + static const GLenum back_buffer_modes[] = { + __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED + }; + uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; + int color; + __DRIconfig **configs = NULL; + + psp->max_gl_compat_version = 13; + psp->max_gl_es1_version = 11; + + if (!radeonInitDriver(psp)) { + return NULL; + } + depth_bits[0] = 0; + stencil_bits[0] = 0; + depth_bits[1] = 16; + stencil_bits[1] = 0; + depth_bits[2] = 24; + stencil_bits[2] = 0; + depth_bits[3] = 24; + stencil_bits[3] = 8; + + msaa_samples_array[0] = 0; + + for (color = 0; color < ARRAY_SIZE(formats); color++) { + __DRIconfig **new_configs; + + new_configs = driCreateConfigs(formats[color], + depth_bits, + stencil_bits, + ARRAY_SIZE(depth_bits), + back_buffer_modes, + ARRAY_SIZE(back_buffer_modes), + msaa_samples_array, + ARRAY_SIZE(msaa_samples_array), + GL_TRUE, GL_FALSE, GL_FALSE); + configs = driConcatConfigs(configs, new_configs); + } + + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + return (const __DRIconfig **)configs; +} + +static const struct __DriverAPIRec radeon_driver_api = { + .InitScreen = radeonInitScreen2, + .DestroyScreen = radeonDestroyScreen, +#if defined(RADEON_R200) + .CreateContext = r200CreateContext, + .DestroyContext = r200DestroyContext, +#else + .CreateContext = r100CreateContext, + .DestroyContext = radeonDestroyContext, +#endif + .CreateBuffer = radeonCreateBuffer, + .DestroyBuffer = radeonDestroyBuffer, + .MakeCurrent = radeonMakeCurrent, + .UnbindContext = radeonUnbindContext, +}; + +static const struct __DRIDriverVtableExtensionRec radeon_vtable = { + .base = { __DRI_DRIVER_VTABLE, 1 }, + .vtable = &radeon_driver_api, +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +static const __DRIextension *radeon_driver_extensions[] = { + &driCoreExtension.base, + &driDRI2Extension.base, + &radeon_config_options.base, + &radeon_vtable.base, + NULL +}; + +#ifdef RADEON_R200 +PUBLIC const __DRIextension **__driDriverGetExtensions_r200(void) +{ + globalDriverAPI = &radeon_driver_api; + + return radeon_driver_extensions; +} +#else +PUBLIC const __DRIextension **__driDriverGetExtensions_radeon(void) +{ + globalDriverAPI = &radeon_driver_api; + + return radeon_driver_extensions; +} +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h new file mode 100644 index 000000000..af1b9454e --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_screen.h @@ -0,0 +1,279 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + +#ifndef __RADEON_SCREEN_H__ +#define __RADEON_SCREEN_H__ + +/* + * IMPORTS: these headers contain all the DRI, X and kernel-related + * definitions that we need. + */ +#include <xf86drm.h> +#include <radeon_drm.h> +#include "dri_util.h" +#include "radeon_chipset.h" +#include "radeon_reg.h" +#include "util/xmlconfig.h" + +#define DRI_CONF_COLOR_REDUCTION_ROUND 0 +#define DRI_CONF_COLOR_REDUCTION_DITHER 1 +#define DRI_CONF_COLOR_REDUCTION(def) \ +DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Initial color reduction method") \ + DRI_CONF_ENUM(0,"Round colors") \ + DRI_CONF_ENUM(1,"Dither colors") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DITHER_XERRORDIFF 0 +#define DRI_CONF_DITHER_XERRORDIFFRESET 1 +#define DRI_CONF_DITHER_ORDERED 2 +#define DRI_CONF_DITHER_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Color dithering method") \ + DRI_CONF_ENUM(0,"Horizontal error diffusion") \ + DRI_CONF_ENUM(1,"Horizontal error diffusion, reset error at line start") \ + DRI_CONF_ENUM(2,"Ordered 2D color dithering") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_ROUND_TRUNC 0 +#define DRI_CONF_ROUND_ROUND 1 +#define DRI_CONF_ROUND_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Color rounding method") \ + DRI_CONF_ENUM(0,"Round color components downward") \ + DRI_CONF_ENUM(1,"Round to nearest color") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FTHROTTLE_BUSY 0 +#define DRI_CONF_FTHROTTLE_USLEEPS 1 +#define DRI_CONF_FTHROTTLE_IRQS 2 +#define DRI_CONF_FTHROTTLE_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Method to limit rendering latency") \ + DRI_CONF_ENUM(0,"Busy waiting for the graphics hardware") \ + DRI_CONF_ENUM(1,"Sleep for brief intervals while waiting for the graphics hardware") \ + DRI_CONF_ENUM(2,"Let the graphics hardware emit a software interrupt and sleep") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_DEPTH_FB 0 +#define DRI_CONF_TEXTURE_DEPTH_32 1 +#define DRI_CONF_TEXTURE_DEPTH_16 2 +#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 +#define DRI_CONF_TEXTURE_DEPTH(def) \ +DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"Texture color depth") \ + DRI_CONF_ENUM(0,"Prefer frame buffer color depth") \ + DRI_CONF_ENUM(1,"Prefer 32 bits per texel") \ + DRI_CONF_ENUM(2,"Prefer 16 bits per texel") \ + DRI_CONF_ENUM(3,"Force 16 bits per texel") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TCL_SW 0 +#define DRI_CONF_TCL_PIPELINED 1 +#define DRI_CONF_TCL_VTXFMT 2 +#define DRI_CONF_TCL_CODEGEN 3 + +typedef struct { + drm_handle_t handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + drmAddress map; /* Mapping of the DRM region */ +} radeonRegionRec, *radeonRegionPtr; + +typedef struct radeon_screen { + int chip_family; + int chip_flags; + int cpp; + int card_type; + int device_id; /* PCI ID */ + int AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ + + unsigned int fbLocation; + unsigned int frontOffset; + unsigned int frontPitch; + unsigned int backOffset; + unsigned int backPitch; + + unsigned int depthOffset; + unsigned int depthPitch; + + /* Shared texture data */ + int numTexHeaps; + int texOffset[RADEON_NR_TEX_HEAPS]; + int texSize[RADEON_NR_TEX_HEAPS]; + int logTexGranularity[RADEON_NR_TEX_HEAPS]; + + radeonRegionRec mmio; + radeonRegionRec status; + radeonRegionRec gartTextures; + + drmBufMapPtr buffers; + + __volatile__ uint32_t *scratch; + + __DRIscreen *driScreen; + unsigned int gart_buffer_offset; /* offset in card memory space */ + unsigned int gart_texture_offset; /* offset in card memory space */ + unsigned int gart_base; + + GLboolean depthHasSurface; + + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; + + int num_gb_pipes; + int num_z_pipes; + struct radeon_bo_manager *bom; + +} radeonScreenRec, *radeonScreenPtr; + +struct __DRIimageRec { + struct radeon_bo *bo; + GLenum internal_format; + uint32_t dri_format; + GLuint format; + GLenum data_type; + int width, height; /* in pixels */ + int pitch; /* in pixels */ + int cpp; + void *data; +}; + +#ifdef RADEON_R200 +/* These defines are to ensure that r200_dri's symbols don't conflict with + * radeon's when linked together. + */ +#define get_radeon_buffer_object r200_get_radeon_buffer_object +#define radeonInitBufferObjectFuncs r200_radeonInitBufferObjectFuncs +#define radeonDestroyContext r200_radeonDestroyContext +#define radeonInitContext r200_radeonInitContext +#define radeonMakeCurrent r200_radeonMakeCurrent +#define radeon_prepare_render r200_radeon_prepare_render +#define radeonUnbindContext r200_radeonUnbindContext +#define radeon_update_renderbuffers r200_radeon_update_renderbuffers +#define radeonCountStateEmitSize r200_radeonCountStateEmitSize +#define radeon_draw_buffer r200_radeon_draw_buffer +#define radeonDrawBuffer r200_radeonDrawBuffer +#define radeonEmitState r200_radeonEmitState +#define radeonFinish r200_radeonFinish +#define radeonFlush r200_radeonFlush +#define radeonGetAge r200_radeonGetAge +#define radeonReadBuffer r200_radeonReadBuffer +#define radeonScissor r200_radeonScissor +#define radeonSetCliprects r200_radeonSetCliprects +#define radeonUpdateScissor r200_radeonUpdateScissor +#define radeonUserClear r200_radeonUserClear +#define radeon_viewport r200_radeon_viewport +#define radeon_window_moved r200_radeon_window_moved +#define rcommonBeginBatch r200_rcommonBeginBatch +#define rcommonDestroyCmdBuf r200_rcommonDestroyCmdBuf +#define rcommonEnsureCmdBufSpace r200_rcommonEnsureCmdBufSpace +#define rcommonFlushCmdBuf r200_rcommonFlushCmdBuf +#define rcommonFlushCmdBufLocked r200_rcommonFlushCmdBufLocked +#define rcommonInitCmdBuf r200_rcommonInitCmdBuf +#define radeonAllocDmaRegion r200_radeonAllocDmaRegion +#define radeonEmitVec12 r200_radeonEmitVec12 +#define radeonEmitVec16 r200_radeonEmitVec16 +#define radeonEmitVec4 r200_radeonEmitVec4 +#define radeonEmitVec8 r200_radeonEmitVec8 +#define radeonFreeDmaRegions r200_radeonFreeDmaRegions +#define radeon_init_dma r200_radeon_init_dma +#define radeonRefillCurrentDmaRegion r200_radeonRefillCurrentDmaRegion +#define radeonReleaseArrays r200_radeonReleaseArrays +#define radeonReleaseDmaRegions r200_radeonReleaseDmaRegions +#define radeonReturnDmaRegion r200_radeonReturnDmaRegion +#define rcommonAllocDmaLowVerts r200_rcommonAllocDmaLowVerts +#define rcommon_emit_vecfog r200_rcommon_emit_vecfog +#define rcommon_emit_vector r200_rcommon_emit_vector +#define rcommon_flush_last_swtcl_prim r200_rcommon_flush_last_swtcl_prim +#define _radeon_debug_add_indent r200__radeon_debug_add_indent +#define _radeon_debug_remove_indent r200__radeon_debug_remove_indent +#define radeon_init_debug r200_radeon_init_debug +#define _radeon_print r200__radeon_print +#define radeon_create_renderbuffer r200_radeon_create_renderbuffer +#define radeon_fbo_init r200_radeon_fbo_init +#define radeon_renderbuffer_set_bo r200_radeon_renderbuffer_set_bo +#define radeonComputeFogBlendFactor r200_radeonComputeFogBlendFactor +#define radeonInitStaticFogData r200_radeonInitStaticFogData +#define get_base_teximage_offset r200_get_base_teximage_offset +#define get_texture_image_row_stride r200_get_texture_image_row_stride +#define get_texture_image_size r200_get_texture_image_size +#define radeon_miptree_create r200_radeon_miptree_create +#define radeon_miptree_image_offset r200_radeon_miptree_image_offset +#define radeon_miptree_matches_image r200_radeon_miptree_matches_image +#define radeon_miptree_reference r200_radeon_miptree_reference +#define radeon_miptree_unreference r200_radeon_miptree_unreference +#define radeon_try_alloc_miptree r200_radeon_try_alloc_miptree +#define radeon_validate_texture_miptree r200_radeon_validate_texture_miptree +#define radeonReadPixels r200_radeonReadPixels +#define radeon_check_query_active r200_radeon_check_query_active +#define radeonEmitQueryEnd r200_radeonEmitQueryEnd +#define radeon_emit_queryobj r200_radeon_emit_queryobj +#define radeonInitQueryObjFunctions r200_radeonInitQueryObjFunctions +#define radeonInitSpanFuncs r200_radeonInitSpanFuncs +#define copy_rows r200_copy_rows +#define radeonChooseTextureFormat r200_radeonChooseTextureFormat +#define radeonChooseTextureFormat_mesa r200_radeonChooseTextureFormat_mesa +#define radeonFreeTextureImageBuffer r200_radeonFreeTextureImageBuffer +#define radeon_image_target_texture_2d r200_radeon_image_target_texture_2d +#define radeon_init_common_texture_funcs r200_radeon_init_common_texture_funcs +#define radeonIsFormatRenderable r200_radeonIsFormatRenderable +#define radeonNewTextureImage r200_radeonNewTextureImage +#define _radeon_texformat_al88 r200__radeon_texformat_al88 +#define _radeon_texformat_argb1555 r200__radeon_texformat_argb1555 +#define _radeon_texformat_argb4444 r200__radeon_texformat_argb4444 +#define _radeon_texformat_argb8888 r200__radeon_texformat_argb8888 +#define _radeon_texformat_rgb565 r200__radeon_texformat_rgb565 +#define _radeon_texformat_rgba8888 r200__radeon_texformat_rgba8888 +#define radeonCopyTexSubImage r200_radeonCopyTexSubImage +#define get_tile_size r200_get_tile_size +#define tile_image r200_tile_image +#define untile_image r200_untile_image +#define set_re_cntl_d3d r200_set_re_cntl_d3d +#define radeonDestroyBuffer r200_radeonDestroyBuffer +#define radeonVendorString r200_radeonVendorString +#define radeonGetRendererString r200_radeonGetRendererString +#endif + +extern void radeonDestroyBuffer(__DRIdrawable *driDrawPriv); +const __DRIextension **__driDriverGetExtensions_radeon(void); +const __DRIextension **__driDriverGetExtensions_r200(void); + +#endif /* __RADEON_SCREEN_H__ */ diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c new file mode 100644 index 000000000..fa5b2d98f --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.c @@ -0,0 +1,155 @@ +/************************************************************************** + +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@vmware.com> + * + */ + +#include "main/glheader.h" +#include "main/texformat.h" +#include "main/renderbuffer.h" +#include "main/samplerobj.h" +#include "main/framebuffer.h" +#include "swrast/swrast.h" +#include "swrast/s_renderbuffer.h" + +#include "radeon_common.h" +#include "radeon_span.h" + + +static void +radeon_renderbuffer_map(struct gl_context *ctx, + struct gl_renderbuffer *rb, + bool flip_y) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + GLubyte *map; + int stride; + + if (!rb || !rrb) + return; + + ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &map, &stride, flip_y); + + rrb->base.Map = map; + rrb->base.RowStride = stride; + /* No floating point color buffers, use GLubytes */ + rrb->base.ColorType = GL_UNSIGNED_BYTE; +} + +static void +radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + if (!rb || !rrb) + return; + + ctx->Driver.UnmapRenderbuffer(ctx, rb); + + rrb->base.Map = NULL; + rrb->base.RowStride = 0; +} + +static void +radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + GLuint i; + + radeon_print(RADEON_MEMORY, RADEON_TRACE, + "%s( %p , fb %p )\n", + __func__, ctx, fb); + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) + radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer, + fb->FlipY); + + if (_mesa_is_front_buffer_drawing(fb)) + RADEON_CONTEXT(ctx)->front_buffer_dirty = true; +} + +static void +radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + GLuint i; + + radeon_print(RADEON_MEMORY, RADEON_TRACE, + "%s( %p , fb %p)\n", + __func__, ctx, fb); + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) + radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer); + + if (_mesa_is_front_buffer_drawing(fb)) + RADEON_CONTEXT(ctx)->front_buffer_dirty = true; +} + +static void radeonSpanRenderStart(struct gl_context * ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + radeon_firevertices(rmesa); + + _swrast_map_textures(ctx); + + radeon_map_framebuffer(ctx, ctx->DrawBuffer); + if (ctx->ReadBuffer != ctx->DrawBuffer) + radeon_map_framebuffer(ctx, ctx->ReadBuffer); +} + +static void radeonSpanRenderFinish(struct gl_context * ctx) +{ + _swrast_flush(ctx); + _swrast_unmap_textures(ctx); + + radeon_unmap_framebuffer(ctx, ctx->DrawBuffer); + if (ctx->ReadBuffer != ctx->DrawBuffer) + radeon_unmap_framebuffer(ctx, ctx->ReadBuffer); +} + +void radeonInitSpanFuncs(struct gl_context * ctx) +{ + struct swrast_device_driver *swdd = + _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = radeonSpanRenderStart; + swdd->SpanRenderFinish = radeonSpanRenderFinish; +} + diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.h new file mode 100644 index 000000000..f66e6870e --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_span.h @@ -0,0 +1,47 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@vmware.com> + * Kevin E. Martin <martin@valinux.com> + */ + +#ifndef __RADEON_SPAN_H__ +#define __RADEON_SPAN_H__ + +extern void radeonInitSpanFuncs(struct gl_context * ctx); + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_tex_copy.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_tex_copy.c new file mode 100644 index 000000000..93313c2b6 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_tex_copy.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_common.h" +#include "radeon_texture.h" + +#include "main/enums.h" +#include "main/image.h" +#include "main/teximage.h" +#include "main/texstate.h" +#include "drivers/common/meta.h" + +#include "radeon_mipmap_tree.h" + +static GLboolean +do_copy_texsubimage(struct gl_context *ctx, + struct radeon_tex_obj *tobj, + radeon_texture_image *timg, + GLint dstx, GLint dsty, + struct radeon_renderbuffer *rrb, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + const GLuint face = timg->base.Base.Face; + const GLuint level = timg->base.Base.Level; + unsigned src_bpp; + unsigned dst_bpp; + mesa_format src_mesaformat; + mesa_format dst_mesaformat; + unsigned flip_y; + + if (!radeon->vtbl.blit) { + return GL_FALSE; + } + + // This is software renderbuffer, fallback to swrast + if (!rrb) { + return GL_FALSE; + } + + if (_mesa_get_format_bits(timg->base.Base.TexFormat, GL_DEPTH_BITS) > 0) { + /* copying depth values */ + flip_y = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Type == GL_NONE; + } else { + /* copying color */ + flip_y = ctx->ReadBuffer->Attachment[BUFFER_COLOR0].Type == GL_NONE; + } + + if (!timg->mt) { + radeon_validate_texture_miptree(ctx, &tobj->base.Sampler, &tobj->base); + } + + assert(rrb->bo); + assert(timg->mt); + assert(timg->mt->bo); + assert(timg->base.Base.Width >= dstx + width); + assert(timg->base.Base.Height >= dsty + height); + + intptr_t src_offset = rrb->draw_offset; + intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, face, level); + + if (0) { + fprintf(stderr, "%s: copying to face %d, level %d\n", + __func__, face, level); + fprintf(stderr, "to: x %d, y %d, offset %d\n", dstx, dsty, (uint32_t) dst_offset); + fprintf(stderr, "from (%dx%d) width %d, height %d, offset %d, pitch %d\n", + x, y, rrb->base.Base.Width, rrb->base.Base.Height, (uint32_t) src_offset, rrb->pitch/rrb->cpp); + fprintf(stderr, "src size %d, dst size %d\n", rrb->bo->size, timg->mt->bo->size); + + } + + src_mesaformat = rrb->base.Base.Format; + dst_mesaformat = timg->base.Base.TexFormat; + src_bpp = _mesa_get_format_bytes(src_mesaformat); + dst_bpp = _mesa_get_format_bytes(dst_mesaformat); + if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) { + /* depth formats tend to be special */ + if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0) + return GL_FALSE; + + if (src_bpp != dst_bpp) + return GL_FALSE; + + switch (dst_bpp) { + case 2: + src_mesaformat = MESA_FORMAT_B5G6R5_UNORM; + dst_mesaformat = MESA_FORMAT_B5G6R5_UNORM; + break; + case 4: + src_mesaformat = MESA_FORMAT_B8G8R8A8_UNORM; + dst_mesaformat = MESA_FORMAT_B8G8R8A8_UNORM; + break; + case 1: + src_mesaformat = MESA_FORMAT_A_UNORM8; + dst_mesaformat = MESA_FORMAT_A_UNORM8; + break; + default: + return GL_FALSE; + } + } + + /* blit from src buffer to texture */ + return radeon->vtbl.blit(ctx, rrb->bo, src_offset, src_mesaformat, rrb->pitch/rrb->cpp, + rrb->base.Base.Width, rrb->base.Base.Height, x, y, + timg->mt->bo, dst_offset, dst_mesaformat, + timg->mt->levels[level].rowstride / dst_bpp, + timg->base.Base.Width, timg->base.Base.Height, + dstx, dsty, width, height, flip_y); +} + +void +radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint slice, + struct gl_renderbuffer *rb, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + radeon_prepare_render(radeon); + + if (slice != 0 || !do_copy_texsubimage(ctx, + radeon_tex_obj(texImage->TexObject), + (radeon_texture_image *)texImage, + xoffset, yoffset, + radeon_renderbuffer(rb), x, y, width, height)) { + + radeon_print(RADEON_FALLBACKS, RADEON_NORMAL, + "Falling back to sw for glCopyTexSubImage2D\n"); + + _mesa_meta_CopyTexSubImage(ctx, dims, texImage, + xoffset, yoffset, slice, + rb, x, y, width, height); + } +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_texture.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_texture.c new file mode 100644 index 000000000..f2d435a37 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_texture.c @@ -0,0 +1,696 @@ +/* + * Copyright (C) 2009 Maciej Cencora. + * Copyright (C) 2008 Nicolai Haehnle. + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/enums.h" +#include "main/mipmap.h" +#include "main/pbo.h" +#include "main/texcompress.h" +#include "main/texstore.h" +#include "main/teximage.h" +#include "main/texobj.h" +#include "drivers/common/meta.h" + +#include "util/xmlpool.h" /* for symbolic values of enum-type options */ + +#include "radeon_common.h" + +#include "radeon_mipmap_tree.h" + +static void teximage_assign_miptree(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, + GLuint numrows, GLuint rowsize) +{ + assert(rowsize <= dststride); + assert(rowsize <= srcstride); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s dst %p, stride %u, src %p, stride %u, " + "numrows %u, rowsize %u.\n", + __func__, dst, dststride, + src, srcstride, + numrows, rowsize); + + if (rowsize == srcstride && rowsize == dststride) { + memcpy(dst, src, numrows*rowsize); + } else { + GLuint i; + for(i = 0; i < numrows; ++i) { + memcpy(dst, src, rowsize); + dst += dststride; + src += srcstride; + } + } +} + +/* textures */ +/** + * Allocate an empty texture image object. + */ +struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx) +{ + return calloc(1, sizeof(radeon_texture_image)); +} + + +/** + * Delete a texture image object. + */ +static void +radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img) +{ + /* nothing special (yet) for radeon_texture_image */ + _mesa_delete_texture_image(ctx, img); +} + +static GLboolean +radeonAllocTextureImageBuffer(struct gl_context *ctx, + struct gl_texture_image *timage) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_object *texobj = timage->TexObject; + + ctx->Driver.FreeTextureImageBuffer(ctx, timage); + + if (!_swrast_init_texture_image(timage)) + return GL_FALSE; + + teximage_assign_miptree(rmesa, texobj, timage); + + return GL_TRUE; +} + + +/** + * Free memory associated with this texture image. + */ +void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage) +{ + radeon_texture_image* image = get_radeon_texture_image(timage); + + if (image->mt) { + radeon_miptree_unreference(&image->mt); + } + if (image->bo) { + radeon_bo_unref(image->bo); + image->bo = NULL; + } + + _swrast_free_texture_image_buffer(ctx, timage); +} + +/** + * Map texture memory/buffer into user space. + * Note: the region of interest parameters are ignored here. + * \param mapOut returns start of mapping of region of interest + * \param rowStrideOut returns row stride in bytes + */ +static void +radeon_map_texture_image(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **map, + GLint *stride) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeon_texture_image *image = get_radeon_texture_image(texImage); + radeon_mipmap_tree *mt = image->mt; + GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat); + GLuint width = texImage->Width; + GLuint height = texImage->Height; + struct radeon_bo *bo = !image->mt ? image->bo : image->mt->bo; + unsigned int bw, bh; + GLboolean write = (mode & GL_MAP_WRITE_BIT) != 0; + + _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); + assert(y % bh == 0); + y /= bh; + texel_size /= bw; + + if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s for texture that is " + "queued for GPU processing.\n", + __func__); + radeon_firevertices(rmesa); + } + + if (image->bo) { + /* TFP case */ + radeon_bo_map(image->bo, write); + *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target); + *map = bo->ptr; + } else if (likely(mt)) { + void *base; + radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level]; + + radeon_bo_map(mt->bo, write); + base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset; + + *stride = lvl->rowstride; + *map = base + (slice * height) * *stride; + } else { + /* texture data is in malloc'd memory */ + + assert(map); + + *stride = _mesa_format_row_stride(texImage->TexFormat, width); + *map = image->base.Buffer + (slice * height) * *stride; + } + + *map += y * *stride + x * texel_size; +} + +static void +radeon_unmap_texture_image(struct gl_context *ctx, + struct gl_texture_image *texImage, GLuint slice) +{ + radeon_texture_image *image = get_radeon_texture_image(texImage); + + if (image->bo) + radeon_bo_unmap(image->bo); + else if (image->mt) + radeon_bo_unmap(image->mt->bo); +} + +/* try to find a format which will only need a memcopy */ +static mesa_format radeonChoose8888TexFormat(radeonContextPtr rmesa, + GLenum srcFormat, + GLenum srcType, GLboolean fbo) +{ +#if defined(RADEON_R100) + /* r100 can only do this */ + return _radeon_texformat_argb8888; +#elif defined(RADEON_R200) + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *)&ui); + + + /* Unfortunately, regardless the fbo flag, we might still be asked to + * attach a texture to a fbo later, which then won't succeed if we chose + * one which isn't renderable. And unlike more exotic formats, apps aren't + * really prepared for the incomplete framebuffer this results in (they'd + * have to retry with same internalFormat even, just different + * srcFormat/srcType, which can't really be expected anyway). + * Ideally, we'd defer format selection until later (if the texture is + * used as a rt it's likely there's never data uploaded to it before attached + * to a fbo), but this isn't really possible, so for now just always use + * a renderable format. + */ + if (1 || fbo) + return _radeon_texformat_argb8888; + + if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { + return MESA_FORMAT_A8B8G8R8_UNORM; + } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { + return MESA_FORMAT_R8G8B8A8_UNORM; + } else + return _radeon_texformat_argb8888; +#endif +} + +mesa_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, + GLenum target, + GLint internalFormat, + GLenum format, + GLenum type) +{ + return radeonChooseTextureFormat(ctx, internalFormat, format, + type, 0); +} + +mesa_format radeonChooseTextureFormat(struct gl_context * ctx, + GLint internalFormat, + GLenum format, + GLenum type, GLboolean fbo) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + const GLboolean do32bpt = + (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); + const GLboolean force16bpt = + (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); + (void)format; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s InternalFormat=%s(%d) type=%s format=%s\n", + __func__, + _mesa_enum_to_string(internalFormat), internalFormat, + _mesa_enum_to_string(type), _mesa_enum_to_string(format)); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s do32bpt=%d force16bpt=%d\n", + __func__, do32bpt, force16bpt); + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + switch (type) { + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return do32bpt ? _radeon_texformat_argb8888 : + _radeon_texformat_argb1555; + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return _radeon_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return _radeon_texformat_argb1555; + default: + return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : + _radeon_texformat_argb4444; + } + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return _radeon_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return _radeon_texformat_argb1555; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return _radeon_texformat_rgb565; + default: + return do32bpt ? _radeon_texformat_argb8888 : + _radeon_texformat_rgb565; + } + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return !force16bpt ? + radeonChoose8888TexFormat(rmesa, format, type, fbo) : + _radeon_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return _radeon_texformat_argb4444; + + case GL_RGB5_A1: + return _radeon_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return !force16bpt ? _radeon_texformat_argb8888 : + _radeon_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return _radeon_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: +#if defined(RADEON_R200) + /* r200: can't use a8 format since interpreting hw I8 as a8 would result + in wrong rgb values (same as alpha value instead of 0). */ + return _radeon_texformat_al88; +#else + return MESA_FORMAT_A_UNORM8; +#endif + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return MESA_FORMAT_L_UNORM8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return _radeon_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return MESA_FORMAT_I_UNORM8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE) + return MESA_FORMAT_YCBCR; + else + return MESA_FORMAT_YCBCR_REV; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return MESA_FORMAT_RGB_DXT1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return MESA_FORMAT_RGBA_DXT1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return MESA_FORMAT_RGBA_DXT3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return MESA_FORMAT_RGBA_DXT5; + + case GL_ALPHA16F_ARB: + return MESA_FORMAT_A_FLOAT16; + case GL_ALPHA32F_ARB: + return MESA_FORMAT_A_FLOAT32; + case GL_LUMINANCE16F_ARB: + return MESA_FORMAT_L_FLOAT16; + case GL_LUMINANCE32F_ARB: + return MESA_FORMAT_L_FLOAT32; + case GL_LUMINANCE_ALPHA16F_ARB: + return MESA_FORMAT_LA_FLOAT16; + case GL_LUMINANCE_ALPHA32F_ARB: + return MESA_FORMAT_LA_FLOAT32; + case GL_INTENSITY16F_ARB: + return MESA_FORMAT_I_FLOAT16; + case GL_INTENSITY32F_ARB: + return MESA_FORMAT_I_FLOAT32; + case GL_RGB16F_ARB: + return MESA_FORMAT_RGBA_FLOAT16; + case GL_RGB32F_ARB: + return MESA_FORMAT_RGBA_FLOAT32; + case GL_RGBA16F_ARB: + return MESA_FORMAT_RGBA_FLOAT16; + case GL_RGBA32F_ARB: + return MESA_FORMAT_RGBA_FLOAT32; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + return MESA_FORMAT_Z24_UNORM_S8_UINT; + + /* EXT_texture_sRGB */ + case GL_SRGB: + case GL_SRGB8: + case GL_SRGB_ALPHA: + case GL_SRGB8_ALPHA8: + case GL_COMPRESSED_SRGB: + case GL_COMPRESSED_SRGB_ALPHA: + return MESA_FORMAT_B8G8R8A8_SRGB; + + case GL_SLUMINANCE: + case GL_SLUMINANCE8: + case GL_COMPRESSED_SLUMINANCE: + return MESA_FORMAT_L_SRGB8; + + case GL_SLUMINANCE_ALPHA: + case GL_SLUMINANCE8_ALPHA8: + case GL_COMPRESSED_SLUMINANCE_ALPHA: + return MESA_FORMAT_L8A8_SRGB; + + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + return MESA_FORMAT_SRGB_DXT1; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return MESA_FORMAT_SRGBA_DXT1; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return MESA_FORMAT_SRGBA_DXT3; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return MESA_FORMAT_SRGBA_DXT5; + + default: + _mesa_problem(ctx, + "unexpected internalFormat 0x%x in %s", + (int)internalFormat, __func__); + return MESA_FORMAT_NONE; + } + + return MESA_FORMAT_NONE; /* never get here */ +} + +/** Check if given image is valid within current texture object. + */ +static void teximage_assign_miptree(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + /* Try using current miptree, or create new if there isn't any */ + if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) { + radeon_miptree_unreference(&t->mt); + t->mt = radeon_miptree_create_for_teximage(rmesa, + texObj, + texImage); + + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: texObj %p, texImage %p, " + "texObj miptree doesn't match, allocated new miptree %p\n", + __func__, texObj, texImage, t->mt); + } + + /* Miptree alocation may have failed, + * when there was no image for baselevel specified */ + if (t->mt) { + radeon_miptree_reference(t->mt, &image->mt); + } else + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Failed to allocate miptree.\n", __func__); +} + +unsigned radeonIsFormatRenderable(mesa_format mesa_format) +{ + if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 || + mesa_format == _radeon_texformat_argb1555 || mesa_format == _radeon_texformat_argb4444) + return 1; + + switch (mesa_format) + { + case MESA_FORMAT_Z_UNORM16: + case MESA_FORMAT_Z24_UNORM_S8_UINT: + return 1; + default: + return 0; + } +} + +void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLeglImageOES image_handle) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image *radeonImage = get_radeon_texture_image(texImage); + __DRIscreen *screen; + __DRIimage *image; + + screen = radeon->radeonScreen->driScreen; + image = screen->dri2.image->lookupEGLImage(screen, image_handle, + screen->loaderPrivate); + if (image == NULL) + return; + + radeonFreeTextureImageBuffer(ctx, texImage); + + texImage->Width = image->width; + texImage->Height = image->height; + texImage->Depth = 1; + texImage->_BaseFormat = GL_RGBA; + texImage->TexFormat = image->format; + radeonImage->base.RowStride = image->pitch; + texImage->InternalFormat = image->internal_format; + + if(t->mt) + { + radeon_miptree_unreference(&t->mt); + t->mt = NULL; + } + + /* NOTE: The following is *very* ugly and will probably break. But + I don't know how to deal with it, without creating a whole new + function like radeon_miptree_from_bo() so I'm going with the + easy but error-prone way. */ + + radeon_try_alloc_miptree(radeon, t); + + radeon_miptree_reference(t->mt, &radeonImage->mt); + + if (t->mt == NULL) + { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Failed to allocate miptree.\n", __func__); + return; + } + + /* Particularly ugly: this is guaranteed to break, if image->bo is + not of the required size for a miptree. */ + radeon_bo_unref(t->mt->bo); + radeon_bo_ref(image->bo); + t->mt->bo = image->bo; + + if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base)) + fprintf(stderr, "miptree doesn't match image\n"); +} + +mesa_format _radeon_texformat_rgba8888 = MESA_FORMAT_NONE; +mesa_format _radeon_texformat_argb8888 = MESA_FORMAT_NONE; +mesa_format _radeon_texformat_rgb565 = MESA_FORMAT_NONE; +mesa_format _radeon_texformat_argb4444 = MESA_FORMAT_NONE; +mesa_format _radeon_texformat_argb1555 = MESA_FORMAT_NONE; +mesa_format _radeon_texformat_al88 = MESA_FORMAT_NONE; +/*@}*/ + + +static void +radeonInitTextureFormats(void) +{ + if (_mesa_little_endian()) { + _radeon_texformat_rgba8888 = MESA_FORMAT_A8B8G8R8_UNORM; + _radeon_texformat_argb8888 = MESA_FORMAT_B8G8R8A8_UNORM; + _radeon_texformat_rgb565 = MESA_FORMAT_B5G6R5_UNORM; + _radeon_texformat_argb4444 = MESA_FORMAT_B4G4R4A4_UNORM; + _radeon_texformat_argb1555 = MESA_FORMAT_B5G5R5A1_UNORM; + _radeon_texformat_al88 = MESA_FORMAT_L8A8_UNORM; + } + else { + _radeon_texformat_rgba8888 = MESA_FORMAT_R8G8B8A8_UNORM; + _radeon_texformat_argb8888 = MESA_FORMAT_A8R8G8B8_UNORM; + _radeon_texformat_rgb565 = MESA_FORMAT_R5G6B5_UNORM; + _radeon_texformat_argb4444 = MESA_FORMAT_A4R4G4B4_UNORM; + _radeon_texformat_argb1555 = MESA_FORMAT_A1R5G5B5_UNORM; + _radeon_texformat_al88 = MESA_FORMAT_A8L8_UNORM; + } +} + +void +radeon_init_common_texture_funcs(radeonContextPtr radeon, + struct dd_function_table *functions) +{ + functions->NewTextureImage = radeonNewTextureImage; + functions->DeleteTextureImage = radeonDeleteTextureImage; + functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer; + functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer; + functions->MapTextureImage = radeon_map_texture_image; + functions->UnmapTextureImage = radeon_unmap_texture_image; + + functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; + + functions->CopyTexSubImage = radeonCopyTexSubImage; + + functions->Bitmap = _mesa_meta_Bitmap; + functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d; + + radeonInitTextureFormats(); +} + +static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeonTexObj *t = radeon_tex_obj(texObj); + GLuint firstLevel; + GLuint lastLevel; + int width, height, depth; + int i; + + width = texImage->Width; + height = texImage->Height; + depth = texImage->Depth; + + if (texImage->Level > texObj->BaseLevel && + (width == 1 || + (texObj->Target != GL_TEXTURE_1D && height == 1) || + (texObj->Target == GL_TEXTURE_3D && depth == 1))) { + /* For this combination, we're at some lower mipmap level and + * some important dimension is 1. We can't extrapolate up to a + * likely base level width/height/depth for a full mipmap stack + * from this info, so just allocate this one level. + */ + firstLevel = texImage->Level; + lastLevel = texImage->Level; + } else { + if (texImage->Level < texObj->BaseLevel) + firstLevel = 0; + else + firstLevel = texObj->BaseLevel; + + for (i = texImage->Level; i > firstLevel; i--) { + width <<= 1; + if (height != 1) + height <<= 1; + if (depth != 1) + depth <<= 1; + } + if ((texObj->Sampler.MinFilter == GL_NEAREST || + texObj->Sampler.MinFilter == GL_LINEAR) && + texImage->Level == firstLevel) { + lastLevel = firstLevel; + } else { + lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth)); + } + } + + return radeon_miptree_create(rmesa, texObj->Target, + texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1, + width, height, depth, + t->tile_bits); +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_texture.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_texture.h new file mode 100644 index 000000000..286b2a20a --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_texture.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_TEXTURE_H +#define RADEON_TEXTURE_H + +#include "main/formats.h" + +extern mesa_format _radeon_texformat_rgba8888; +extern mesa_format _radeon_texformat_argb8888; +extern mesa_format _radeon_texformat_rgb565; +extern mesa_format _radeon_texformat_argb4444; +extern mesa_format _radeon_texformat_argb1555; +extern mesa_format _radeon_texformat_al88; + +extern +void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, + GLuint numrows, GLuint rowsize); +struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx); +void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage); + +int radeon_validate_texture_miptree(struct gl_context * ctx, + struct gl_sampler_object *samp, + struct gl_texture_object *texObj); + + +mesa_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, + GLenum target, + GLint internalFormat, + GLenum format, + GLenum type); + +mesa_format radeonChooseTextureFormat(struct gl_context * ctx, + GLint internalFormat, + GLenum format, + GLenum type, GLboolean fbo); + +void radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + struct gl_renderbuffer *rb, + GLint x, GLint y, + GLsizei width, GLsizei height); + +unsigned radeonIsFormatRenderable(mesa_format mesa_format); + +void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLeglImageOES image_handle); + +void +radeon_init_common_texture_funcs(radeonContextPtr radeon, + struct dd_function_table *functions); + +#endif diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_tile.c b/lib/mesa/src/mesa/drivers/dri/r200/radeon_tile.c new file mode 100644 index 000000000..433199fdc --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_tile.c @@ -0,0 +1,513 @@ +/* + * Copyright (C) 2010 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_screen.h" +#include "radeon_tile.h" + +#include <stdint.h> +#include <string.h> + +#include "main/macros.h" +#include "radeon_debug.h" + +#define MICRO_TILE_SIZE 32 + +static void micro_tile_8_x_4_8bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current source row */ + unsigned col; /* current source column */ + unsigned k; /* number of processed tiles */ + const unsigned tile_width = 8, tile_height = 4; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint8_t *src2 = (uint8_t *)src + src_pitch * row + col; + uint8_t *dst2 = (uint8_t *)dst + row * dst_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint8_t); + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint8_t)); + dst2 += tile_width; + src2 += src_pitch; + } + } + } +} + +static void micro_tile_4_x_4_16bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current source row */ + unsigned col; /* current source column */ + unsigned k; /* number of processed tiles */ + const unsigned tile_width = 4, tile_height = 4; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint16_t *src2 = (uint16_t *)src + src_pitch * row + col; + uint16_t *dst2 = (uint16_t *)dst + row * dst_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint16_t); + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint16_t)); + dst2 += tile_width; + src2 += src_pitch; + } + } + } +} + +static void micro_tile_8_x_2_16bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current source row */ + unsigned col; /* current source column */ + unsigned k; /* number of processed tiles */ + const unsigned tile_width = 8, tile_height = 2; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint16_t *src2 = (uint16_t *)src + src_pitch * row + col; + uint16_t *dst2 = (uint16_t *)dst + row * dst_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint16_t); + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint16_t)); + dst2 += tile_width; + src2 += src_pitch; + } + } + } +} + +static void micro_tile_4_x_2_32bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current source row */ + unsigned col; /* current source column */ + unsigned k; /* number of processed tiles */ + const unsigned tile_width = 4, tile_height = 2; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint32_t *src2 = (uint32_t *)src + src_pitch * row + col; + uint32_t *dst2 = (uint32_t *)dst + row * dst_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint32_t); + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint32_t)); + dst2 += tile_width; + src2 += src_pitch; + } + } + } +} + +static void micro_tile_2_x_2_64bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current source row */ + unsigned col; /* current source column */ + unsigned k; /* number of processed tiles */ + const unsigned tile_width = 2, tile_height = 2; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint64_t *src2 = (uint64_t *)src + src_pitch * row + col; + uint64_t *dst2 = (uint64_t *)dst + row * dst_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint64_t); + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint64_t)); + dst2 += tile_width; + src2 += src_pitch; + } + } + } +} + +static void micro_tile_1_x_1_128bit(const void * src, unsigned src_pitch, + void * dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned i, j; + const unsigned elem_size = 16; /* sizeof(uint128_t) */ + + for (j = 0; j < height; ++j) + { + for (i = 0; i < width; ++i) + { + memcpy(dst, src, width * elem_size); + dst += dst_pitch * elem_size; + src += src_pitch * elem_size; + } + } +} + +void tile_image(const void * src, unsigned src_pitch, + void *dst, unsigned dst_pitch, + mesa_format format, unsigned width, unsigned height) +{ + assert(src_pitch >= width); + assert(dst_pitch >= width); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "Software tiling: src_pitch %d, dst_pitch %d, width %d, height %d, bpp %d\n", + src_pitch, dst_pitch, width, height, _mesa_get_format_bytes(format)); + + switch (_mesa_get_format_bytes(format)) + { + case 16: + micro_tile_1_x_1_128bit(src, src_pitch, dst, dst_pitch, width, height); + break; + case 8: + micro_tile_2_x_2_64bit(src, src_pitch, dst, dst_pitch, width, height); + break; + case 4: + micro_tile_4_x_2_32bit(src, src_pitch, dst, dst_pitch, width, height); + break; + case 2: + if (_mesa_get_format_bits(format, GL_DEPTH_BITS)) + { + micro_tile_4_x_4_16bit(src, src_pitch, dst, dst_pitch, width, height); + } + else + { + micro_tile_8_x_2_16bit(src, src_pitch, dst, dst_pitch, width, height); + } + break; + case 1: + micro_tile_8_x_4_8bit(src, src_pitch, dst, dst_pitch, width, height); + break; + default: + assert(0); + break; + } +} + +static void micro_untile_8_x_4_8bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current destination row */ + unsigned col; /* current destination column */ + unsigned k; /* current tile number */ + const unsigned tile_width = 8, tile_height = 4; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + assert(src_pitch % tile_width == 0); + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint8_t *src2 = (uint8_t *)src + row * src_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint8_t); + uint8_t *dst2 = (uint8_t *)dst + dst_pitch * row + col; + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint8_t)); + dst2 += dst_pitch; + src2 += tile_width; + } + } + } +} + +static void micro_untile_8_x_2_16bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current destination row */ + unsigned col; /* current destination column */ + unsigned k; /* current tile number */ + const unsigned tile_width = 8, tile_height = 2; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + assert(src_pitch % tile_width == 0); + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint16_t *src2 = (uint16_t *)src + row * src_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint16_t); + uint16_t *dst2 = (uint16_t *)dst + dst_pitch * row + col; + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint16_t)); + dst2 += dst_pitch; + src2 += tile_width; + } + } + } +} + +static void micro_untile_4_x_4_16bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current destination row */ + unsigned col; /* current destination column */ + unsigned k; /* current tile number */ + const unsigned tile_width = 4, tile_height = 4; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + assert(src_pitch % tile_width == 0); + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint16_t *src2 = (uint16_t *)src + row * src_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint16_t); + uint16_t *dst2 = (uint16_t *)dst + dst_pitch * row + col; + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint16_t)); + dst2 += dst_pitch; + src2 += tile_width; + } + } + } +} + +static void micro_untile_4_x_2_32bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current destination row */ + unsigned col; /* current destination column */ + unsigned k; /* current tile number */ + const unsigned tile_width = 4, tile_height = 2; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + assert(src_pitch % tile_width == 0); + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint32_t *src2 = (uint32_t *)src + row * src_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint32_t); + uint32_t *dst2 = (uint32_t *)dst + dst_pitch * row + col; + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint32_t)); + dst2 += dst_pitch; + src2 += tile_width; + } + } + } +} + +static void micro_untile_2_x_2_64bit(const void * const src, unsigned src_pitch, + void * const dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned row; /* current destination row */ + unsigned col; /* current destination column */ + unsigned k; /* current tile number */ + const unsigned tile_width = 2, tile_height = 2; + const unsigned tiles_in_row = (width + (tile_width - 1)) / tile_width; + + assert(src_pitch % tile_width == 0); + + k = 0; + for (row = 0; row < height; row += tile_height) + { + for (col = 0; col < width; col += tile_width, ++k) + { + uint64_t *src2 = (uint64_t *)src + row * src_pitch + + (k % tiles_in_row) * MICRO_TILE_SIZE / sizeof(uint64_t); + uint64_t *dst2 = (uint64_t *)dst + dst_pitch * row + col; + unsigned j; + + for (j = 0; j < MIN2(tile_height, height - row); ++j) + { + unsigned columns = MIN2(tile_width, width - col); + memcpy(dst2, src2, columns * sizeof(uint64_t)); + dst2 += dst_pitch; + src2 += tile_width; + } + } + } +} + +static void micro_untile_1_x_1_128bit(const void * src, unsigned src_pitch, + void * dst, unsigned dst_pitch, + unsigned width, unsigned height) +{ + unsigned i, j; + const unsigned elem_size = 16; /* sizeof(uint128_t) */ + + for (j = 0; j < height; ++j) + { + for (i = 0; i < width; ++i) + { + memcpy(dst, src, width * elem_size); + dst += dst_pitch * elem_size; + src += src_pitch * elem_size; + } + } +} + +void untile_image(const void * src, unsigned src_pitch, + void *dst, unsigned dst_pitch, + mesa_format format, unsigned width, unsigned height) +{ + assert(src_pitch >= width); + assert(dst_pitch >= width); + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "Software untiling: src_pitch %d, dst_pitch %d, width %d, height %d, bpp %d\n", + src_pitch, dst_pitch, width, height, _mesa_get_format_bytes(format)); + + switch (_mesa_get_format_bytes(format)) + { + case 16: + micro_untile_1_x_1_128bit(src, src_pitch, dst, dst_pitch, width, height); + break; + case 8: + micro_untile_2_x_2_64bit(src, src_pitch, dst, dst_pitch, width, height); + break; + case 4: + micro_untile_4_x_2_32bit(src, src_pitch, dst, dst_pitch, width, height); + break; + case 2: + if (_mesa_get_format_bits(format, GL_DEPTH_BITS)) + { + micro_untile_4_x_4_16bit(src, src_pitch, dst, dst_pitch, width, height); + } + else + { + micro_untile_8_x_2_16bit(src, src_pitch, dst, dst_pitch, width, height); + } + break; + case 1: + micro_untile_8_x_4_8bit(src, src_pitch, dst, dst_pitch, width, height); + break; + default: + assert(0); + break; + } +} + +void get_tile_size(mesa_format format, unsigned *block_width, unsigned *block_height) +{ + switch (_mesa_get_format_bytes(format)) + { + case 16: + *block_width = 1; + *block_height = 1; + break; + case 8: + *block_width = 2; + *block_height = 2; + break; + case 4: + *block_width = 4; + *block_height = 2; + break; + case 2: + if (_mesa_get_format_bits(format, GL_DEPTH_BITS)) + { + *block_width = 4; + *block_height = 4; + } + else + { + *block_width = 8; + *block_height = 2; + } + break; + case 1: + *block_width = 8; + *block_height = 4; + break; + default: + assert(0); + break; + } +} diff --git a/lib/mesa/src/mesa/drivers/dri/r200/radeon_tile.h b/lib/mesa/src/mesa/drivers/dri/r200/radeon_tile.h new file mode 100644 index 000000000..6654c7db7 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/radeon_tile.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include <main/formats.h> + +void tile_image(const void * src, unsigned src_pitch, + void *dst, unsigned dst_pitch, + mesa_format format, unsigned width, unsigned height); + +void untile_image(const void * src, unsigned src_pitch, + void *dst, unsigned dst_pitch, + mesa_format format, unsigned width, unsigned height); + +void get_tile_size(mesa_format format, unsigned *block_width, unsigned *block_height); diff --git a/lib/mesa/src/mesa/drivers/dri/r200/server/radeon_reg.h b/lib/mesa/src/mesa/drivers/dri/r200/server/radeon_reg.h new file mode 100644 index 000000000..7ba5b38c4 --- /dev/null +++ b/lib/mesa/src/mesa/drivers/dri/r200/server/radeon_reg.h @@ -0,0 +1,2163 @@ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and + * VA Linux Systems Inc., Fremont, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * Authors: + * Kevin E. Martin <martin@xfree86.org> + * Rickard E. Faith <faith@valinux.com> + * Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * !!!! FIXME !!!! + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h + * AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT + * ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */ + +#ifndef _RADEON_REG_H_ +#define _RADEON_REG_H_ + + /* Registers for 2D/Video/Overlay */ +#define RADEON_ADAPTER_ID 0x0f2c /* PCI */ +#define RADEON_AGP_BASE 0x0170 +#define RADEON_AGP_CNTL 0x0174 +# define RADEON_AGP_APER_SIZE_256MB (0x00 << 0) +# define RADEON_AGP_APER_SIZE_128MB (0x20 << 0) +# define RADEON_AGP_APER_SIZE_64MB (0x30 << 0) +# define RADEON_AGP_APER_SIZE_32MB (0x38 << 0) +# define RADEON_AGP_APER_SIZE_16MB (0x3c << 0) +# define RADEON_AGP_APER_SIZE_8MB (0x3e << 0) +# define RADEON_AGP_APER_SIZE_4MB (0x3f << 0) +# define RADEON_AGP_APER_SIZE_MASK (0x3f << 0) +#define RADEON_AGP_COMMAND 0x0f60 /* PCI */ +#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config*/ +# define RADEON_AGP_ENABLE (1<<8) +#define RADEON_AGP_PLL_CNTL 0x000b /* PLL */ +#define RADEON_AGP_STATUS 0x0f5c /* PCI */ +# define RADEON_AGP_1X_MODE 0x01 +# define RADEON_AGP_2X_MODE 0x02 +# define RADEON_AGP_4X_MODE 0x04 +# define RADEON_AGP_FW_MODE 0x10 +# define RADEON_AGP_MODE_MASK 0x17 +#define RADEON_ATTRDR 0x03c1 /* VGA */ +#define RADEON_ATTRDW 0x03c0 /* VGA */ +#define RADEON_ATTRX 0x03c0 /* VGA */ +#define RADEON_AUX_SC_CNTL 0x1660 +# define RADEON_AUX1_SC_EN (1 << 0) +# define RADEON_AUX1_SC_MODE_OR (0 << 1) +# define RADEON_AUX1_SC_MODE_NAND (1 << 1) +# define RADEON_AUX2_SC_EN (1 << 2) +# define RADEON_AUX2_SC_MODE_OR (0 << 3) +# define RADEON_AUX2_SC_MODE_NAND (1 << 3) +# define RADEON_AUX3_SC_EN (1 << 4) +# define RADEON_AUX3_SC_MODE_OR (0 << 5) +# define RADEON_AUX3_SC_MODE_NAND (1 << 5) +#define RADEON_AUX1_SC_BOTTOM 0x1670 +#define RADEON_AUX1_SC_LEFT 0x1664 +#define RADEON_AUX1_SC_RIGHT 0x1668 +#define RADEON_AUX1_SC_TOP 0x166c +#define RADEON_AUX2_SC_BOTTOM 0x1680 +#define RADEON_AUX2_SC_LEFT 0x1674 +#define RADEON_AUX2_SC_RIGHT 0x1678 +#define RADEON_AUX2_SC_TOP 0x167c +#define RADEON_AUX3_SC_BOTTOM 0x1690 +#define RADEON_AUX3_SC_LEFT 0x1684 +#define RADEON_AUX3_SC_RIGHT 0x1688 +#define RADEON_AUX3_SC_TOP 0x168c +#define RADEON_AUX_WINDOW_HORZ_CNTL 0x02d8 +#define RADEON_AUX_WINDOW_VERT_CNTL 0x02dc + +#define RADEON_BASE_CODE 0x0f0b +#define RADEON_BIOS_0_SCRATCH 0x0010 +#define RADEON_BIOS_1_SCRATCH 0x0014 +#define RADEON_BIOS_2_SCRATCH 0x0018 +#define RADEON_BIOS_3_SCRATCH 0x001c +#define RADEON_BIOS_4_SCRATCH 0x0020 +#define RADEON_BIOS_5_SCRATCH 0x0024 +#define RADEON_BIOS_6_SCRATCH 0x0028 +#define RADEON_BIOS_7_SCRATCH 0x002c +#define RADEON_BIOS_ROM 0x0f30 /* PCI */ +#define RADEON_BIST 0x0f0f /* PCI */ +#define RADEON_BRUSH_DATA0 0x1480 +#define RADEON_BRUSH_DATA1 0x1484 +#define RADEON_BRUSH_DATA10 0x14a8 +#define RADEON_BRUSH_DATA11 0x14ac +#define RADEON_BRUSH_DATA12 0x14b0 +#define RADEON_BRUSH_DATA13 0x14b4 +#define RADEON_BRUSH_DATA14 0x14b8 +#define RADEON_BRUSH_DATA15 0x14bc +#define RADEON_BRUSH_DATA16 0x14c0 +#define RADEON_BRUSH_DATA17 0x14c4 +#define RADEON_BRUSH_DATA18 0x14c8 +#define RADEON_BRUSH_DATA19 0x14cc +#define RADEON_BRUSH_DATA2 0x1488 +#define RADEON_BRUSH_DATA20 0x14d0 +#define RADEON_BRUSH_DATA21 0x14d4 +#define RADEON_BRUSH_DATA22 0x14d8 +#define RADEON_BRUSH_DATA23 0x14dc +#define RADEON_BRUSH_DATA24 0x14e0 +#define RADEON_BRUSH_DATA25 0x14e4 +#define RADEON_BRUSH_DATA26 0x14e8 +#define RADEON_BRUSH_DATA27 0x14ec +#define RADEON_BRUSH_DATA28 0x14f0 +#define RADEON_BRUSH_DATA29 0x14f4 +#define RADEON_BRUSH_DATA3 0x148c +#define RADEON_BRUSH_DATA30 0x14f8 +#define RADEON_BRUSH_DATA31 0x14fc +#define RADEON_BRUSH_DATA32 0x1500 +#define RADEON_BRUSH_DATA33 0x1504 +#define RADEON_BRUSH_DATA34 0x1508 +#define RADEON_BRUSH_DATA35 0x150c +#define RADEON_BRUSH_DATA36 0x1510 +#define RADEON_BRUSH_DATA37 0x1514 +#define RADEON_BRUSH_DATA38 0x1518 +#define RADEON_BRUSH_DATA39 0x151c +#define RADEON_BRUSH_DATA4 0x1490 +#define RADEON_BRUSH_DATA40 0x1520 +#define RADEON_BRUSH_DATA41 0x1524 +#define RADEON_BRUSH_DATA42 0x1528 +#define RADEON_BRUSH_DATA43 0x152c +#define RADEON_BRUSH_DATA44 0x1530 +#define RADEON_BRUSH_DATA45 0x1534 +#define RADEON_BRUSH_DATA46 0x1538 +#define RADEON_BRUSH_DATA47 0x153c +#define RADEON_BRUSH_DATA48 0x1540 +#define RADEON_BRUSH_DATA49 0x1544 +#define RADEON_BRUSH_DATA5 0x1494 +#define RADEON_BRUSH_DATA50 0x1548 +#define RADEON_BRUSH_DATA51 0x154c +#define RADEON_BRUSH_DATA52 0x1550 +#define RADEON_BRUSH_DATA53 0x1554 +#define RADEON_BRUSH_DATA54 0x1558 +#define RADEON_BRUSH_DATA55 0x155c +#define RADEON_BRUSH_DATA56 0x1560 +#define RADEON_BRUSH_DATA57 0x1564 +#define RADEON_BRUSH_DATA58 0x1568 +#define RADEON_BRUSH_DATA59 0x156c +#define RADEON_BRUSH_DATA6 0x1498 +#define RADEON_BRUSH_DATA60 0x1570 +#define RADEON_BRUSH_DATA61 0x1574 +#define RADEON_BRUSH_DATA62 0x1578 +#define RADEON_BRUSH_DATA63 0x157c +#define RADEON_BRUSH_DATA7 0x149c +#define RADEON_BRUSH_DATA8 0x14a0 +#define RADEON_BRUSH_DATA9 0x14a4 +#define RADEON_BRUSH_SCALE 0x1470 +#define RADEON_BRUSH_Y_X 0x1474 +#define RADEON_BUS_CNTL 0x0030 +# define RADEON_BUS_MASTER_DIS (1 << 6) +# define RADEON_BUS_RD_DISCARD_EN (1 << 24) +# define RADEON_BUS_RD_ABORT_EN (1 << 25) +# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define RADEON_BUS_WRT_BURST (1 << 29) +# define RADEON_BUS_READ_BURST (1 << 30) +#define RADEON_BUS_CNTL1 0x0034 +# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define RADEON_CACHE_CNTL 0x1724 +#define RADEON_CACHE_LINE 0x0f0c /* PCI */ +#define RADEON_CAP0_TRIG_CNTL 0x0950 /* ? */ +#define RADEON_CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ +#define RADEON_CAPABILITIES_PTR 0x0f34 /* PCI */ +#define RADEON_CLK_PIN_CNTL 0x0001 /* PLL */ +#define RADEON_CLOCK_CNTL_DATA 0x000c +#define RADEON_CLOCK_CNTL_INDEX 0x0008 +# define RADEON_PLL_WR_EN (1 << 7) +# define RADEON_PLL_DIV_SEL (3 << 8) +# define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8) +#define RADEON_CLR_CMP_CLR_3D 0x1a24 +#define RADEON_CLR_CMP_CLR_DST 0x15c8 +#define RADEON_CLR_CMP_CLR_SRC 0x15c4 +#define RADEON_CLR_CMP_CNTL 0x15c0 +# define RADEON_SRC_CMP_EQ_COLOR (4 << 0) +# define RADEON_SRC_CMP_NEQ_COLOR (5 << 0) +# define RADEON_CLR_CMP_SRC_SOURCE (1 << 24) +#define RADEON_CLR_CMP_MASK 0x15cc +# define RADEON_CLR_CMP_MSK 0xffffffff +#define RADEON_CLR_CMP_MASK_3D 0x1A28 +#define RADEON_COMMAND 0x0f04 /* PCI */ +#define RADEON_COMPOSITE_SHADOW_ID 0x1a0c +#define RADEON_CONFIG_APER_0_BASE 0x0100 +#define RADEON_CONFIG_APER_1_BASE 0x0104 +#define RADEON_CONFIG_APER_SIZE 0x0108 +#define RADEON_CONFIG_BONDS 0x00e8 +#define RADEON_CONFIG_CNTL 0x00e0 +# define RADEON_CFG_ATI_REV_A11 (0 << 16) +# define RADEON_CFG_ATI_REV_A12 (1 << 16) +# define RADEON_CFG_ATI_REV_A13 (2 << 16) +# define RADEON_CFG_ATI_REV_ID_MASK (0xf << 16) +#define RADEON_CONFIG_MEMSIZE 0x00f8 +#define RADEON_CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define RADEON_CONFIG_REG_1_BASE 0x010c +#define RADEON_CONFIG_REG_APER_SIZE 0x0110 +#define RADEON_CONFIG_XSTRAP 0x00e4 +#define RADEON_CONSTANT_COLOR_C 0x1d34 +# define RADEON_CONSTANT_COLOR_MASK 0x00ffffff +# define RADEON_CONSTANT_COLOR_ONE 0x00ffffff +# define RADEON_CONSTANT_COLOR_ZERO 0x00000000 +#define RADEON_CRC_CMDFIFO_ADDR 0x0740 +#define RADEON_CRC_CMDFIFO_DOUT 0x0744 +#define RADEON_GRPH_BUFFER_CNTL 0x02f0 +# define RADEON_GRPH_START_REQ_MASK (0x7f) +# define RADEON_GRPH_START_REQ_SHIFT 0 +# define RADEON_GRPH_STOP_REQ_MASK (0x7f<<8) +# define RADEON_GRPH_STOP_REQ_SHIFT 8 +# define RADEON_GRPH_CRITICAL_POINT_MASK (0x7f<<16) +# define RADEON_GRPH_CRITICAL_POINT_SHIFT 16 +# define RADEON_GRPH_CRITICAL_CNTL (1<<28) +# define RADEON_GRPH_BUFFER_SIZE (1<<29) +# define RADEON_GRPH_CRITICAL_AT_SOF (1<<30) +# define RADEON_GRPH_STOP_CNTL (1<<31) +#define RADEON_GRPH2_BUFFER_CNTL 0x03f0 +# define RADEON_GRPH2_START_REQ_MASK (0x7f) +# define RADEON_GRPH2_START_REQ_SHIFT 0 +# define RADEON_GRPH2_STOP_REQ_MASK (0x7f<<8) +# define RADEON_GRPH2_STOP_REQ_SHIFT 8 +# define RADEON_GRPH2_CRITICAL_POINT_MASK (0x7f<<16) +# define RADEON_GRPH2_CRITICAL_POINT_SHIFT 16 +# define RADEON_GRPH2_CRITICAL_CNTL (1<<28) +# define RADEON_GRPH2_BUFFER_SIZE (1<<29) +# define RADEON_GRPH2_CRITICAL_AT_SOF (1<<30) +# define RADEON_GRPH2_STOP_CNTL (1<<31) +#define RADEON_CRTC_CRNT_FRAME 0x0214 +#define RADEON_CRTC_EXT_CNTL 0x0054 +# define RADEON_CRTC_VGA_XOVERSCAN (1 << 0) +# define RADEON_VGA_ATI_LINEAR (1 << 3) +# define RADEON_XCRT_CNT_EN (1 << 6) +# define RADEON_CRTC_HSYNC_DIS (1 << 8) +# define RADEON_CRTC_VSYNC_DIS (1 << 9) +# define RADEON_CRTC_DISPLAY_DIS (1 << 10) +# define RADEON_CRTC_SYNC_TRISTAT (1 << 11) +# define RADEON_CRTC_CRT_ON (1 << 15) +#define RADEON_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define RADEON_CRTC_HSYNC_DIS_BYTE (1 << 0) +# define RADEON_CRTC_VSYNC_DIS_BYTE (1 << 1) +# define RADEON_CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define RADEON_CRTC_GEN_CNTL 0x0050 +# define RADEON_CRTC_DBL_SCAN_EN (1 << 0) +# define RADEON_CRTC_INTERLACE_EN (1 << 1) +# define RADEON_CRTC_CSYNC_EN (1 << 4) +# define RADEON_CRTC_CUR_EN (1 << 16) +# define RADEON_CRTC_CUR_MODE_MASK (7 << 17) +# define RADEON_CRTC_ICON_EN (1 << 20) +# define RADEON_CRTC_EXT_DISP_EN (1 << 24) +# define RADEON_CRTC_EN (1 << 25) +# define RADEON_CRTC_DISP_REQ_EN_B (1 << 26) +#define RADEON_CRTC2_GEN_CNTL 0x03f8 +# define RADEON_CRTC2_DBL_SCAN_EN (1 << 0) +# define RADEON_CRTC2_INTERLACE_EN (1 << 1) +# define RADEON_CRTC2_SYNC_TRISTAT (1 << 4) +# define RADEON_CRTC2_HSYNC_TRISTAT (1 << 5) +# define RADEON_CRTC2_VSYNC_TRISTAT (1 << 6) +# define RADEON_CRTC2_CRT2_ON (1 << 7) +# define RADEON_CRTC2_ICON_EN (1 << 15) +# define RADEON_CRTC2_CUR_EN (1 << 16) +# define RADEON_CRTC2_CUR_MODE_MASK (7 << 20) +# define RADEON_CRTC2_DISP_DIS (1 << 23) +# define RADEON_CRTC2_EN (1 << 25) +# define RADEON_CRTC2_DISP_REQ_EN_B (1 << 26) +# define RADEON_CRTC2_CSYNC_EN (1 << 27) +# define RADEON_CRTC2_HSYNC_DIS (1 << 28) +# define RADEON_CRTC2_VSYNC_DIS (1 << 29) +#define RADEON_CRTC_MORE_CNTL 0x27c +# define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4) +# define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5) +#define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 +#define RADEON_CRTC_H_SYNC_STRT_WID 0x0204 +# define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define RADEON_CRTC_H_SYNC_STRT_CHAR (0x3ff << 3) +# define RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define RADEON_CRTC_H_SYNC_WID (0x3f << 16) +# define RADEON_CRTC_H_SYNC_WID_SHIFT 16 +# define RADEON_CRTC_H_SYNC_POL (1 << 23) +#define RADEON_CRTC2_H_SYNC_STRT_WID 0x0304 +# define RADEON_CRTC2_H_SYNC_STRT_PIX (0x07 << 0) +# define RADEON_CRTC2_H_SYNC_STRT_CHAR (0x3ff << 3) +# define RADEON_CRTC2_H_SYNC_STRT_CHAR_SHIFT 3 +# define RADEON_CRTC2_H_SYNC_WID (0x3f << 16) +# define RADEON_CRTC2_H_SYNC_WID_SHIFT 16 +# define RADEON_CRTC2_H_SYNC_POL (1 << 23) +#define RADEON_CRTC_H_TOTAL_DISP 0x0200 +# define RADEON_CRTC_H_TOTAL (0x03ff << 0) +# define RADEON_CRTC_H_TOTAL_SHIFT 0 +# define RADEON_CRTC_H_DISP (0x01ff << 16) +# define RADEON_CRTC_H_DISP_SHIFT 16 +#define RADEON_CRTC2_H_TOTAL_DISP 0x0300 +# define RADEON_CRTC2_H_TOTAL (0x03ff << 0) +# define RADEON_CRTC2_H_TOTAL_SHIFT 0 +# define RADEON_CRTC2_H_DISP (0x01ff << 16) +# define RADEON_CRTC2_H_DISP_SHIFT 16 +#define RADEON_CRTC_OFFSET 0x0224 +#define RADEON_CRTC2_OFFSET 0x0324 +#define RADEON_CRTC_OFFSET_CNTL 0x0228 +# define RADEON_CRTC_TILE_EN (1 << 15) +#define RADEON_CRTC2_OFFSET_CNTL 0x0328 +# define RADEON_CRTC2_TILE_EN (1 << 15) +#define RADEON_CRTC_PITCH 0x022c +#define RADEON_CRTC2_PITCH 0x032c +#define RADEON_CRTC_STATUS 0x005c +# define RADEON_CRTC_VBLANK_SAVE (1 << 1) +# define RADEON_CRTC_VBLANK_SAVE_CLEAR (1 << 1) +#define RADEON_CRTC2_STATUS 0x03fc +# define RADEON_CRTC2_VBLANK_SAVE (1 << 1) +# define RADEON_CRTC2_VBLANK_SAVE_CLEAR (1 << 1) +#define RADEON_CRTC_V_SYNC_STRT_WID 0x020c +# define RADEON_CRTC_V_SYNC_STRT (0x7ff << 0) +# define RADEON_CRTC_V_SYNC_STRT_SHIFT 0 +# define RADEON_CRTC_V_SYNC_WID (0x1f << 16) +# define RADEON_CRTC_V_SYNC_WID_SHIFT 16 +# define RADEON_CRTC_V_SYNC_POL (1 << 23) +#define RADEON_CRTC2_V_SYNC_STRT_WID 0x030c +# define RADEON_CRTC2_V_SYNC_STRT (0x7ff << 0) +# define RADEON_CRTC2_V_SYNC_STRT_SHIFT 0 +# define RADEON_CRTC2_V_SYNC_WID (0x1f << 16) +# define RADEON_CRTC2_V_SYNC_WID_SHIFT 16 +# define RADEON_CRTC2_V_SYNC_POL (1 << 23) +#define RADEON_CRTC_V_TOTAL_DISP 0x0208 +# define RADEON_CRTC_V_TOTAL (0x07ff << 0) +# define RADEON_CRTC_V_TOTAL_SHIFT 0 +# define RADEON_CRTC_V_DISP (0x07ff << 16) +# define RADEON_CRTC_V_DISP_SHIFT 16 +#define RADEON_CRTC2_V_TOTAL_DISP 0x0308 +# define RADEON_CRTC2_V_TOTAL (0x07ff << 0) +# define RADEON_CRTC2_V_TOTAL_SHIFT 0 +# define RADEON_CRTC2_V_DISP (0x07ff << 16) +# define RADEON_CRTC2_V_DISP_SHIFT 16 +#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210 +# define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define RADEON_CRTC2_CRNT_FRAME 0x0314 +#define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318 +#define RADEON_CRTC2_STATUS 0x03fc +#define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310 +#define RADEON_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define RADEON_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define RADEON_CUR_CLR0 0x026c +#define RADEON_CUR_CLR1 0x0270 +#define RADEON_CUR_HORZ_VERT_OFF 0x0268 +#define RADEON_CUR_HORZ_VERT_POSN 0x0264 +#define RADEON_CUR_OFFSET 0x0260 +# define RADEON_CUR_LOCK (1 << 31) +#define RADEON_CUR2_CLR0 0x036c +#define RADEON_CUR2_CLR1 0x0370 +#define RADEON_CUR2_HORZ_VERT_OFF 0x0368 +#define RADEON_CUR2_HORZ_VERT_POSN 0x0364 +#define RADEON_CUR2_OFFSET 0x0360 +# define RADEON_CUR2_LOCK (1 << 31) + +#define RADEON_DAC_CNTL 0x0058 +# define RADEON_DAC_RANGE_CNTL (3 << 0) +# define RADEON_DAC_RANGE_CNTL_MASK 0x03 +# define RADEON_DAC_BLANKING (1 << 2) +# define RADEON_DAC_CMP_EN (1 << 3) +# define RADEON_DAC_CMP_OUTPUT (1 << 7) +# define RADEON_DAC_8BIT_EN (1 << 8) +# define RADEON_DAC_VGA_ADR_EN (1 << 13) +# define RADEON_DAC_PDWN (1 << 15) +# define RADEON_DAC_MASK_ALL (0xff << 24) +#define RADEON_DAC_CNTL2 0x007c +# define RADEON_DAC2_DAC_CLK_SEL (1 << 0) +# define RADEON_DAC2_DAC2_CLK_SEL (1 << 1) +# define RADEON_DAC2_PALETTE_ACC_CTL (1 << 5) +#define RADEON_DAC_EXT_CNTL 0x0280 +# define RADEON_DAC_FORCE_BLANK_OFF_EN (1 << 4) +# define RADEON_DAC_FORCE_DATA_EN (1 << 5) +# define RADEON_DAC_FORCE_DATA_SEL_MASK (3 << 6) +# define RADEON_DAC_FORCE_DATA_MASK 0x0003ff00 +# define RADEON_DAC_FORCE_DATA_SHIFT 8 +#define RADEON_TV_DAC_CNTL 0x088c +# define RADEON_TV_DAC_STD_MASK 0x0300 +# define RADEON_TV_DAC_RDACPD (1 << 24) +# define RADEON_TV_DAC_GDACPD (1 << 25) +# define RADEON_TV_DAC_BDACPD (1 << 26) +#define RADEON_DISP_HW_DEBUG 0x0d14 +# define RADEON_CRT2_DISP1_SEL (1 << 5) +#define RADEON_DISP_OUTPUT_CNTL 0x0d64 +# define RADEON_DISP_DAC_SOURCE_MASK 0x03 +# define RADEON_DISP_DAC2_SOURCE_MASK 0x0c +# define RADEON_DISP_DAC_SOURCE_CRTC2 0x01 +# define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04 +#define RADEON_DAC_CRC_SIG 0x02cc +#define RADEON_DAC_DATA 0x03c9 /* VGA */ +#define RADEON_DAC_MASK 0x03c6 /* VGA */ +#define RADEON_DAC_R_INDEX 0x03c7 /* VGA */ +#define RADEON_DAC_W_INDEX 0x03c8 /* VGA */ +#define RADEON_DDA_CONFIG 0x02e0 +#define RADEON_DDA_ON_OFF 0x02e4 +#define RADEON_DEFAULT_OFFSET 0x16e0 +#define RADEON_DEFAULT_PITCH 0x16e4 +#define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define RADEON_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define RADEON_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define RADEON_DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define RADEON_DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define RADEON_DEVICE_ID 0x0f02 /* PCI */ +#define RADEON_DISP_MISC_CNTL 0x0d00 +# define RADEON_SOFT_RESET_GRPH_PP (1 << 0) +#define RADEON_DISP_MERGE_CNTL 0x0d60 +# define RADEON_DISP_ALPHA_MODE_MASK 0x03 +# define RADEON_DISP_ALPHA_MODE_KEY 0 +# define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1 +# define RADEON_DISP_ALPHA_MODE_GLOBAL 2 +# define RADEON_DISP_RGB_OFFSET_EN (1<<8) +# define RADEON_DISP_GRPH_ALPHA_MASK (0xff << 16) +# define RADEON_DISP_OV0_ALPHA_MASK (0xff << 24) +# define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9) +#define RADEON_DISP2_MERGE_CNTL 0x0d68 +# define RADEON_DISP2_RGB_OFFSET_EN (1<<8) +#define RADEON_DISP_LIN_TRANS_GRPH_A 0x0d80 +#define RADEON_DISP_LIN_TRANS_GRPH_B 0x0d84 +#define RADEON_DISP_LIN_TRANS_GRPH_C 0x0d88 +#define RADEON_DISP_LIN_TRANS_GRPH_D 0x0d8c +#define RADEON_DISP_LIN_TRANS_GRPH_E 0x0d90 +#define RADEON_DISP_LIN_TRANS_GRPH_F 0x0d98 +#define RADEON_DP_BRUSH_BKGD_CLR 0x1478 +#define RADEON_DP_BRUSH_FRGD_CLR 0x147c +#define RADEON_DP_CNTL 0x16c0 +# define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0) +# define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define RADEON_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define RADEON_DST_Y_MAJOR (1 << 2) +# define RADEON_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define RADEON_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define RADEON_DP_DATATYPE 0x16c4 +# define RADEON_HOST_BIG_ENDIAN_EN (1 << 29) +#define RADEON_DP_GUI_MASTER_CNTL 0x146c +# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define RADEON_GMC_SRC_CLIPPING (1 << 2) +# define RADEON_GMC_DST_CLIPPING (1 << 3) +# define RADEON_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define RADEON_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define RADEON_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define RADEON_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define RADEON_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define RADEON_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define RADEON_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define RADEON_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4) +# define RADEON_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4) +# define RADEON_GMC_BRUSH_8x8_COLOR (10 << 4) +# define RADEON_GMC_BRUSH_1X8_COLOR (12 << 4) +# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define RADEON_GMC_BRUSH_NONE (15 << 4) +# define RADEON_GMC_DST_8BPP_CI (2 << 8) +# define RADEON_GMC_DST_15BPP (3 << 8) +# define RADEON_GMC_DST_16BPP (4 << 8) +# define RADEON_GMC_DST_24BPP (5 << 8) +# define RADEON_GMC_DST_32BPP (6 << 8) +# define RADEON_GMC_DST_8BPP_RGB (7 << 8) +# define RADEON_GMC_DST_Y8 (8 << 8) +# define RADEON_GMC_DST_RGB8 (9 << 8) +# define RADEON_GMC_DST_VYUY (11 << 8) +# define RADEON_GMC_DST_YVYU (12 << 8) +# define RADEON_GMC_DST_AYUV444 (14 << 8) +# define RADEON_GMC_DST_ARGB4444 (15 << 8) +# define RADEON_GMC_DST_DATATYPE_MASK (0x0f << 8) +# define RADEON_GMC_DST_DATATYPE_SHIFT 8 +# define RADEON_GMC_SRC_DATATYPE_MASK (3 << 12) +# define RADEON_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define RADEON_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define RADEON_GMC_BYTE_PIX_ORDER (1 << 14) +# define RADEON_GMC_BYTE_MSB_TO_LSB (0 << 14) +# define RADEON_GMC_BYTE_LSB_TO_MSB (1 << 14) +# define RADEON_GMC_CONVERSION_TEMP (1 << 15) +# define RADEON_GMC_CONVERSION_TEMP_6500 (0 << 15) +# define RADEON_GMC_CONVERSION_TEMP_9300 (1 << 15) +# define RADEON_GMC_ROP3_MASK (0xff << 16) +# define RADEON_DP_SRC_SOURCE_MASK (7 << 24) +# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) +# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define RADEON_GMC_3D_FCN_EN (1 << 27) +# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define RADEON_GMC_AUX_CLIP_DIS (1 << 29) +# define RADEON_GMC_WR_MSK_DIS (1 << 30) +# define RADEON_GMC_LD_BRUSH_Y_X (1 << 31) +# define RADEON_ROP3_ZERO 0x00000000 +# define RADEON_ROP3_DSa 0x00880000 +# define RADEON_ROP3_SDna 0x00440000 +# define RADEON_ROP3_S 0x00cc0000 +# define RADEON_ROP3_DSna 0x00220000 +# define RADEON_ROP3_D 0x00aa0000 +# define RADEON_ROP3_DSx 0x00660000 +# define RADEON_ROP3_DSo 0x00ee0000 +# define RADEON_ROP3_DSon 0x00110000 +# define RADEON_ROP3_DSxn 0x00990000 +# define RADEON_ROP3_Dn 0x00550000 +# define RADEON_ROP3_SDno 0x00dd0000 +# define RADEON_ROP3_Sn 0x00330000 +# define RADEON_ROP3_DSno 0x00bb0000 +# define RADEON_ROP3_DSan 0x00770000 +# define RADEON_ROP3_ONE 0x00ff0000 +# define RADEON_ROP3_DPa 0x00a00000 +# define RADEON_ROP3_PDna 0x00500000 +# define RADEON_ROP3_P 0x00f00000 +# define RADEON_ROP3_DPna 0x000a0000 +# define RADEON_ROP3_D 0x00aa0000 +# define RADEON_ROP3_DPx 0x005a0000 +# define RADEON_ROP3_DPo 0x00fa0000 +# define RADEON_ROP3_DPon 0x00050000 +# define RADEON_ROP3_PDxn 0x00a50000 +# define RADEON_ROP3_PDno 0x00f50000 +# define RADEON_ROP3_Pn 0x000f0000 +# define RADEON_ROP3_DPno 0x00af0000 +# define RADEON_ROP3_DPan 0x005f0000 +#define RADEON_DP_GUI_MASTER_CNTL_C 0x1c84 +#define RADEON_DP_MIX 0x16c8 +#define RADEON_DP_SRC_BKGD_CLR 0x15dc +#define RADEON_DP_SRC_FRGD_CLR 0x15d8 +#define RADEON_DP_WRITE_MASK 0x16cc +#define RADEON_DST_BRES_DEC 0x1630 +#define RADEON_DST_BRES_ERR 0x1628 +#define RADEON_DST_BRES_INC 0x162c +#define RADEON_DST_BRES_LNTH 0x1634 +#define RADEON_DST_BRES_LNTH_SUB 0x1638 +#define RADEON_DST_HEIGHT 0x1410 +#define RADEON_DST_HEIGHT_WIDTH 0x143c +#define RADEON_DST_HEIGHT_WIDTH_8 0x158c +#define RADEON_DST_HEIGHT_WIDTH_BW 0x15b4 +#define RADEON_DST_HEIGHT_Y 0x15a0 +#define RADEON_DST_LINE_START 0x1600 +#define RADEON_DST_LINE_END 0x1604 +#define RADEON_DST_LINE_PATCOUNT 0x1608 +# define RADEON_BRES_CNTL_SHIFT 8 +#define RADEON_DST_OFFSET 0x1404 +#define RADEON_DST_PITCH 0x1408 +#define RADEON_DST_PITCH_OFFSET 0x142c +#define RADEON_DST_PITCH_OFFSET_C 0x1c80 +# define RADEON_PITCH_SHIFT 21 +# define RADEON_DST_TILE_LINEAR (0 << 30) +# define RADEON_DST_TILE_MACRO (1 << 30) +# define RADEON_DST_TILE_MICRO (2 << 30) +# define RADEON_DST_TILE_BOTH (3 << 30) +#define RADEON_DST_WIDTH 0x140c +#define RADEON_DST_WIDTH_HEIGHT 0x1598 +#define RADEON_DST_WIDTH_X 0x1588 +#define RADEON_DST_WIDTH_X_INCY 0x159c +#define RADEON_DST_X 0x141c +#define RADEON_DST_X_SUB 0x15a4 +#define RADEON_DST_X_Y 0x1594 +#define RADEON_DST_Y 0x1420 +#define RADEON_DST_Y_SUB 0x15a8 +#define RADEON_DST_Y_X 0x1438 + +#define RADEON_FCP_CNTL 0x0910 +# define RADEON_FCP0_SRC_PCICLK 0 +# define RADEON_FCP0_SRC_PCLK 1 +# define RADEON_FCP0_SRC_PCLKb 2 +# define RADEON_FCP0_SRC_HREF 3 +# define RADEON_FCP0_SRC_GND 4 +# define RADEON_FCP0_SRC_HREFb 5 +#define RADEON_FLUSH_1 0x1704 +#define RADEON_FLUSH_2 0x1708 +#define RADEON_FLUSH_3 0x170c +#define RADEON_FLUSH_4 0x1710 +#define RADEON_FLUSH_5 0x1714 +#define RADEON_FLUSH_6 0x1718 +#define RADEON_FLUSH_7 0x171c +#define RADEON_FOG_3D_TABLE_START 0x1810 +#define RADEON_FOG_3D_TABLE_END 0x1814 +#define RADEON_FOG_3D_TABLE_DENSITY 0x181c +#define RADEON_FOG_TABLE_INDEX 0x1a14 +#define RADEON_FOG_TABLE_DATA 0x1a18 +#define RADEON_FP_CRTC_H_TOTAL_DISP 0x0250 +#define RADEON_FP_CRTC_V_TOTAL_DISP 0x0254 +#define RADEON_FP_CRTC2_H_TOTAL_DISP 0x0350 +#define RADEON_FP_CRTC2_V_TOTAL_DISP 0x0354 +# define RADEON_FP_CRTC_H_TOTAL_MASK 0x000003ff +# define RADEON_FP_CRTC_H_DISP_MASK 0x01ff0000 +# define RADEON_FP_CRTC_V_TOTAL_MASK 0x00000fff +# define RADEON_FP_CRTC_V_DISP_MASK 0x0fff0000 +# define RADEON_FP_H_SYNC_STRT_CHAR_MASK 0x00001ff8 +# define RADEON_FP_H_SYNC_WID_MASK 0x003f0000 +# define RADEON_FP_V_SYNC_STRT_MASK 0x00000fff +# define RADEON_FP_V_SYNC_WID_MASK 0x001f0000 +# define RADEON_FP_CRTC_H_TOTAL_SHIFT 0x00000000 +# define RADEON_FP_CRTC_H_DISP_SHIFT 0x00000010 +# define RADEON_FP_CRTC_V_TOTAL_SHIFT 0x00000000 +# define RADEON_FP_CRTC_V_DISP_SHIFT 0x00000010 +# define RADEON_FP_H_SYNC_STRT_CHAR_SHIFT 0x00000003 +# define RADEON_FP_H_SYNC_WID_SHIFT 0x00000010 +# define RADEON_FP_V_SYNC_STRT_SHIFT 0x00000000 +# define RADEON_FP_V_SYNC_WID_SHIFT 0x00000010 +#define RADEON_FP_GEN_CNTL 0x0284 +# define RADEON_FP_FPON (1 << 0) +# define RADEON_FP_TMDS_EN (1 << 2) +# define RADEON_FP_PANEL_FORMAT (1 << 3) +# define RADEON_FP_EN_TMDS (1 << 7) +# define RADEON_FP_DETECT_SENSE (1 << 8) +# define RADEON_FP_SEL_CRTC2 (1 << 13) +# define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) +# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) +# define RADEON_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define RADEON_FP_RMX_HVSYNC_CONTROL_EN (1 << 20) +# define RADEON_FP_DFP_SYNC_SEL (1 << 21) +# define RADEON_FP_CRTC_LOCK_8DOT (1 << 22) +# define RADEON_FP_CRT_SYNC_SEL (1 << 23) +# define RADEON_FP_USE_SHADOW_EN (1 << 24) +# define RADEON_FP_CRT_SYNC_ALT (1 << 26) +#define RADEON_FP2_GEN_CNTL 0x0288 +# define RADEON_FP2_BLANK_EN (1 << 1) +# define RADEON_FP2_ON (1 << 2) +# define RADEON_FP2_PANEL_FORMAT (1 << 3) +# define RADEON_FP2_SOURCE_SEL_MASK (3 << 10) +# define RADEON_FP2_SOURCE_SEL_CRTC2 (1 << 10) +# define RADEON_FP2_SRC_SEL_MASK (3 << 13) +# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13) +# define RADEON_FP2_FP_POL (1 << 16) +# define RADEON_FP2_LP_POL (1 << 17) +# define RADEON_FP2_SCK_POL (1 << 18) +# define RADEON_FP2_LCD_CNTL_MASK (7 << 19) +# define RADEON_FP2_PAD_FLOP_EN (1 << 22) +# define RADEON_FP2_CRC_EN (1 << 23) +# define RADEON_FP2_CRC_READ_EN (1 << 24) +# define RADEON_FP2_DV0_EN (1 << 25) +# define RADEON_FP2_DV0_RATE_SEL_SDR (1 << 26) +#define RADEON_FP_H_SYNC_STRT_WID 0x02c4 +#define RADEON_FP_H2_SYNC_STRT_WID 0x03c4 +#define RADEON_FP_HORZ_STRETCH 0x028c +#define RADEON_FP_HORZ2_STRETCH 0x038c +# define RADEON_HORZ_STRETCH_RATIO_MASK 0xffff +# define RADEON_HORZ_STRETCH_RATIO_MAX 4096 +# define RADEON_HORZ_PANEL_SIZE (0x1ff << 16) +# define RADEON_HORZ_PANEL_SHIFT 16 +# define RADEON_HORZ_STRETCH_PIXREP (0 << 25) +# define RADEON_HORZ_STRETCH_BLEND (1 << 26) +# define RADEON_HORZ_STRETCH_ENABLE (1 << 25) +# define RADEON_HORZ_AUTO_RATIO (1 << 27) +# define RADEON_HORZ_FP_LOOP_STRETCH (0x7 << 28) +# define RADEON_HORZ_AUTO_RATIO_INC (1 << 31) +#define RADEON_FP_V_SYNC_STRT_WID 0x02c8 +#define RADEON_FP_VERT_STRETCH 0x0290 +#define RADEON_FP_V2_SYNC_STRT_WID 0x03c8 +#define RADEON_FP_VERT2_STRETCH 0x0390 +# define RADEON_VERT_PANEL_SIZE (0xfff << 12) +# define RADEON_VERT_PANEL_SHIFT 12 +# define RADEON_VERT_STRETCH_RATIO_MASK 0xfff +# define RADEON_VERT_STRETCH_RATIO_SHIFT 0 +# define RADEON_VERT_STRETCH_RATIO_MAX 4096 +# define RADEON_VERT_STRETCH_ENABLE (1 << 25) +# define RADEON_VERT_STRETCH_LINEREP (0 << 26) +# define RADEON_VERT_STRETCH_BLEND (1 << 26) +# define RADEON_VERT_AUTO_RATIO_EN (1 << 27) +# define RADEON_VERT_STRETCH_RESERVED 0xf1000000 + +#define RADEON_GEN_INT_CNTL 0x0040 +#define RADEON_GEN_INT_STATUS 0x0044 +# define RADEON_VSYNC_INT_AK (1 << 2) +# define RADEON_VSYNC_INT (1 << 2) +# define RADEON_VSYNC2_INT_AK (1 << 6) +# define RADEON_VSYNC2_INT (1 << 6) +#define RADEON_GENENB 0x03c3 /* VGA */ +#define RADEON_GENFC_RD 0x03ca /* VGA */ +#define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ +#define RADEON_GENMO_RD 0x03cc /* VGA */ +#define RADEON_GENMO_WT 0x03c2 /* VGA */ +#define RADEON_GENS0 0x03c2 /* VGA */ +#define RADEON_GENS1 0x03da /* VGA, 0x03ba */ +#define RADEON_GPIO_MONID 0x0068 /* DDC interface via I2C */ +#define RADEON_GPIO_MONIDB 0x006c +#define RADEON_GPIO_CRT2_DDC 0x006c +#define RADEON_GPIO_DVI_DDC 0x0064 +#define RADEON_GPIO_VGA_DDC 0x0060 +# define RADEON_GPIO_A_0 (1 << 0) +# define RADEON_GPIO_A_1 (1 << 1) +# define RADEON_GPIO_Y_0 (1 << 8) +# define RADEON_GPIO_Y_1 (1 << 9) +# define RADEON_GPIO_Y_SHIFT_0 8 +# define RADEON_GPIO_Y_SHIFT_1 9 +# define RADEON_GPIO_EN_0 (1 << 16) +# define RADEON_GPIO_EN_1 (1 << 17) +# define RADEON_GPIO_MASK_0 (1 << 24) /*??*/ +# define RADEON_GPIO_MASK_1 (1 << 25) /*??*/ +#define RADEON_GRPH8_DATA 0x03cf /* VGA */ +#define RADEON_GRPH8_IDX 0x03ce /* VGA */ +#define RADEON_GUI_SCRATCH_REG0 0x15e0 +#define RADEON_GUI_SCRATCH_REG1 0x15e4 +#define RADEON_GUI_SCRATCH_REG2 0x15e8 +#define RADEON_GUI_SCRATCH_REG3 0x15ec +#define RADEON_GUI_SCRATCH_REG4 0x15f0 +#define RADEON_GUI_SCRATCH_REG5 0x15f4 + +#define RADEON_HEADER 0x0f0e /* PCI */ +#define RADEON_HOST_DATA0 0x17c0 +#define RADEON_HOST_DATA1 0x17c4 +#define RADEON_HOST_DATA2 0x17c8 +#define RADEON_HOST_DATA3 0x17cc +#define RADEON_HOST_DATA4 0x17d0 +#define RADEON_HOST_DATA5 0x17d4 +#define RADEON_HOST_DATA6 0x17d8 +#define RADEON_HOST_DATA7 0x17dc +#define RADEON_HOST_DATA_LAST 0x17e0 +#define RADEON_HOST_PATH_CNTL 0x0130 +# define RADEON_HDP_SOFT_RESET (1 << 26) +#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */ +#define RADEON_HTOTAL2_CNTL 0x002e /* PLL */ + +#define RADEON_I2C_CNTL_1 0x0094 /* ? */ +#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */ +#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ +#define RADEON_INTERRUPT_PIN 0x0f3d /* PCI */ +#define RADEON_IO_BASE 0x0f14 /* PCI */ + +#define RADEON_LATENCY 0x0f0d /* PCI */ +#define RADEON_LEAD_BRES_DEC 0x1608 +#define RADEON_LEAD_BRES_LNTH 0x161c +#define RADEON_LEAD_BRES_LNTH_SUB 0x1624 +#define RADEON_LVDS_GEN_CNTL 0x02d0 +# define RADEON_LVDS_ON (1 << 0) +# define RADEON_LVDS_DISPLAY_DIS (1 << 1) +# define RADEON_LVDS_PANEL_TYPE (1 << 2) +# define RADEON_LVDS_PANEL_FORMAT (1 << 3) +# define RADEON_LVDS_EN (1 << 7) +# define RADEON_LVDS_DIGON (1 << 18) +# define RADEON_LVDS_BLON (1 << 19) +# define RADEON_LVDS_SEL_CRTC2 (1 << 23) +#define RADEON_LVDS_PLL_CNTL 0x02d4 +# define RADEON_HSYNC_DELAY_SHIFT 28 +# define RADEON_HSYNC_DELAY_MASK (0xf << 28) + +#define RADEON_MAX_LATENCY 0x0f3f /* PCI */ +#define RADEON_MC_AGP_LOCATION 0x014c +#define RADEON_MC_FB_LOCATION 0x0148 +#define RADEON_DISPLAY_BASE_ADDR 0x23c +#define RADEON_DISPLAY2_BASE_ADDR 0x33c +#define RADEON_OV0_BASE_ADDR 0x43c +#define RADEON_NB_TOM 0x15c +#define RADEON_MCLK_CNTL 0x0012 /* PLL */ +# define RADEON_FORCEON_MCLKA (1 << 16) +# define RADEON_FORCEON_MCLKB (1 << 17) +# define RADEON_FORCEON_YCLKA (1 << 18) +# define RADEON_FORCEON_YCLKB (1 << 19) +# define RADEON_FORCEON_MC (1 << 20) +# define RADEON_FORCEON_AIC (1 << 21) +#define RADEON_MDGPIO_A_REG 0x01ac +#define RADEON_MDGPIO_EN_REG 0x01b0 +#define RADEON_MDGPIO_MASK 0x0198 +#define RADEON_MDGPIO_Y_REG 0x01b4 +#define RADEON_MEM_ADDR_CONFIG 0x0148 +#define RADEON_MEM_BASE 0x0f10 /* PCI */ +#define RADEON_MEM_CNTL 0x0140 +# define RADEON_MEM_NUM_CHANNELS_MASK 0x01 +# define RADEON_MEM_USE_B_CH_ONLY (1<<1) +# define RV100_HALF_MODE (1<<3) +#define RADEON_MEM_TIMING_CNTL 0x0144 /* EXT_MEM_CNTL */ +#define RADEON_MEM_INIT_LAT_TIMER 0x0154 +#define RADEON_MEM_INTF_CNTL 0x014c +#define RADEON_MEM_SDRAM_MODE_REG 0x0158 +#define RADEON_MEM_STR_CNTL 0x0150 +#define RADEON_MEM_VGA_RP_SEL 0x003c +#define RADEON_MEM_VGA_WP_SEL 0x0038 +#define RADEON_MIN_GRANT 0x0f3e /* PCI */ +#define RADEON_MM_DATA 0x0004 +#define RADEON_MM_INDEX 0x0000 +#define RADEON_MPLL_CNTL 0x000e /* PLL */ +#define RADEON_MPP_TB_CONFIG 0x01c0 /* ? */ +#define RADEON_MPP_GP_CONFIG 0x01c8 /* ? */ + +#define RADEON_N_VIF_COUNT 0x0248 + +#define RADEON_OV0_AUTO_FLIP_CNTL 0x0470 +#define RADEON_OV0_COLOUR_CNTL 0x04E0 +#define RADEON_OV0_DEINTERLACE_PATTERN 0x0474 +#define RADEON_OV0_EXCLUSIVE_HORZ 0x0408 +# define RADEON_EXCL_HORZ_START_MASK 0x000000ff +# define RADEON_EXCL_HORZ_END_MASK 0x0000ff00 +# define RADEON_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define RADEON_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define RADEON_OV0_EXCLUSIVE_VERT 0x040C +# define RADEON_EXCL_VERT_START_MASK 0x000003ff +# define RADEON_EXCL_VERT_END_MASK 0x03ff0000 +#define RADEON_OV0_FILTER_CNTL 0x04A0 +#define RADEON_OV0_FOUR_TAP_COEF_0 0x04B0 +#define RADEON_OV0_FOUR_TAP_COEF_1 0x04B4 +#define RADEON_OV0_FOUR_TAP_COEF_2 0x04B8 +#define RADEON_OV0_FOUR_TAP_COEF_3 0x04BC +#define RADEON_OV0_FOUR_TAP_COEF_4 0x04C0 +#define RADEON_OV0_GAMMA_000_00F 0x0d40 +#define RADEON_OV0_GAMMA_010_01F 0x0d44 +#define RADEON_OV0_GAMMA_020_03F 0x0d48 +#define RADEON_OV0_GAMMA_040_07F 0x0d4c +#define RADEON_OV0_GAMMA_080_0BF 0x0e00 +#define RADEON_OV0_GAMMA_0C0_0FF 0x0e04 +#define RADEON_OV0_GAMMA_100_13F 0x0e08 +#define RADEON_OV0_GAMMA_140_17F 0x0e0c +#define RADEON_OV0_GAMMA_180_1BF 0x0e10 +#define RADEON_OV0_GAMMA_1C0_1FF 0x0e14 +#define RADEON_OV0_GAMMA_200_23F 0x0e18 +#define RADEON_OV0_GAMMA_240_27F 0x0e1c +#define RADEON_OV0_GAMMA_280_2BF 0x0e20 +#define RADEON_OV0_GAMMA_2C0_2FF 0x0e24 +#define RADEON_OV0_GAMMA_300_33F 0x0e28 +#define RADEON_OV0_GAMMA_340_37F 0x0e2c +#define RADEON_OV0_GAMMA_380_3BF 0x0d50 +#define RADEON_OV0_GAMMA_3C0_3FF 0x0d54 +#define RADEON_OV0_GRAPHICS_KEY_CLR_LOW 0x04EC +#define RADEON_OV0_GRAPHICS_KEY_CLR_HIGH 0x04F0 +#define RADEON_OV0_H_INC 0x0480 +#define RADEON_OV0_KEY_CNTL 0x04F4 +# define RADEON_VIDEO_KEY_FN_MASK 0x00000003L +# define RADEON_VIDEO_KEY_FN_FALSE 0x00000000L +# define RADEON_VIDEO_KEY_FN_TRUE 0x00000001L +# define RADEON_VIDEO_KEY_FN_EQ 0x00000002L +# define RADEON_VIDEO_KEY_FN_NE 0x00000003L +# define RADEON_GRAPHIC_KEY_FN_MASK 0x00000030L +# define RADEON_GRAPHIC_KEY_FN_FALSE 0x00000000L +# define RADEON_GRAPHIC_KEY_FN_TRUE 0x00000010L +# define RADEON_GRAPHIC_KEY_FN_EQ 0x00000020L +# define RADEON_GRAPHIC_KEY_FN_NE 0x00000030L +# define RADEON_CMP_MIX_MASK 0x00000100L +# define RADEON_CMP_MIX_OR 0x00000000L +# define RADEON_CMP_MIX_AND 0x00000100L +#define RADEON_OV0_LIN_TRANS_A 0x0d20 +#define RADEON_OV0_LIN_TRANS_B 0x0d24 +#define RADEON_OV0_LIN_TRANS_C 0x0d28 +#define RADEON_OV0_LIN_TRANS_D 0x0d2c +#define RADEON_OV0_LIN_TRANS_E 0x0d30 +#define RADEON_OV0_LIN_TRANS_F 0x0d34 +#define RADEON_OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define RADEON_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL +# define RADEON_P1_ACTIVE_LINES_M1 0x0fff0000L +#define RADEON_OV0_P1_H_ACCUM_INIT 0x0488 +#define RADEON_OV0_P1_V_ACCUM_INIT 0x0428 +# define RADEON_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define RADEON_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L +#define RADEON_OV0_P1_X_START_END 0x0494 +#define RADEON_OV0_P2_X_START_END 0x0498 +#define RADEON_OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define RADEON_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL +# define RADEON_P23_ACTIVE_LINES_M1 0x07ff0000L +#define RADEON_OV0_P23_H_ACCUM_INIT 0x048C +#define RADEON_OV0_P23_V_ACCUM_INIT 0x042C +#define RADEON_OV0_P3_X_START_END 0x049C +#define RADEON_OV0_REG_LOAD_CNTL 0x0410 +# define RADEON_REG_LD_CTL_LOCK 0x00000001L +# define RADEON_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L +# define RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L +# define RADEON_REG_LD_CTL_LOCK_READBACK 0x00000008L +#define RADEON_OV0_SCALE_CNTL 0x0420 +# define RADEON_SCALER_HORZ_PICK_NEAREST 0x00000004L +# define RADEON_SCALER_VERT_PICK_NEAREST 0x00000008L +# define RADEON_SCALER_SIGNED_UV 0x00000010L +# define RADEON_SCALER_GAMMA_SEL_MASK 0x00000060L +# define RADEON_SCALER_GAMMA_SEL_BRIGHT 0x00000000L +# define RADEON_SCALER_GAMMA_SEL_G22 0x00000020L +# define RADEON_SCALER_GAMMA_SEL_G18 0x00000040L +# define RADEON_SCALER_GAMMA_SEL_G14 0x00000060L +# define RADEON_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L +# define RADEON_SCALER_SURFAC_FORMAT 0x00000f00L +# define RADEON_SCALER_SOURCE_15BPP 0x00000300L +# define RADEON_SCALER_SOURCE_16BPP 0x00000400L +# define RADEON_SCALER_SOURCE_32BPP 0x00000600L +# define RADEON_SCALER_SOURCE_YUV9 0x00000900L +# define RADEON_SCALER_SOURCE_YUV12 0x00000A00L +# define RADEON_SCALER_SOURCE_VYUY422 0x00000B00L +# define RADEON_SCALER_SOURCE_YVYU422 0x00000C00L +# define RADEON_SCALER_ADAPTIVE_DEINT 0x00001000L +# define RADEON_SCALER_TEMPORAL_DEINT 0x00002000L +# define RADEON_SCALER_SMART_SWITCH 0x00008000L +# define RADEON_SCALER_BURST_PER_PLANE 0x007F0000L +# define RADEON_SCALER_DOUBLE_BUFFER 0x01000000L +# define RADEON_SCALER_DIS_LIMIT 0x08000000L +# define RADEON_SCALER_INT_EMU 0x20000000L +# define RADEON_SCALER_ENABLE 0x40000000L +# define RADEON_SCALER_SOFT_RESET 0x80000000L +# define RADEON_SCALER_ADAPTIVE_DEINT 0x00001000L +#define RADEON_OV0_STEP_BY 0x0484 +#define RADEON_OV0_TEST 0x04F8 +#define RADEON_OV0_V_INC 0x0424 +#define RADEON_OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define RADEON_OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define RADEON_OV0_VID_BUF0_BASE_ADRS 0x0440 +# define RADEON_VIF_BUF0_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF0_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF1_BASE_ADRS 0x0444 +# define RADEON_VIF_BUF1_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF1_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF2_BASE_ADRS 0x0448 +# define RADEON_VIF_BUF2_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF2_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF3_BASE_ADRS 0x044C +#define RADEON_OV0_VID_BUF4_BASE_ADRS 0x0450 +#define RADEON_OV0_VID_BUF5_BASE_ADRS 0x0454 +#define RADEON_OV0_VIDEO_KEY_CLR_HIGH 0x04E8 +#define RADEON_OV0_VIDEO_KEY_CLR_LOW 0x04E4 +#define RADEON_OV0_Y_X_START 0x0400 +#define RADEON_OV0_Y_X_END 0x0404 +#define RADEON_OV1_Y_X_START 0x0600 +#define RADEON_OV1_Y_X_END 0x0604 +#define RADEON_OVR_CLR 0x0230 +#define RADEON_OVR_WID_LEFT_RIGHT 0x0234 +#define RADEON_OVR_WID_TOP_BOTTOM 0x0238 + +#define RADEON_P2PLL_CNTL 0x002a /* P2PLL */ +# define RADEON_P2PLL_RESET (1 << 0) +# define RADEON_P2PLL_SLEEP (1 << 1) +# define RADEON_P2PLL_ATOMIC_UPDATE_EN (1 << 16) +# define RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +# define RADEON_P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18) +#define RADEON_P2PLL_DIV_0 0x002c +# define RADEON_P2PLL_FB0_DIV_MASK 0x07ff +# define RADEON_P2PLL_POST0_DIV_MASK 0x00070000 +#define RADEON_P2PLL_REF_DIV 0x002B /* PLL */ +# define RADEON_P2PLL_REF_DIV_MASK 0x03ff +# define RADEON_P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define RADEON_P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define RADEON_PALETTE_DATA 0x00b4 +#define RADEON_PALETTE_30_DATA 0x00b8 +#define RADEON_PALETTE_INDEX 0x00b0 +#define RADEON_PCI_GART_PAGE 0x017c +#define RADEON_PIXCLKS_CNTL 0x002d +# define RADEON_PIX2CLK_SRC_SEL_MASK 0x03 +# define RADEON_PIX2CLK_SRC_SEL_CPUCLK 0x00 +# define RADEON_PIX2CLK_SRC_SEL_PSCANCLK 0x01 +# define RADEON_PIX2CLK_SRC_SEL_BYTECLK 0x02 +# define RADEON_PIX2CLK_SRC_SEL_P2PLLCLK 0x03 +# define RADEON_PIX2CLK_ALWAYS_ONb (1<<6) +# define RADEON_PIX2CLK_DAC_ALWAYS_ONb (1<<7) +# define RADEON_PIXCLK_TV_SRC_SEL (1 << 8) +# define RADEON_PIXCLK_LVDS_ALWAYS_ONb (1 << 14) +# define RADEON_PIXCLK_TMDS_ALWAYS_ONb (1 << 15) +#define RADEON_PLANE_3D_MASK_C 0x1d44 +#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */ +#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */ +#define RADEON_PMI_DATA 0x0f63 /* PCI */ +#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define RADEON_PMI_PMC_REG 0x0f5e /* PCI */ +#define RADEON_PMI_PMCSR_REG 0x0f60 /* PCI */ +#define RADEON_PMI_REGISTER 0x0f5c /* PCI */ +#define RADEON_PPLL_CNTL 0x0002 /* PLL */ +# define RADEON_PPLL_RESET (1 << 0) +# define RADEON_PPLL_SLEEP (1 << 1) +# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) +#define RADEON_PPLL_DIV_0 0x0004 /* PLL */ +#define RADEON_PPLL_DIV_1 0x0005 /* PLL */ +#define RADEON_PPLL_DIV_2 0x0006 /* PLL */ +#define RADEON_PPLL_DIV_3 0x0007 /* PLL */ +# define RADEON_PPLL_FB3_DIV_MASK 0x07ff +# define RADEON_PPLL_POST3_DIV_MASK 0x00070000 +#define RADEON_PPLL_REF_DIV 0x0003 /* PLL */ +# define RADEON_PPLL_REF_DIV_MASK 0x03ff +# define RADEON_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ + +#define RADEON_RBBM_GUICNTL 0x172c +# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) +# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) +# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) +# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) +#define RADEON_RBBM_SOFT_RESET 0x00f0 +# define RADEON_SOFT_RESET_CP (1 << 0) +# define RADEON_SOFT_RESET_HI (1 << 1) +# define RADEON_SOFT_RESET_SE (1 << 2) +# define RADEON_SOFT_RESET_RE (1 << 3) +# define RADEON_SOFT_RESET_PP (1 << 4) +# define RADEON_SOFT_RESET_E2 (1 << 5) +# define RADEON_SOFT_RESET_RB (1 << 6) +# define RADEON_SOFT_RESET_HDP (1 << 7) +#define RADEON_RBBM_STATUS 0x0e40 +# define RADEON_RBBM_FIFOCNT_MASK 0x007f +# define RADEON_RBBM_ACTIVE (1 << 31) +#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c +# define RADEON_RB2D_DC_FLUSH (3 << 0) +# define RADEON_RB2D_DC_FREE (3 << 2) +# define RADEON_RB2D_DC_FLUSH_ALL 0xf +# define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_RB2D_DSTCACHE_MODE 0x3428 +#define RADEON_REG_BASE 0x0f18 /* PCI */ +#define RADEON_REGPROG_INF 0x0f09 /* PCI */ +#define RADEON_REVISION_ID 0x0f08 /* PCI */ + +#define RADEON_SC_BOTTOM 0x164c +#define RADEON_SC_BOTTOM_RIGHT 0x16f0 +#define RADEON_SC_BOTTOM_RIGHT_C 0x1c8c +#define RADEON_SC_LEFT 0x1640 +#define RADEON_SC_RIGHT 0x1644 +#define RADEON_SC_TOP 0x1648 +#define RADEON_SC_TOP_LEFT 0x16ec +#define RADEON_SC_TOP_LEFT_C 0x1c88 +# define RADEON_SC_SIGN_MASK_LO 0x8000 +# define RADEON_SC_SIGN_MASK_HI 0x80000000 +#define RADEON_SCLK_CNTL 0x000d /* PLL */ +# define RADEON_DYN_STOP_LAT_MASK 0x00007ff8 +# define RADEON_CP_MAX_DYN_STOP_LAT 0x0008 +# define RADEON_SCLK_FORCEON_MASK 0xffff8000 +#define RADEON_SCLK_MORE_CNTL 0x0035 /* PLL */ +# define RADEON_SCLK_MORE_FORCEON 0x0700 +#define RADEON_SDRAM_MODE_REG 0x0158 +#define RADEON_SEQ8_DATA 0x03c5 /* VGA */ +#define RADEON_SEQ8_IDX 0x03c4 /* VGA */ +#define RADEON_SNAPSHOT_F_COUNT 0x0244 +#define RADEON_SNAPSHOT_VH_COUNTS 0x0240 +#define RADEON_SNAPSHOT_VIF_COUNT 0x024c +#define RADEON_SRC_OFFSET 0x15ac +#define RADEON_SRC_PITCH 0x15b0 +#define RADEON_SRC_PITCH_OFFSET 0x1428 +#define RADEON_SRC_SC_BOTTOM 0x165c +#define RADEON_SRC_SC_BOTTOM_RIGHT 0x16f4 +#define RADEON_SRC_SC_RIGHT 0x1654 +#define RADEON_SRC_X 0x1414 +#define RADEON_SRC_X_Y 0x1590 +#define RADEON_SRC_Y 0x1418 +#define RADEON_SRC_Y_X 0x1434 +#define RADEON_STATUS 0x0f06 /* PCI */ +#define RADEON_SUBPIC_CNTL 0x0540 /* ? */ +#define RADEON_SUB_CLASS 0x0f0a /* PCI */ +#define RADEON_SURFACE_CNTL 0x0b00 +# define RADEON_SURF_TRANSLATION_DIS (1 << 8) +# define RADEON_NONSURF_AP0_SWP_16BPP (1 << 20) +# define RADEON_NONSURF_AP0_SWP_32BPP (1 << 21) +#define RADEON_SURFACE0_INFO 0x0b0c +# define RADEON_SURF_TILE_COLOR_MACRO (0 << 16) +# define RADEON_SURF_TILE_COLOR_BOTH (1 << 16) +# define RADEON_SURF_TILE_DEPTH_32BPP (2 << 16) +# define RADEON_SURF_TILE_DEPTH_16BPP (3 << 16) +# define R200_SURF_TILE_NONE (0 << 16) +# define R200_SURF_TILE_COLOR_MACRO (1 << 16) +# define R200_SURF_TILE_COLOR_MICRO (2 << 16) +# define R200_SURF_TILE_COLOR_BOTH (3 << 16) +# define R200_SURF_TILE_DEPTH_32BPP (4 << 16) +# define R200_SURF_TILE_DEPTH_16BPP (5 << 16) +# define RADEON_SURF_AP0_SWP_16BPP (1 << 20) +# define RADEON_SURF_AP0_SWP_32BPP (1 << 21) +# define RADEON_SURF_AP1_SWP_16BPP (1 << 22) +# define RADEON_SURF_AP1_SWP_32BPP (1 << 23) +#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 +#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 +#define RADEON_SURFACE1_INFO 0x0b1c +#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 +#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 +#define RADEON_SURFACE2_INFO 0x0b2c +#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 +#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 +#define RADEON_SURFACE3_INFO 0x0b3c +#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 +#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 +#define RADEON_SURFACE4_INFO 0x0b4c +#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 +#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 +#define RADEON_SURFACE5_INFO 0x0b5c +#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 +#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 +#define RADEON_SURFACE6_INFO 0x0b6c +#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 +#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 +#define RADEON_SURFACE7_INFO 0x0b7c +#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 +#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 +#define RADEON_SW_SEMAPHORE 0x013c + +#define RADEON_TEST_DEBUG_CNTL 0x0120 +#define RADEON_TEST_DEBUG_MUX 0x0124 +#define RADEON_TEST_DEBUG_OUT 0x012c +#define RADEON_TMDS_PLL_CNTL 0x02a8 +#define RADEON_TMDS_TRANSMITTER_CNTL 0x02a4 +# define RADEON_TMDS_TRANSMITTER_PLLEN 1 +# define RADEON_TMDS_TRANSMITTER_PLLRST 2 +#define RADEON_TRAIL_BRES_DEC 0x1614 +#define RADEON_TRAIL_BRES_ERR 0x160c +#define RADEON_TRAIL_BRES_INC 0x1610 +#define RADEON_TRAIL_X 0x1618 +#define RADEON_TRAIL_X_SUB 0x1620 + +#define RADEON_VCLK_ECP_CNTL 0x0008 /* PLL */ +# define RADEON_VCLK_SRC_SEL_MASK 0x03 +# define RADEON_VCLK_SRC_SEL_CPUCLK 0x00 +# define RADEON_VCLK_SRC_SEL_PSCANCLK 0x01 +# define RADEON_VCLK_SRC_SEL_BYTECLK 0x02 +# define RADEON_VCLK_SRC_SEL_PPLLCLK 0x03 +# define RADEON_PIXCLK_ALWAYS_ONb (1<<6) +# define RADEON_PIXCLK_DAC_ALWAYS_ONb (1<<7) + +#define RADEON_VENDOR_ID 0x0f00 /* PCI */ +#define RADEON_VGA_DDA_CONFIG 0x02e8 +#define RADEON_VGA_DDA_ON_OFF 0x02ec +#define RADEON_VID_BUFFER_CONTROL 0x0900 +#define RADEON_VIDEOMUX_CNTL 0x0190 +#define RADEON_VIPH_CONTROL 0x0c40 /* ? */ + +#define RADEON_WAIT_UNTIL 0x1720 +# define RADEON_WAIT_CRTC_PFLIP (1 << 0) +# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) +# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) +# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) + +#define RADEON_X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define RADEON_XCLK_CNTL 0x000d /* PLL */ +#define RADEON_XDLL_CNTL 0x000c /* PLL */ +#define RADEON_XPLL_CNTL 0x000b /* PLL */ + + + + /* Registers for 3D/TCL */ +#define RADEON_PP_BORDER_COLOR_0 0x1d40 +#define RADEON_PP_BORDER_COLOR_1 0x1d44 +#define RADEON_PP_BORDER_COLOR_2 0x1d48 +#define RADEON_PP_CNTL 0x1c38 +# define RADEON_STIPPLE_ENABLE (1 << 0) +# define RADEON_SCISSOR_ENABLE (1 << 1) +# define RADEON_PATTERN_ENABLE (1 << 2) +# define RADEON_SHADOW_ENABLE (1 << 3) +# define RADEON_TEX_ENABLE_MASK (0xf << 4) +# define RADEON_TEX_0_ENABLE (1 << 4) +# define RADEON_TEX_1_ENABLE (1 << 5) +# define RADEON_TEX_2_ENABLE (1 << 6) +# define RADEON_TEX_3_ENABLE (1 << 7) +# define RADEON_TEX_BLEND_ENABLE_MASK (0xf << 12) +# define RADEON_TEX_BLEND_0_ENABLE (1 << 12) +# define RADEON_TEX_BLEND_1_ENABLE (1 << 13) +# define RADEON_TEX_BLEND_2_ENABLE (1 << 14) +# define RADEON_TEX_BLEND_3_ENABLE (1 << 15) +# define RADEON_PLANAR_YUV_ENABLE (1 << 20) +# define RADEON_SPECULAR_ENABLE (1 << 21) +# define RADEON_FOG_ENABLE (1 << 22) +# define RADEON_ALPHA_TEST_ENABLE (1 << 23) +# define RADEON_ANTI_ALIAS_NONE (0 << 24) +# define RADEON_ANTI_ALIAS_LINE (1 << 24) +# define RADEON_ANTI_ALIAS_POLY (2 << 24) +# define RADEON_ANTI_ALIAS_LINE_POLY (3 << 24) +# define RADEON_BUMP_MAP_ENABLE (1 << 26) +# define RADEON_BUMPED_MAP_T0 (0 << 27) +# define RADEON_BUMPED_MAP_T1 (1 << 27) +# define RADEON_BUMPED_MAP_T2 (2 << 27) +# define RADEON_TEX_3D_ENABLE_0 (1 << 29) +# define RADEON_TEX_3D_ENABLE_1 (1 << 30) +# define RADEON_MC_ENABLE (1 << 31) +#define RADEON_PP_FOG_COLOR 0x1c18 +# define RADEON_FOG_COLOR_MASK 0x00ffffff +# define RADEON_FOG_VERTEX (0 << 24) +# define RADEON_FOG_TABLE (1 << 24) +# define RADEON_FOG_USE_DEPTH (0 << 25) +# define RADEON_FOG_USE_DIFFUSE_ALPHA (2 << 25) +# define RADEON_FOG_USE_SPEC_ALPHA (3 << 25) +#define RADEON_PP_LUM_MATRIX 0x1d00 +#define RADEON_PP_MISC 0x1c14 +# define RADEON_REF_ALPHA_MASK 0x000000ff +# define RADEON_ALPHA_TEST_FAIL (0 << 8) +# define RADEON_ALPHA_TEST_LESS (1 << 8) +# define RADEON_ALPHA_TEST_LEQUAL (2 << 8) +# define RADEON_ALPHA_TEST_EQUAL (3 << 8) +# define RADEON_ALPHA_TEST_GEQUAL (4 << 8) +# define RADEON_ALPHA_TEST_GREATER (5 << 8) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 8) +# define RADEON_ALPHA_TEST_PASS (7 << 8) +# define RADEON_ALPHA_TEST_OP_MASK (7 << 8) +# define RADEON_CHROMA_FUNC_FAIL (0 << 16) +# define RADEON_CHROMA_FUNC_PASS (1 << 16) +# define RADEON_CHROMA_FUNC_NEQUAL (2 << 16) +# define RADEON_CHROMA_FUNC_EQUAL (3 << 16) +# define RADEON_CHROMA_KEY_NEAREST (0 << 18) +# define RADEON_CHROMA_KEY_ZERO (1 << 18) +# define RADEON_SHADOW_ID_AUTO_INC (1 << 20) +# define RADEON_SHADOW_FUNC_EQUAL (0 << 21) +# define RADEON_SHADOW_FUNC_NEQUAL (1 << 21) +# define RADEON_SHADOW_PASS_1 (0 << 22) +# define RADEON_SHADOW_PASS_2 (1 << 22) +# define RADEON_RIGHT_HAND_CUBE_D3D (0 << 24) +# define RADEON_RIGHT_HAND_CUBE_OGL (1 << 24) +#define RADEON_PP_ROT_MATRIX_0 0x1d58 +#define RADEON_PP_ROT_MATRIX_1 0x1d5c +#define RADEON_PP_TXFILTER_0 0x1c54 +#define RADEON_PP_TXFILTER_1 0x1c6c +#define RADEON_PP_TXFILTER_2 0x1c84 +# define RADEON_MAG_FILTER_NEAREST (0 << 0) +# define RADEON_MAG_FILTER_LINEAR (1 << 0) +# define RADEON_MAG_FILTER_MASK (1 << 0) +# define RADEON_MIN_FILTER_NEAREST (0 << 1) +# define RADEON_MIN_FILTER_LINEAR (1 << 1) +# define RADEON_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) +# define RADEON_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) +# define RADEON_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) +# define RADEON_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) +# define RADEON_MIN_FILTER_ANISO_NEAREST (8 << 1) +# define RADEON_MIN_FILTER_ANISO_LINEAR (9 << 1) +# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) +# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) +# define RADEON_MIN_FILTER_MASK (15 << 1) +# define RADEON_MAX_ANISO_1_TO_1 (0 << 5) +# define RADEON_MAX_ANISO_2_TO_1 (1 << 5) +# define RADEON_MAX_ANISO_4_TO_1 (2 << 5) +# define RADEON_MAX_ANISO_8_TO_1 (3 << 5) +# define RADEON_MAX_ANISO_16_TO_1 (4 << 5) +# define RADEON_MAX_ANISO_MASK (7 << 5) +# define RADEON_LOD_BIAS_MASK (0xff << 8) +# define RADEON_LOD_BIAS_SHIFT 8 +# define RADEON_MAX_MIP_LEVEL_MASK (0x0f << 16) +# define RADEON_MAX_MIP_LEVEL_SHIFT 16 +# define RADEON_YUV_TO_RGB (1 << 20) +# define RADEON_YUV_TEMPERATURE_COOL (0 << 21) +# define RADEON_YUV_TEMPERATURE_HOT (1 << 21) +# define RADEON_YUV_TEMPERATURE_MASK (1 << 21) +# define RADEON_WRAPEN_S (1 << 22) +# define RADEON_CLAMP_S_WRAP (0 << 23) +# define RADEON_CLAMP_S_MIRROR (1 << 23) +# define RADEON_CLAMP_S_CLAMP_LAST (2 << 23) +# define RADEON_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) +# define RADEON_CLAMP_S_CLAMP_BORDER (4 << 23) +# define RADEON_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) +# define RADEON_CLAMP_S_CLAMP_GL (6 << 23) +# define RADEON_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) +# define RADEON_CLAMP_S_MASK (7 << 23) +# define RADEON_WRAPEN_T (1 << 26) +# define RADEON_CLAMP_T_WRAP (0 << 27) +# define RADEON_CLAMP_T_MIRROR (1 << 27) +# define RADEON_CLAMP_T_CLAMP_LAST (2 << 27) +# define RADEON_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) +# define RADEON_CLAMP_T_CLAMP_BORDER (4 << 27) +# define RADEON_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) +# define RADEON_CLAMP_T_CLAMP_GL (6 << 27) +# define RADEON_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) +# define RADEON_CLAMP_T_MASK (7 << 27) +# define RADEON_BORDER_MODE_OGL (0 << 31) +# define RADEON_BORDER_MODE_D3D (1 << 31) +#define RADEON_PP_TXFORMAT_0 0x1c58 +#define RADEON_PP_TXFORMAT_1 0x1c70 +#define RADEON_PP_TXFORMAT_2 0x1c88 +# define RADEON_TXFORMAT_I8 (0 << 0) +# define RADEON_TXFORMAT_AI88 (1 << 0) +# define RADEON_TXFORMAT_RGB332 (2 << 0) +# define RADEON_TXFORMAT_ARGB1555 (3 << 0) +# define RADEON_TXFORMAT_RGB565 (4 << 0) +# define RADEON_TXFORMAT_ARGB4444 (5 << 0) +# define RADEON_TXFORMAT_ARGB8888 (6 << 0) +# define RADEON_TXFORMAT_RGBA8888 (7 << 0) +# define RADEON_TXFORMAT_Y8 (8 << 0) +# define RADEON_TXFORMAT_VYUY422 (10 << 0) +# define RADEON_TXFORMAT_YVYU422 (11 << 0) +# define RADEON_TXFORMAT_DXT1 (12 << 0) +# define RADEON_TXFORMAT_DXT23 (14 << 0) +# define RADEON_TXFORMAT_DXT45 (15 << 0) +# define RADEON_TXFORMAT_SHADOW16 (16 << 0) +# define RADEON_TXFORMAT_SHADOW32 (17 << 0) +# define RADEON_TXFORMAT_DUDV88 (18 << 0) +# define RADEON_TXFORMAT_LDUDV655 (19 << 0) +# define RADEON_TXFORMAT_LDUDUV8888 (20 << 0) +# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0) +# define RADEON_TXFORMAT_FORMAT_SHIFT 0 +# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5) +# define RADEON_TXFORMAT_ALPHA_IN_MAP (1 << 6) +# define RADEON_TXFORMAT_NON_POWER2 (1 << 7) +# define RADEON_TXFORMAT_WIDTH_MASK (15 << 8) +# define RADEON_TXFORMAT_WIDTH_SHIFT 8 +# define RADEON_TXFORMAT_HEIGHT_MASK (15 << 12) +# define RADEON_TXFORMAT_HEIGHT_SHIFT 12 +# define RADEON_TXFORMAT_F5_WIDTH_MASK (15 << 16) +# define RADEON_TXFORMAT_F5_WIDTH_SHIFT 16 +# define RADEON_TXFORMAT_F5_HEIGHT_MASK (15 << 20) +# define RADEON_TXFORMAT_F5_HEIGHT_SHIFT 20 +# define RADEON_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) +# define RADEON_TXFORMAT_ST_ROUTE_MASK (3 << 24) +# define RADEON_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) +# define RADEON_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) +# define RADEON_TXFORMAT_ENDIAN_NO_SWAP (0 << 26) +# define RADEON_TXFORMAT_ENDIAN_16BPP_SWAP (1 << 26) +# define RADEON_TXFORMAT_ENDIAN_32BPP_SWAP (2 << 26) +# define RADEON_TXFORMAT_ENDIAN_HALFDW_SWAP (3 << 26) +# define RADEON_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) +# define RADEON_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) +# define RADEON_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) +# define RADEON_TXFORMAT_PERSPECTIVE_ENABLE (1 << 31) +#define RADEON_PP_CUBIC_FACES_0 0x1d24 +#define RADEON_PP_CUBIC_FACES_1 0x1d28 +#define RADEON_PP_CUBIC_FACES_2 0x1d2c +# define RADEON_FACE_WIDTH_1_SHIFT 0 +# define RADEON_FACE_HEIGHT_1_SHIFT 4 +# define RADEON_FACE_WIDTH_1_MASK (0xf << 0) +# define RADEON_FACE_HEIGHT_1_MASK (0xf << 4) +# define RADEON_FACE_WIDTH_2_SHIFT 8 +# define RADEON_FACE_HEIGHT_2_SHIFT 12 +# define RADEON_FACE_WIDTH_2_MASK (0xf << 8) +# define RADEON_FACE_HEIGHT_2_MASK (0xf << 12) +# define RADEON_FACE_WIDTH_3_SHIFT 16 +# define RADEON_FACE_HEIGHT_3_SHIFT 20 +# define RADEON_FACE_WIDTH_3_MASK (0xf << 16) +# define RADEON_FACE_HEIGHT_3_MASK (0xf << 20) +# define RADEON_FACE_WIDTH_4_SHIFT 24 +# define RADEON_FACE_HEIGHT_4_SHIFT 28 +# define RADEON_FACE_WIDTH_4_MASK (0xf << 24) +# define RADEON_FACE_HEIGHT_4_MASK (0xf << 28) + +#define RADEON_PP_TXOFFSET_0 0x1c5c +#define RADEON_PP_TXOFFSET_1 0x1c74 +#define RADEON_PP_TXOFFSET_2 0x1c8c +# define RADEON_TXO_ENDIAN_NO_SWAP (0 << 0) +# define RADEON_TXO_ENDIAN_BYTE_SWAP (1 << 0) +# define RADEON_TXO_ENDIAN_WORD_SWAP (2 << 0) +# define RADEON_TXO_ENDIAN_HALFDW_SWAP (3 << 0) +# define RADEON_TXO_MACRO_LINEAR (0 << 2) +# define RADEON_TXO_MACRO_TILE (1 << 2) +# define RADEON_TXO_MICRO_LINEAR (0 << 3) +# define RADEON_TXO_MICRO_TILE_X2 (1 << 3) +# define RADEON_TXO_MICRO_TILE_OPT (2 << 3) +# define RADEON_TXO_OFFSET_MASK 0xffffffe0 +# define RADEON_TXO_OFFSET_SHIFT 5 + +#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */ +#define RADEON_PP_CUBIC_OFFSET_T0_1 0x1dd4 +#define RADEON_PP_CUBIC_OFFSET_T0_2 0x1dd8 +#define RADEON_PP_CUBIC_OFFSET_T0_3 0x1ddc +#define RADEON_PP_CUBIC_OFFSET_T0_4 0x1de0 +#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 +#define RADEON_PP_CUBIC_OFFSET_T1_1 0x1e04 +#define RADEON_PP_CUBIC_OFFSET_T1_2 0x1e08 +#define RADEON_PP_CUBIC_OFFSET_T1_3 0x1e0c +#define RADEON_PP_CUBIC_OFFSET_T1_4 0x1e10 +#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 +#define RADEON_PP_CUBIC_OFFSET_T2_1 0x1e18 +#define RADEON_PP_CUBIC_OFFSET_T2_2 0x1e1c +#define RADEON_PP_CUBIC_OFFSET_T2_3 0x1e20 +#define RADEON_PP_CUBIC_OFFSET_T2_4 0x1e24 + +#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ +#define RADEON_PP_TEX_SIZE_1 0x1d0c +#define RADEON_PP_TEX_SIZE_2 0x1d14 +# define RADEON_TEX_USIZE_MASK (0x7ff << 0) +# define RADEON_TEX_USIZE_SHIFT 0 +# define RADEON_TEX_VSIZE_MASK (0x7ff << 16) +# define RADEON_TEX_VSIZE_SHIFT 16 +# define RADEON_SIGNED_RGB_MASK (1 << 30) +# define RADEON_SIGNED_RGB_SHIFT 30 +# define RADEON_SIGNED_ALPHA_MASK (1 << 31) +# define RADEON_SIGNED_ALPHA_SHIFT 31 +#define RADEON_PP_TEX_PITCH_0 0x1d08 /* NPOT */ +#define RADEON_PP_TEX_PITCH_1 0x1d10 /* NPOT */ +#define RADEON_PP_TEX_PITCH_2 0x1d18 /* NPOT */ +/* note: bits 13-5: 32 byte aligned stride of texture map */ + +#define RADEON_PP_TXCBLEND_0 0x1c60 +#define RADEON_PP_TXCBLEND_1 0x1c78 +#define RADEON_PP_TXCBLEND_2 0x1c90 +# define RADEON_COLOR_ARG_A_SHIFT 0 +# define RADEON_COLOR_ARG_A_MASK (0x1f << 0) +# define RADEON_COLOR_ARG_A_ZERO (0 << 0) +# define RADEON_COLOR_ARG_A_CURRENT_COLOR (2 << 0) +# define RADEON_COLOR_ARG_A_CURRENT_ALPHA (3 << 0) +# define RADEON_COLOR_ARG_A_DIFFUSE_COLOR (4 << 0) +# define RADEON_COLOR_ARG_A_DIFFUSE_ALPHA (5 << 0) +# define RADEON_COLOR_ARG_A_SPECULAR_COLOR (6 << 0) +# define RADEON_COLOR_ARG_A_SPECULAR_ALPHA (7 << 0) +# define RADEON_COLOR_ARG_A_TFACTOR_COLOR (8 << 0) +# define RADEON_COLOR_ARG_A_TFACTOR_ALPHA (9 << 0) +# define RADEON_COLOR_ARG_A_T0_COLOR (10 << 0) +# define RADEON_COLOR_ARG_A_T0_ALPHA (11 << 0) +# define RADEON_COLOR_ARG_A_T1_COLOR (12 << 0) +# define RADEON_COLOR_ARG_A_T1_ALPHA (13 << 0) +# define RADEON_COLOR_ARG_A_T2_COLOR (14 << 0) +# define RADEON_COLOR_ARG_A_T2_ALPHA (15 << 0) +# define RADEON_COLOR_ARG_A_T3_COLOR (16 << 0) +# define RADEON_COLOR_ARG_A_T3_ALPHA (17 << 0) +# define RADEON_COLOR_ARG_B_SHIFT 5 +# define RADEON_COLOR_ARG_B_MASK (0x1f << 5) +# define RADEON_COLOR_ARG_B_ZERO (0 << 5) +# define RADEON_COLOR_ARG_B_CURRENT_COLOR (2 << 5) +# define RADEON_COLOR_ARG_B_CURRENT_ALPHA (3 << 5) +# define RADEON_COLOR_ARG_B_DIFFUSE_COLOR (4 << 5) +# define RADEON_COLOR_ARG_B_DIFFUSE_ALPHA (5 << 5) +# define RADEON_COLOR_ARG_B_SPECULAR_COLOR (6 << 5) +# define RADEON_COLOR_ARG_B_SPECULAR_ALPHA (7 << 5) +# define RADEON_COLOR_ARG_B_TFACTOR_COLOR (8 << 5) +# define RADEON_COLOR_ARG_B_TFACTOR_ALPHA (9 << 5) +# define RADEON_COLOR_ARG_B_T0_COLOR (10 << 5) +# define RADEON_COLOR_ARG_B_T0_ALPHA (11 << 5) +# define RADEON_COLOR_ARG_B_T1_COLOR (12 << 5) +# define RADEON_COLOR_ARG_B_T1_ALPHA (13 << 5) +# define RADEON_COLOR_ARG_B_T2_COLOR (14 << 5) +# define RADEON_COLOR_ARG_B_T2_ALPHA (15 << 5) +# define RADEON_COLOR_ARG_B_T3_COLOR (16 << 5) +# define RADEON_COLOR_ARG_B_T3_ALPHA (17 << 5) +# define RADEON_COLOR_ARG_C_SHIFT 10 +# define RADEON_COLOR_ARG_C_MASK (0x1f << 10) +# define RADEON_COLOR_ARG_C_ZERO (0 << 10) +# define RADEON_COLOR_ARG_C_CURRENT_COLOR (2 << 10) +# define RADEON_COLOR_ARG_C_CURRENT_ALPHA (3 << 10) +# define RADEON_COLOR_ARG_C_DIFFUSE_COLOR (4 << 10) +# define RADEON_COLOR_ARG_C_DIFFUSE_ALPHA (5 << 10) +# define RADEON_COLOR_ARG_C_SPECULAR_COLOR (6 << 10) +# define RADEON_COLOR_ARG_C_SPECULAR_ALPHA (7 << 10) +# define RADEON_COLOR_ARG_C_TFACTOR_COLOR (8 << 10) +# define RADEON_COLOR_ARG_C_TFACTOR_ALPHA (9 << 10) +# define RADEON_COLOR_ARG_C_T0_COLOR (10 << 10) +# define RADEON_COLOR_ARG_C_T0_ALPHA (11 << 10) +# define RADEON_COLOR_ARG_C_T1_COLOR (12 << 10) +# define RADEON_COLOR_ARG_C_T1_ALPHA (13 << 10) +# define RADEON_COLOR_ARG_C_T2_COLOR (14 << 10) +# define RADEON_COLOR_ARG_C_T2_ALPHA (15 << 10) +# define RADEON_COLOR_ARG_C_T3_COLOR (16 << 10) +# define RADEON_COLOR_ARG_C_T3_ALPHA (17 << 10) +# define RADEON_COMP_ARG_A (1 << 15) +# define RADEON_COMP_ARG_A_SHIFT 15 +# define RADEON_COMP_ARG_B (1 << 16) +# define RADEON_COMP_ARG_B_SHIFT 16 +# define RADEON_COMP_ARG_C (1 << 17) +# define RADEON_COMP_ARG_C_SHIFT 17 +# define RADEON_BLEND_CTL_MASK (7 << 18) +# define RADEON_BLEND_CTL_ADD (0 << 18) +# define RADEON_BLEND_CTL_SUBTRACT (1 << 18) +# define RADEON_BLEND_CTL_ADDSIGNED (2 << 18) +# define RADEON_BLEND_CTL_BLEND (3 << 18) +# define RADEON_BLEND_CTL_DOT3 (4 << 18) +# define RADEON_SCALE_SHIFT 21 +# define RADEON_SCALE_MASK (3 << 21) +# define RADEON_SCALE_1X (0 << 21) +# define RADEON_SCALE_2X (1 << 21) +# define RADEON_SCALE_4X (2 << 21) +# define RADEON_CLAMP_TX (1 << 23) +# define RADEON_T0_EQ_TCUR (1 << 24) +# define RADEON_T1_EQ_TCUR (1 << 25) +# define RADEON_T2_EQ_TCUR (1 << 26) +# define RADEON_T3_EQ_TCUR (1 << 27) +# define RADEON_COLOR_ARG_MASK 0x1f +# define RADEON_COMP_ARG_SHIFT 15 +#define RADEON_PP_TXABLEND_0 0x1c64 +#define RADEON_PP_TXABLEND_1 0x1c7c +#define RADEON_PP_TXABLEND_2 0x1c94 +# define RADEON_ALPHA_ARG_A_SHIFT 0 +# define RADEON_ALPHA_ARG_A_MASK (0xf << 0) +# define RADEON_ALPHA_ARG_A_ZERO (0 << 0) +# define RADEON_ALPHA_ARG_A_CURRENT_ALPHA (1 << 0) +# define RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA (2 << 0) +# define RADEON_ALPHA_ARG_A_SPECULAR_ALPHA (3 << 0) +# define RADEON_ALPHA_ARG_A_TFACTOR_ALPHA (4 << 0) +# define RADEON_ALPHA_ARG_A_T0_ALPHA (5 << 0) +# define RADEON_ALPHA_ARG_A_T1_ALPHA (6 << 0) +# define RADEON_ALPHA_ARG_A_T2_ALPHA (7 << 0) +# define RADEON_ALPHA_ARG_A_T3_ALPHA (8 << 0) +# define RADEON_ALPHA_ARG_B_SHIFT 4 +# define RADEON_ALPHA_ARG_B_MASK (0xf << 4) +# define RADEON_ALPHA_ARG_B_ZERO (0 << 4) +# define RADEON_ALPHA_ARG_B_CURRENT_ALPHA (1 << 4) +# define RADEON_ALPHA_ARG_B_DIFFUSE_ALPHA (2 << 4) +# define RADEON_ALPHA_ARG_B_SPECULAR_ALPHA (3 << 4) +# define RADEON_ALPHA_ARG_B_TFACTOR_ALPHA (4 << 4) +# define RADEON_ALPHA_ARG_B_T0_ALPHA (5 << 4) +# define RADEON_ALPHA_ARG_B_T1_ALPHA (6 << 4) +# define RADEON_ALPHA_ARG_B_T2_ALPHA (7 << 4) +# define RADEON_ALPHA_ARG_B_T3_ALPHA (8 << 4) +# define RADEON_ALPHA_ARG_C_SHIFT 8 +# define RADEON_ALPHA_ARG_C_MASK (0xf << 8) +# define RADEON_ALPHA_ARG_C_ZERO (0 << 8) +# define RADEON_ALPHA_ARG_C_CURRENT_ALPHA (1 << 8) +# define RADEON_ALPHA_ARG_C_DIFFUSE_ALPHA (2 << 8) +# define RADEON_ALPHA_ARG_C_SPECULAR_ALPHA (3 << 8) +# define RADEON_ALPHA_ARG_C_TFACTOR_ALPHA (4 << 8) +# define RADEON_ALPHA_ARG_C_T0_ALPHA (5 << 8) +# define RADEON_ALPHA_ARG_C_T1_ALPHA (6 << 8) +# define RADEON_ALPHA_ARG_C_T2_ALPHA (7 << 8) +# define RADEON_ALPHA_ARG_C_T3_ALPHA (8 << 8) +# define RADEON_DOT_ALPHA_DONT_REPLICATE (1 << 12) +# define RADEON_ALPHA_ARG_MASK 0xf + +#define RADEON_PP_TFACTOR_0 0x1c68 +#define RADEON_PP_TFACTOR_1 0x1c80 +#define RADEON_PP_TFACTOR_2 0x1c98 + +#define RADEON_RB3D_BLENDCNTL 0x1c20 +# define RADEON_COMB_FCN_MASK (3 << 12) +# define RADEON_COMB_FCN_ADD_CLAMP (0 << 12) +# define RADEON_COMB_FCN_ADD_NOCLAMP (1 << 12) +# define RADEON_COMB_FCN_SUB_CLAMP (2 << 12) +# define RADEON_COMB_FCN_SUB_NOCLAMP (3 << 12) +# define RADEON_SRC_BLEND_GL_ZERO (32 << 16) +# define RADEON_SRC_BLEND_GL_ONE (33 << 16) +# define RADEON_SRC_BLEND_GL_SRC_COLOR (34 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) +# define RADEON_SRC_BLEND_GL_DST_COLOR (36 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) +# define RADEON_SRC_BLEND_GL_SRC_ALPHA (38 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) +# define RADEON_SRC_BLEND_GL_DST_ALPHA (40 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) +# define RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) +# define RADEON_SRC_BLEND_MASK (63 << 16) +# define RADEON_DST_BLEND_GL_ZERO (32 << 24) +# define RADEON_DST_BLEND_GL_ONE (33 << 24) +# define RADEON_DST_BLEND_GL_SRC_COLOR (34 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) +# define RADEON_DST_BLEND_GL_DST_COLOR (36 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) +# define RADEON_DST_BLEND_GL_SRC_ALPHA (38 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) +# define RADEON_DST_BLEND_GL_DST_ALPHA (40 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) +# define RADEON_DST_BLEND_MASK (63 << 24) +#define RADEON_RB3D_CNTL 0x1c3c +# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) +# define RADEON_PLANE_MASK_ENABLE (1 << 1) +# define RADEON_DITHER_ENABLE (1 << 2) +# define RADEON_ROUND_ENABLE (1 << 3) +# define RADEON_SCALE_DITHER_ENABLE (1 << 4) +# define RADEON_DITHER_INIT (1 << 5) +# define RADEON_ROP_ENABLE (1 << 6) +# define RADEON_STENCIL_ENABLE (1 << 7) +# define RADEON_Z_ENABLE (1 << 8) +# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) +# define RADEON_COLOR_FORMAT_ARGB1555 (3 << 10) +# define RADEON_COLOR_FORMAT_RGB565 (4 << 10) +# define RADEON_COLOR_FORMAT_ARGB8888 (6 << 10) +# define RADEON_COLOR_FORMAT_RGB332 (7 << 10) +# define RADEON_COLOR_FORMAT_Y8 (8 << 10) +# define RADEON_COLOR_FORMAT_RGB8 (9 << 10) +# define RADEON_COLOR_FORMAT_YUV422_VYUY (11 << 10) +# define RADEON_COLOR_FORMAT_YUV422_YVYU (12 << 10) +# define RADEON_COLOR_FORMAT_aYUV444 (14 << 10) +# define RADEON_COLOR_FORMAT_ARGB4444 (15 << 10) +# define RADEON_CLRCMP_FLIP_ENABLE (1 << 14) +# define RADEON_ZBLOCK16 (1 << 15) +#define RADEON_RB3D_COLOROFFSET 0x1c40 +# define RADEON_COLOROFFSET_MASK 0xfffffff0 +#define RADEON_RB3D_COLORPITCH 0x1c48 +# define RADEON_COLORPITCH_MASK 0x000001ff8 +# define RADEON_COLOR_TILE_ENABLE (1 << 16) +# define RADEON_COLOR_MICROTILE_ENABLE (1 << 17) +# define RADEON_COLOR_ENDIAN_NO_SWAP (0 << 18) +# define RADEON_COLOR_ENDIAN_WORD_SWAP (1 << 18) +# define RADEON_COLOR_ENDIAN_DWORD_SWAP (2 << 18) +#define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_DEPTHPITCH 0x1c28 +# define RADEON_DEPTHPITCH_MASK 0x00001ff8 +# define RADEON_DEPTH_HYPERZ (3 << 16) +# define RADEON_DEPTH_ENDIAN_NO_SWAP (0 << 18) +# define RADEON_DEPTH_ENDIAN_WORD_SWAP (1 << 18) +# define RADEON_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) +#define RADEON_RB3D_PLANEMASK 0x1d84 +#define RADEON_RB3D_ROPCNTL 0x1d80 +# define RADEON_ROP_MASK (15 << 8) +# define RADEON_ROP_CLEAR (0 << 8) +# define RADEON_ROP_NOR (1 << 8) +# define RADEON_ROP_AND_INVERTED (2 << 8) +# define RADEON_ROP_COPY_INVERTED (3 << 8) +# define RADEON_ROP_AND_REVERSE (4 << 8) +# define RADEON_ROP_INVERT (5 << 8) +# define RADEON_ROP_XOR (6 << 8) +# define RADEON_ROP_NAND (7 << 8) +# define RADEON_ROP_AND (8 << 8) +# define RADEON_ROP_EQUIV (9 << 8) +# define RADEON_ROP_NOOP (10 << 8) +# define RADEON_ROP_OR_INVERTED (11 << 8) +# define RADEON_ROP_COPY (12 << 8) +# define RADEON_ROP_OR_REVERSE (13 << 8) +# define RADEON_ROP_OR (14 << 8) +# define RADEON_ROP_SET (15 << 8) +#define RADEON_RB3D_STENCILREFMASK 0x1d7c +# define RADEON_STENCIL_REF_SHIFT 0 +# define RADEON_STENCIL_REF_MASK (0xff << 0) +# define RADEON_STENCIL_MASK_SHIFT 16 +# define RADEON_STENCIL_VALUE_MASK (0xff << 16) +# define RADEON_STENCIL_WRITEMASK_SHIFT 24 +# define RADEON_STENCIL_WRITE_MASK (0xff << 24) +#define RADEON_RB3D_ZPASS_DATA 0x3290 +#define RADEON_RB3D_ZPASS_ADDR 0x3294 +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_DEPTH_FORMAT_MASK (0xf << 0) +# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) +# define RADEON_DEPTH_FORMAT_16BIT_FLOAT_W (7 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) +# define RADEON_Z_TEST_NEVER (0 << 4) +# define RADEON_Z_TEST_LESS (1 << 4) +# define RADEON_Z_TEST_LEQUAL (2 << 4) +# define RADEON_Z_TEST_EQUAL (3 << 4) +# define RADEON_Z_TEST_GEQUAL (4 << 4) +# define RADEON_Z_TEST_GREATER (5 << 4) +# define RADEON_Z_TEST_NEQUAL (6 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) +# define RADEON_STENCIL_TEST_NEVER (0 << 12) +# define RADEON_STENCIL_TEST_LESS (1 << 12) +# define RADEON_STENCIL_TEST_LEQUAL (2 << 12) +# define RADEON_STENCIL_TEST_EQUAL (3 << 12) +# define RADEON_STENCIL_TEST_GEQUAL (4 << 12) +# define RADEON_STENCIL_TEST_GREATER (5 << 12) +# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_TEST_MASK (0x7 << 12) +# define RADEON_STENCIL_FAIL_KEEP (0 << 16) +# define RADEON_STENCIL_FAIL_ZERO (1 << 16) +# define RADEON_STENCIL_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_FAIL_INC (3 << 16) +# define RADEON_STENCIL_FAIL_DEC (4 << 16) +# define RADEON_STENCIL_FAIL_INVERT (5 << 16) +# define RADEON_STENCIL_FAIL_INC_WRAP (6 << 16) +# define RADEON_STENCIL_FAIL_DEC_WRAP (7 << 16) +# define RADEON_STENCIL_FAIL_MASK (0x7 << 16) +# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) +# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZPASS_INC (3 << 20) +# define RADEON_STENCIL_ZPASS_DEC (4 << 20) +# define RADEON_STENCIL_ZPASS_INVERT (5 << 20) +# define RADEON_STENCIL_ZPASS_INC_WRAP (6 << 20) +# define RADEON_STENCIL_ZPASS_DEC_WRAP (7 << 20) +# define RADEON_STENCIL_ZPASS_MASK (0x7 << 20) +# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) +# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) +# define RADEON_STENCIL_ZFAIL_INC (3 << 24) +# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) +# define RADEON_STENCIL_ZFAIL_INVERT (5 << 24) +# define RADEON_STENCIL_ZFAIL_INC_WRAP (6 << 24) +# define RADEON_STENCIL_ZFAIL_DEC_WRAP (7 << 24) +# define RADEON_STENCIL_ZFAIL_MASK (0x7 << 24) +# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) +# define RADEON_FORCE_Z_DIRTY (1 << 29) +# define RADEON_Z_WRITE_ENABLE (1 << 30) +# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) + +#define RADEON_RE_STIPPLE_ADDR 0x1cc8 +#define RADEON_RE_STIPPLE_DATA 0x1ccc +#define RADEON_RE_LINE_PATTERN 0x1cd0 +# define RADEON_LINE_PATTERN_MASK 0x0000ffff +# define RADEON_LINE_REPEAT_COUNT_SHIFT 16 +# define RADEON_LINE_PATTERN_START_SHIFT 24 +# define RADEON_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) +# define RADEON_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) +# define RADEON_LINE_PATTERN_AUTO_RESET (1 << 29) +#define RADEON_RE_LINE_STATE 0x1cd4 +# define RADEON_LINE_CURRENT_PTR_SHIFT 0 +# define RADEON_LINE_CURRENT_COUNT_SHIFT 8 +#define RADEON_RE_MISC 0x26c4 +# define RADEON_STIPPLE_COORD_MASK 0x1f +# define RADEON_STIPPLE_X_OFFSET_SHIFT 0 +# define RADEON_STIPPLE_X_OFFSET_MASK (0x1f << 0) +# define RADEON_STIPPLE_Y_OFFSET_SHIFT 8 +# define RADEON_STIPPLE_Y_OFFSET_MASK (0x1f << 8) +# define RADEON_STIPPLE_LITTLE_BIT_ORDER (0 << 16) +# define RADEON_STIPPLE_BIG_BIT_ORDER (1 << 16) +#define RADEON_RE_SOLID_COLOR 0x1c1c +#define RADEON_RE_TOP_LEFT 0x26c0 +# define RADEON_RE_LEFT_SHIFT 0 +# define RADEON_RE_TOP_SHIFT 16 +#define RADEON_RE_WIDTH_HEIGHT 0x1c44 +# define RADEON_RE_WIDTH_SHIFT 0 +# define RADEON_RE_HEIGHT_SHIFT 16 + +#define RADEON_SE_CNTL 0x1c4c +# define RADEON_FFACE_CULL_CW (0 << 0) +# define RADEON_FFACE_CULL_CCW (1 << 0) +# define RADEON_FFACE_CULL_DIR_MASK (1 << 0) +# define RADEON_BFACE_CULL (0 << 1) +# define RADEON_BFACE_SOLID (3 << 1) +# define RADEON_FFACE_CULL (0 << 3) +# define RADEON_FFACE_SOLID (3 << 3) +# define RADEON_FFACE_CULL_MASK (3 << 3) +# define RADEON_BADVTX_CULL_DISABLE (1 << 5) +# define RADEON_FLAT_SHADE_VTX_0 (0 << 6) +# define RADEON_FLAT_SHADE_VTX_1 (1 << 6) +# define RADEON_FLAT_SHADE_VTX_2 (2 << 6) +# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) +# define RADEON_DIFFUSE_SHADE_SOLID (0 << 8) +# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) +# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) +# define RADEON_DIFFUSE_SHADE_MASK (3 << 8) +# define RADEON_ALPHA_SHADE_SOLID (0 << 10) +# define RADEON_ALPHA_SHADE_FLAT (1 << 10) +# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) +# define RADEON_ALPHA_SHADE_MASK (3 << 10) +# define RADEON_SPECULAR_SHADE_SOLID (0 << 12) +# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) +# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) +# define RADEON_SPECULAR_SHADE_MASK (3 << 12) +# define RADEON_FOG_SHADE_SOLID (0 << 14) +# define RADEON_FOG_SHADE_FLAT (1 << 14) +# define RADEON_FOG_SHADE_GOURAUD (2 << 14) +# define RADEON_FOG_SHADE_MASK (3 << 14) +# define RADEON_ZBIAS_ENABLE_POINT (1 << 16) +# define RADEON_ZBIAS_ENABLE_LINE (1 << 17) +# define RADEON_ZBIAS_ENABLE_TRI (1 << 18) +# define RADEON_WIDELINE_ENABLE (1 << 20) +# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) +# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) +# define RADEON_VTX_PIX_CENTER_D3D (0 << 27) +# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) +# define RADEON_ROUND_MODE_TRUNC (0 << 28) +# define RADEON_ROUND_MODE_ROUND (1 << 28) +# define RADEON_ROUND_MODE_ROUND_EVEN (2 << 28) +# define RADEON_ROUND_MODE_ROUND_ODD (3 << 28) +# define RADEON_ROUND_PREC_16TH_PIX (0 << 30) +# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) +# define RADEON_ROUND_PREC_4TH_PIX (2 << 30) +# define RADEON_ROUND_PREC_HALF_PIX (3 << 30) +#define RADEON_SE_CNTL_STATUS 0x2140 +# define RADEON_VC_NO_SWAP (0 << 0) +# define RADEON_VC_16BIT_SWAP (1 << 0) +# define RADEON_VC_32BIT_SWAP (2 << 0) +# define RADEON_VC_HALF_DWORD_SWAP (3 << 0) +# define RADEON_TCL_BYPASS (1 << 8) +#define RADEON_SE_COORD_FMT 0x1c50 +# define RADEON_VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0) +# define RADEON_VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1) +# define RADEON_VTX_ST0_NONPARAMETRIC (1 << 8) +# define RADEON_VTX_ST1_NONPARAMETRIC (1 << 9) +# define RADEON_VTX_ST2_NONPARAMETRIC (1 << 10) +# define RADEON_VTX_ST3_NONPARAMETRIC (1 << 11) +# define RADEON_VTX_W0_NORMALIZE (1 << 12) +# define RADEON_VTX_W0_IS_NOT_1_OVER_W0 (1 << 16) +# define RADEON_VTX_ST0_PRE_MULT_1_OVER_W0 (1 << 17) +# define RADEON_VTX_ST1_PRE_MULT_1_OVER_W0 (1 << 19) +# define RADEON_VTX_ST2_PRE_MULT_1_OVER_W0 (1 << 21) +# define RADEON_VTX_ST3_PRE_MULT_1_OVER_W0 (1 << 23) +# define RADEON_TEX1_W_ROUTING_USE_W0 (0 << 26) +# define RADEON_TEX1_W_ROUTING_USE_Q1 (1 << 26) +#define RADEON_SE_LINE_WIDTH 0x1db8 +#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c +# define RADEON_LIGHTING_ENABLE (1 << 0) +# define RADEON_LIGHT_IN_MODELSPACE (1 << 1) +# define RADEON_LOCAL_VIEWER (1 << 2) +# define RADEON_NORMALIZE_NORMALS (1 << 3) +# define RADEON_RESCALE_NORMALS (1 << 4) +# define RADEON_SPECULAR_LIGHTS (1 << 5) +# define RADEON_DIFFUSE_SPECULAR_COMBINE (1 << 6) +# define RADEON_LIGHT_ALPHA (1 << 7) +# define RADEON_LOCAL_LIGHT_VEC_GL (1 << 8) +# define RADEON_LIGHT_NO_NORMAL_AMBIENT_ONLY (1 << 9) +# define RADEON_LM_SOURCE_STATE_PREMULT 0 +# define RADEON_LM_SOURCE_STATE_MULT 1 +# define RADEON_LM_SOURCE_VERTEX_DIFFUSE 2 +# define RADEON_LM_SOURCE_VERTEX_SPECULAR 3 +# define RADEON_EMISSIVE_SOURCE_SHIFT 16 +# define RADEON_AMBIENT_SOURCE_SHIFT 18 +# define RADEON_DIFFUSE_SOURCE_SHIFT 20 +# define RADEON_SPECULAR_SOURCE_SHIFT 22 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_RED 0x2220 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA 0x222c +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_RED 0x2230 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN 0x2234 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE 0x2238 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA 0x223c +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN 0x2214 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE 0x2218 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA 0x221c +#define RADEON_SE_TCL_MATERIAL_SPECULAR_RED 0x2240 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c +#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c +# define RADEON_MODELVIEW_0_SHIFT 0 +# define RADEON_MODELVIEW_1_SHIFT 4 +# define RADEON_MODELVIEW_2_SHIFT 8 +# define RADEON_MODELVIEW_3_SHIFT 12 +# define RADEON_IT_MODELVIEW_0_SHIFT 16 +# define RADEON_IT_MODELVIEW_1_SHIFT 20 +# define RADEON_IT_MODELVIEW_2_SHIFT 24 +# define RADEON_IT_MODELVIEW_3_SHIFT 28 +#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260 +# define RADEON_MODELPROJECT_0_SHIFT 0 +# define RADEON_MODELPROJECT_1_SHIFT 4 +# define RADEON_MODELPROJECT_2_SHIFT 8 +# define RADEON_MODELPROJECT_3_SHIFT 12 +# define RADEON_TEXMAT_0_SHIFT 16 +# define RADEON_TEXMAT_1_SHIFT 20 +# define RADEON_TEXMAT_2_SHIFT 24 +# define RADEON_TEXMAT_3_SHIFT 28 + + +#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 +# define RADEON_TCL_VTX_W0 (1 << 0) +# define RADEON_TCL_VTX_FP_DIFFUSE (1 << 1) +# define RADEON_TCL_VTX_FP_ALPHA (1 << 2) +# define RADEON_TCL_VTX_PK_DIFFUSE (1 << 3) +# define RADEON_TCL_VTX_FP_SPEC (1 << 4) +# define RADEON_TCL_VTX_FP_FOG (1 << 5) +# define RADEON_TCL_VTX_PK_SPEC (1 << 6) +# define RADEON_TCL_VTX_ST0 (1 << 7) +# define RADEON_TCL_VTX_ST1 (1 << 8) +# define RADEON_TCL_VTX_Q1 (1 << 9) +# define RADEON_TCL_VTX_ST2 (1 << 10) +# define RADEON_TCL_VTX_Q2 (1 << 11) +# define RADEON_TCL_VTX_ST3 (1 << 12) +# define RADEON_TCL_VTX_Q3 (1 << 13) +# define RADEON_TCL_VTX_Q0 (1 << 14) +# define RADEON_TCL_VTX_WEIGHT_COUNT_SHIFT 15 +# define RADEON_TCL_VTX_NORM0 (1 << 18) +# define RADEON_TCL_VTX_XY1 (1 << 27) +# define RADEON_TCL_VTX_Z1 (1 << 28) +# define RADEON_TCL_VTX_W1 (1 << 29) +# define RADEON_TCL_VTX_NORM1 (1 << 30) +# define RADEON_TCL_VTX_Z0 (1 << 31) + +#define RADEON_SE_TCL_OUTPUT_VTX_SEL 0x2258 +# define RADEON_TCL_COMPUTE_XYZW (1 << 0) +# define RADEON_TCL_COMPUTE_DIFFUSE (1 << 1) +# define RADEON_TCL_COMPUTE_SPECULAR (1 << 2) +# define RADEON_TCL_FORCE_NAN_IF_COLOR_NAN (1 << 3) +# define RADEON_TCL_FORCE_INORDER_PROC (1 << 4) +# define RADEON_TCL_TEX_INPUT_TEX_0 0 +# define RADEON_TCL_TEX_INPUT_TEX_1 1 +# define RADEON_TCL_TEX_INPUT_TEX_2 2 +# define RADEON_TCL_TEX_INPUT_TEX_3 3 +# define RADEON_TCL_TEX_COMPUTED_TEX_0 8 +# define RADEON_TCL_TEX_COMPUTED_TEX_1 9 +# define RADEON_TCL_TEX_COMPUTED_TEX_2 10 +# define RADEON_TCL_TEX_COMPUTED_TEX_3 11 +# define RADEON_TCL_TEX_0_OUTPUT_SHIFT 16 +# define RADEON_TCL_TEX_1_OUTPUT_SHIFT 20 +# define RADEON_TCL_TEX_2_OUTPUT_SHIFT 24 +# define RADEON_TCL_TEX_3_OUTPUT_SHIFT 28 + +#define RADEON_SE_TCL_PER_LIGHT_CTL_0 0x2270 +# define RADEON_LIGHT_0_ENABLE (1 << 0) +# define RADEON_LIGHT_0_ENABLE_AMBIENT (1 << 1) +# define RADEON_LIGHT_0_ENABLE_SPECULAR (1 << 2) +# define RADEON_LIGHT_0_IS_LOCAL (1 << 3) +# define RADEON_LIGHT_0_IS_SPOT (1 << 4) +# define RADEON_LIGHT_0_DUAL_CONE (1 << 5) +# define RADEON_LIGHT_0_ENABLE_RANGE_ATTEN (1 << 6) +# define RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN (1 << 7) +# define RADEON_LIGHT_0_SHIFT 0 +# define RADEON_LIGHT_1_ENABLE (1 << 16) +# define RADEON_LIGHT_1_ENABLE_AMBIENT (1 << 17) +# define RADEON_LIGHT_1_ENABLE_SPECULAR (1 << 18) +# define RADEON_LIGHT_1_IS_LOCAL (1 << 19) +# define RADEON_LIGHT_1_IS_SPOT (1 << 20) +# define RADEON_LIGHT_1_DUAL_CONE (1 << 21) +# define RADEON_LIGHT_1_ENABLE_RANGE_ATTEN (1 << 22) +# define RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN (1 << 23) +# define RADEON_LIGHT_1_SHIFT 16 +#define RADEON_SE_TCL_PER_LIGHT_CTL_1 0x2274 +# define RADEON_LIGHT_2_SHIFT 0 +# define RADEON_LIGHT_3_SHIFT 16 +#define RADEON_SE_TCL_PER_LIGHT_CTL_2 0x2278 +# define RADEON_LIGHT_4_SHIFT 0 +# define RADEON_LIGHT_5_SHIFT 16 +#define RADEON_SE_TCL_PER_LIGHT_CTL_3 0x227c +# define RADEON_LIGHT_6_SHIFT 0 +# define RADEON_LIGHT_7_SHIFT 16 + +#define RADEON_SE_TCL_STATE_FLUSH 0x2284 + +#define RADEON_SE_TCL_SHININESS 0x2250 + +#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268 +# define RADEON_TEXGEN_TEXMAT_0_ENABLE (1 << 0) +# define RADEON_TEXGEN_TEXMAT_1_ENABLE (1 << 1) +# define RADEON_TEXGEN_TEXMAT_2_ENABLE (1 << 2) +# define RADEON_TEXGEN_TEXMAT_3_ENABLE (1 << 3) +# define RADEON_TEXMAT_0_ENABLE (1 << 4) +# define RADEON_TEXMAT_1_ENABLE (1 << 5) +# define RADEON_TEXMAT_2_ENABLE (1 << 6) +# define RADEON_TEXMAT_3_ENABLE (1 << 7) +# define RADEON_TEXGEN_INPUT_MASK 0xf +# define RADEON_TEXGEN_INPUT_TEXCOORD_0 0 +# define RADEON_TEXGEN_INPUT_TEXCOORD_1 1 +# define RADEON_TEXGEN_INPUT_TEXCOORD_2 2 +# define RADEON_TEXGEN_INPUT_TEXCOORD_3 3 +# define RADEON_TEXGEN_INPUT_OBJ 4 +# define RADEON_TEXGEN_INPUT_EYE 5 +# define RADEON_TEXGEN_INPUT_EYE_NORMAL 6 +# define RADEON_TEXGEN_INPUT_EYE_REFLECT 7 +# define RADEON_TEXGEN_INPUT_EYE_NORMALIZED 8 +# define RADEON_TEXGEN_0_INPUT_SHIFT 16 +# define RADEON_TEXGEN_1_INPUT_SHIFT 20 +# define RADEON_TEXGEN_2_INPUT_SHIFT 24 +# define RADEON_TEXGEN_3_INPUT_SHIFT 28 + +#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264 +# define RADEON_UCP_IN_CLIP_SPACE (1 << 0) +# define RADEON_UCP_IN_MODEL_SPACE (1 << 1) +# define RADEON_UCP_ENABLE_0 (1 << 2) +# define RADEON_UCP_ENABLE_1 (1 << 3) +# define RADEON_UCP_ENABLE_2 (1 << 4) +# define RADEON_UCP_ENABLE_3 (1 << 5) +# define RADEON_UCP_ENABLE_4 (1 << 6) +# define RADEON_UCP_ENABLE_5 (1 << 7) +# define RADEON_TCL_FOG_MASK (3 << 8) +# define RADEON_TCL_FOG_DISABLE (0 << 8) +# define RADEON_TCL_FOG_EXP (1 << 8) +# define RADEON_TCL_FOG_EXP2 (2 << 8) +# define RADEON_TCL_FOG_LINEAR (3 << 8) +# define RADEON_RNG_BASED_FOG (1 << 10) +# define RADEON_LIGHT_TWOSIDE (1 << 11) +# define RADEON_BLEND_OP_COUNT_MASK (7 << 12) +# define RADEON_BLEND_OP_COUNT_SHIFT 12 +# define RADEON_POSITION_BLEND_OP_ENABLE (1 << 16) +# define RADEON_NORMAL_BLEND_OP_ENABLE (1 << 17) +# define RADEON_VERTEX_BLEND_SRC_0_PRIMARY (0 << 18) +# define RADEON_VERTEX_BLEND_SRC_0_SECONDARY (1 << 18) +# define RADEON_VERTEX_BLEND_SRC_1_PRIMARY (0 << 19) +# define RADEON_VERTEX_BLEND_SRC_1_SECONDARY (1 << 19) +# define RADEON_VERTEX_BLEND_SRC_2_PRIMARY (0 << 20) +# define RADEON_VERTEX_BLEND_SRC_2_SECONDARY (1 << 20) +# define RADEON_VERTEX_BLEND_SRC_3_PRIMARY (0 << 21) +# define RADEON_VERTEX_BLEND_SRC_3_SECONDARY (1 << 21) +# define RADEON_VERTEX_BLEND_WGT_MINUS_ONE (1 << 22) +# define RADEON_CULL_FRONT_IS_CW (0 << 28) +# define RADEON_CULL_FRONT_IS_CCW (1 << 28) +# define RADEON_CULL_FRONT (1 << 29) +# define RADEON_CULL_BACK (1 << 30) +# define RADEON_FORCE_W_TO_ONE (1 << 31) + +#define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SE_VPORT_XOFFSET 0x1d9c +#define RADEON_SE_VPORT_YSCALE 0x1da0 +#define RADEON_SE_VPORT_YOFFSET 0x1da4 +#define RADEON_SE_VPORT_ZSCALE 0x1da8 +#define RADEON_SE_VPORT_ZOFFSET 0x1dac +#define RADEON_SE_ZBIAS_FACTOR 0x1db0 +#define RADEON_SE_ZBIAS_CONSTANT 0x1db4 + +#define RADEON_SE_VTX_FMT 0x2080 +# define RADEON_SE_VTX_FMT_XY 0x00000000 +# define RADEON_SE_VTX_FMT_W0 0x00000001 +# define RADEON_SE_VTX_FMT_FPCOLOR 0x00000002 +# define RADEON_SE_VTX_FMT_FPALPHA 0x00000004 +# define RADEON_SE_VTX_FMT_PKCOLOR 0x00000008 +# define RADEON_SE_VTX_FMT_FPSPEC 0x00000010 +# define RADEON_SE_VTX_FMT_FPFOG 0x00000020 +# define RADEON_SE_VTX_FMT_PKSPEC 0x00000040 +# define RADEON_SE_VTX_FMT_ST0 0x00000080 +# define RADEON_SE_VTX_FMT_ST1 0x00000100 +# define RADEON_SE_VTX_FMT_Q1 0x00000200 +# define RADEON_SE_VTX_FMT_ST2 0x00000400 +# define RADEON_SE_VTX_FMT_Q2 0x00000800 +# define RADEON_SE_VTX_FMT_ST3 0x00001000 +# define RADEON_SE_VTX_FMT_Q3 0x00002000 +# define RADEON_SE_VTX_FMT_Q0 0x00004000 +# define RADEON_SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 +# define RADEON_SE_VTX_FMT_N0 0x00040000 +# define RADEON_SE_VTX_FMT_XY1 0x08000000 +# define RADEON_SE_VTX_FMT_Z1 0x10000000 +# define RADEON_SE_VTX_FMT_W1 0x20000000 +# define RADEON_SE_VTX_FMT_N1 0x40000000 +# define RADEON_SE_VTX_FMT_Z 0x80000000 + + /* Registers for CP and Microcode Engine */ +#define RADEON_CP_ME_RAM_ADDR 0x07d4 +#define RADEON_CP_ME_RAM_RADDR 0x07d8 +#define RADEON_CP_ME_RAM_DATAH 0x07dc +#define RADEON_CP_ME_RAM_DATAL 0x07e0 + +#define RADEON_CP_RB_BASE 0x0700 +#define RADEON_CP_RB_CNTL 0x0704 +#define RADEON_CP_RB_RPTR_ADDR 0x070c +#define RADEON_CP_RB_RPTR 0x0710 +#define RADEON_CP_RB_WPTR 0x0714 + +#define RADEON_CP_IB_BASE 0x0738 +#define RADEON_CP_IB_BUFSZ 0x073c + +#define RADEON_CP_CSQ_CNTL 0x0740 +# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) +# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) +# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) +# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) +# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) +# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) +#define RADEON_CP_CSQ_STAT 0x07f8 +# define RADEON_CSQ_RPTR_PRIMARY_MASK (0xff << 0) +# define RADEON_CSQ_WPTR_PRIMARY_MASK (0xff << 8) +# define RADEON_CSQ_RPTR_INDIRECT_MASK (0xff << 16) +# define RADEON_CSQ_WPTR_INDIRECT_MASK (0xff << 24) +#define RADEON_CP_CSQ_ADDR 0x07f0 +#define RADEON_CP_CSQ_DATA 0x07f4 +#define RADEON_CP_CSQ_APER_PRIMARY 0x1000 +#define RADEON_CP_CSQ_APER_INDIRECT 0x1300 + +#define RADEON_CP_RB_WPTR_DELAY 0x0718 +# define RADEON_PRE_WRITE_TIMER_SHIFT 0 +# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 + +#define RADEON_AIC_CNTL 0x01d0 +# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) +#define RADEON_AIC_LO_ADDR 0x01dc + + + + /* Constants */ +#define RADEON_LAST_FRAME_REG RADEON_GUI_SCRATCH_REG0 +#define RADEON_LAST_CLEAR_REG RADEON_GUI_SCRATCH_REG2 + + + + /* CP packet types */ +#define RADEON_CP_PACKET0 0x00000000 +#define RADEON_CP_PACKET1 0x40000000 +#define RADEON_CP_PACKET2 0x80000000 +#define RADEON_CP_PACKET3 0xC0000000 +# define RADEON_CP_PACKET_MASK 0xC0000000 +# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 +# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) +# define RADEON_CP_PACKET0_REG_MASK 0x000007ff +# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff +# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 + +#define RADEON_CP_PACKET0_ONE_REG_WR 0x00008000 + +#define RADEON_CP_PACKET3_NOP 0xC0001000 +#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 +#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 +#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 +#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 +#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 +#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 +#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400 +#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500 +#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600 +#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 + + +#define RADEON_CP_VC_FRMT_XY 0x00000000 +#define RADEON_CP_VC_FRMT_W0 0x00000001 +#define RADEON_CP_VC_FRMT_FPCOLOR 0x00000002 +#define RADEON_CP_VC_FRMT_FPALPHA 0x00000004 +#define RADEON_CP_VC_FRMT_PKCOLOR 0x00000008 +#define RADEON_CP_VC_FRMT_FPSPEC 0x00000010 +#define RADEON_CP_VC_FRMT_FPFOG 0x00000020 +#define RADEON_CP_VC_FRMT_PKSPEC 0x00000040 +#define RADEON_CP_VC_FRMT_ST0 0x00000080 +#define RADEON_CP_VC_FRMT_ST1 0x00000100 +#define RADEON_CP_VC_FRMT_Q1 0x00000200 +#define RADEON_CP_VC_FRMT_ST2 0x00000400 +#define RADEON_CP_VC_FRMT_Q2 0x00000800 +#define RADEON_CP_VC_FRMT_ST3 0x00001000 +#define RADEON_CP_VC_FRMT_Q3 0x00002000 +#define RADEON_CP_VC_FRMT_Q0 0x00004000 +#define RADEON_CP_VC_FRMT_BLND_WEIGHT_CNT_MASK 0x00038000 +#define RADEON_CP_VC_FRMT_N0 0x00040000 +#define RADEON_CP_VC_FRMT_XY1 0x08000000 +#define RADEON_CP_VC_FRMT_Z1 0x10000000 +#define RADEON_CP_VC_FRMT_W1 0x20000000 +#define RADEON_CP_VC_FRMT_N1 0x40000000 +#define RADEON_CP_VC_FRMT_Z 0x80000000 + +#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2 0x00000007 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a +#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 +#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080 +#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000 +#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100 +#define RADEON_CP_VC_CNTL_TCL_DISABLE 0x00000000 +#define RADEON_CP_VC_CNTL_TCL_ENABLE 0x00000200 +#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 + +#define RADEON_VS_MATRIX_0_ADDR 0 +#define RADEON_VS_MATRIX_1_ADDR 4 +#define RADEON_VS_MATRIX_2_ADDR 8 +#define RADEON_VS_MATRIX_3_ADDR 12 +#define RADEON_VS_MATRIX_4_ADDR 16 +#define RADEON_VS_MATRIX_5_ADDR 20 +#define RADEON_VS_MATRIX_6_ADDR 24 +#define RADEON_VS_MATRIX_7_ADDR 28 +#define RADEON_VS_MATRIX_8_ADDR 32 +#define RADEON_VS_MATRIX_9_ADDR 36 +#define RADEON_VS_MATRIX_10_ADDR 40 +#define RADEON_VS_MATRIX_11_ADDR 44 +#define RADEON_VS_MATRIX_12_ADDR 48 +#define RADEON_VS_MATRIX_13_ADDR 52 +#define RADEON_VS_MATRIX_14_ADDR 56 +#define RADEON_VS_MATRIX_15_ADDR 60 +#define RADEON_VS_LIGHT_AMBIENT_ADDR 64 +#define RADEON_VS_LIGHT_DIFFUSE_ADDR 72 +#define RADEON_VS_LIGHT_SPECULAR_ADDR 80 +#define RADEON_VS_LIGHT_DIRPOS_ADDR 88 +#define RADEON_VS_LIGHT_HWVSPOT_ADDR 96 +#define RADEON_VS_LIGHT_ATTENUATION_ADDR 104 +#define RADEON_VS_MATRIX_EYE2CLIP_ADDR 112 +#define RADEON_VS_UCP_ADDR 116 +#define RADEON_VS_GLOBAL_AMBIENT_ADDR 122 +#define RADEON_VS_FOG_PARAM_ADDR 123 +#define RADEON_VS_EYE_VECTOR_ADDR 124 + +#define RADEON_SS_LIGHT_DCD_ADDR 0 +#define RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR 8 +#define RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR 16 +#define RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR 24 +#define RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR 32 +#define RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR 48 +#define RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR 49 +#define RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR 50 +#define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 51 +#define RADEON_SS_SHININESS 60 + +#define RADEON_TV_MASTER_CNTL 0x0800 +# define RADEON_TVCLK_ALWAYS_ONb (1 << 30) +#define RADEON_TV_DAC_CNTL 0x088c +# define RADEON_TV_DAC_CMPOUT (1 << 5) +#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888 +# define RADEON_Y_RED_EN (1 << 0) +# define RADEON_C_GRN_EN (1 << 1) +# define RADEON_CMP_BLU_EN (1 << 2) +# define RADEON_RED_MX_FORCE_DAC_DATA (6 << 4) +# define RADEON_GRN_MX_FORCE_DAC_DATA (6 << 8) +# define RADEON_BLU_MX_FORCE_DAC_DATA (6 << 12) +# define RADEON_TV_FORCE_DAC_DATA_SHIFT 16 +#endif |