From 8953bfce0eb7e56f13d4527ef86cdf4cf2db037f Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 6 Mar 2010 06:33:20 +0200 Subject: dri: drop MINIGLX_SOURCES --- src/mesa/drivers/dri/r300/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 04459c2ddfa..08934fc996a 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -7,8 +7,6 @@ CFLAGS += $(RADEON_CFLAGS) LIBNAME = r300_dri.so -MINIGLX_SOURCES = server/radeon_dri.c - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif -- cgit v1.2.3 From 419f0f9d0426bc1eb40ceb60e7764af4013947a0 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 6 Mar 2010 06:33:21 +0200 Subject: dri: drop MINIGLX_SOURCES (2) --- src/mesa/drivers/dri/i810/server/i810_dri.c | 975 ----------------- src/mesa/drivers/dri/i915/server/intel_dri.c | 1 - src/mesa/drivers/dri/i965/server/intel_dri.c | 1 - src/mesa/drivers/dri/intel/server/intel_dri.c | 1306 ---------------------- src/mesa/drivers/dri/mga/server/mga_dri.c | 1088 ------------------ src/mesa/drivers/dri/r128/server/r128_dri.c | 1112 ------------------- src/mesa/drivers/dri/r200/server/radeon_dri.c | 1 - src/mesa/drivers/dri/r300/server/radeon_dri.c | 1 - src/mesa/drivers/dri/r600/server/radeon_dri.c | 1 - src/mesa/drivers/dri/radeon/server/radeon_dri.c | 1337 ----------------------- src/mesa/drivers/dri/tdfx/server/tdfx_dri.c | 471 -------- src/mesa/drivers/dri/unichrome/server/via_dri.c | 1251 --------------------- 12 files changed, 7545 deletions(-) delete mode 100644 src/mesa/drivers/dri/i810/server/i810_dri.c delete mode 120000 src/mesa/drivers/dri/i915/server/intel_dri.c delete mode 120000 src/mesa/drivers/dri/i965/server/intel_dri.c delete mode 100644 src/mesa/drivers/dri/intel/server/intel_dri.c delete mode 100644 src/mesa/drivers/dri/mga/server/mga_dri.c delete mode 100644 src/mesa/drivers/dri/r128/server/r128_dri.c delete mode 120000 src/mesa/drivers/dri/r200/server/radeon_dri.c delete mode 120000 src/mesa/drivers/dri/r300/server/radeon_dri.c delete mode 120000 src/mesa/drivers/dri/r600/server/radeon_dri.c delete mode 100644 src/mesa/drivers/dri/radeon/server/radeon_dri.c delete mode 100644 src/mesa/drivers/dri/tdfx/server/tdfx_dri.c delete mode 100644 src/mesa/drivers/dri/unichrome/server/via_dri.c (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/i810/server/i810_dri.c b/src/mesa/drivers/dri/i810/server/i810_dri.c deleted file mode 100644 index f52797c5ed2..00000000000 --- a/src/mesa/drivers/dri/i810/server/i810_dri.c +++ /dev/null @@ -1,975 +0,0 @@ -/** - * \file server/i810_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2004 Dave Airlie (airlied@linux.ie) - */ - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "i810.h" -#include "i810_dri.h" -#include "i810_reg.h" - - -static int i810_pitches[] = { - 512, - 1024, - 2048, - 4096, - 0 -}; - -static int i810_pitch_flags[] = { - 0x0, - 0x1, - 0x2, - 0x3, - 0 -}; - -static unsigned int i810_drm_version = 0; - -static int -I810AllocLow(I810MemRange * result, I810MemRange * pool, int size) -{ - if (size > pool->Size) - return 0; - - pool->Size -= size; - result->Size = size; - result->Start = pool->Start; - result->End = pool->Start += size; - - return 1; -} - -static int -I810AllocHigh(I810MemRange * result, I810MemRange * pool, int size) -{ - if (size > pool->Size) - return 0; - - pool->Size -= size; - result->Size = size; - result->End = pool->End; - result->Start = pool->End -= size; - - return 1; -} - - -/** - * \brief Wait for free FIFO entries. - * - * \param ctx display handle. - * \param entries number of free entries to wait. - * - * It polls the free entries from the chip until it reaches the requested value - * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out. - */ -static void I810WaitForFifo( const DRIDriverContext *ctx, - int entries ) -{ -} - -/** - * \brief Reset graphics card to known state. - * - * \param ctx display handle. - * - * Resets the values of several I810 registers. - */ -static void I810EngineReset( const DRIDriverContext *ctx ) -{ - unsigned char *I810MMIO = ctx->MMIOAddress; -} - -/** - * \brief Restore the drawing engine. - * - * \param ctx display handle - * - * Resets the graphics card and sets initial values for several registers of - * the card's drawing engine. - * - * Turns on the i810 command processor engine (i.e., the ringbuffer). - */ -static int I810EngineRestore( const DRIDriverContext *ctx ) -{ - I810Ptr info = ctx->driverPrivate; - unsigned char *I810MMIO = ctx->MMIOAddress; - - fprintf(stderr, "%s\n", __FUNCTION__); - - return 1; -} - - -/** - * \brief Shutdown the drawing engine. - * - * \param ctx display handle - * - * Turns off the command processor engine & restores the graphics card - * to a state that fbdev understands. - */ -static int I810EngineShutdown( const DRIDriverContext *ctx ) -{ - drmI810Init info; - int ret; - - memset(&info, 0, sizeof(drmI810Init)); - info.func = I810_CLEANUP_DMA; - - ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &info, sizeof(drmI810Init)); - if (ret>0) - { - fprintf(stderr,"[dri] I810 DMA Cleanup failed\n"); - return -errno; - } - return 0; -} - -/** - * \brief Compute base 2 logarithm. - * - * \param val value. - * - * \return base 2 logarithm of \p val. - */ -static int I810MinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - -static int I810DRIAgpPreInit( const DRIDriverContext *ctx, I810Ptr info) -{ - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - - if (drmAgpEnable(ctx->drmFD, 0) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } -} - -/** - * \brief Initialize the AGP state - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Acquires and enables the AGP device. Reserves memory in the AGP space for - * the ring buffer, vertex buffers and textures. Initialize the I810 - * registers to point to that memory and add client mappings. - */ -static int I810DRIAgpInit( const DRIDriverContext *ctx, I810Ptr info) -{ - unsigned char *I810MMIO = ctx->MMIOAddress; - int ret; - int s, l; - unsigned long dcacheHandle; - unsigned long agpHandle; - int pitch_idx = 0; - int back_size = 0; - int sysmem_size = 0; - int width = ctx->shared.virtualWidth * ctx->cpp; - - - info->backHandle = DRM_AGP_NO_HANDLE; - info->zHandle = DRM_AGP_NO_HANDLE; - info->sysmemHandle = DRM_AGP_NO_HANDLE; - info->dcacheHandle = DRM_AGP_NO_HANDLE; - - memset(&info->DcacheMem, 0, sizeof(I810MemRange)); - memset(&info->BackBuffer, 0, sizeof(I810MemRange)); - memset(&info->DepthBuffer, 0, sizeof(I810MemRange)); - - drmAgpAlloc(ctx->drmFD, 4096 * 1024, 1, NULL, &dcacheHandle); - info->dcacheHandle = dcacheHandle; - - fprintf(stderr, "[agp] dcacheHandle : 0x%x\n", dcacheHandle); - -#define Elements(x) sizeof(x)/sizeof(*x) - for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++) - if (width <= i810_pitches[pitch_idx]) - break; - - if (pitch_idx == Elements(i810_pitches)) { - fprintf(stderr,"[dri] Couldn't find depth/back buffer pitch\n"); - exit(-1); - } - else - { - int lines = (ctx->shared.virtualWidth + 15) / 16 * 16; - back_size = i810_pitches[pitch_idx] * lines; - back_size = ((back_size + 4096 - 1) / 4096) * 4096; - } - - sysmem_size = ctx->shared.fbSize; - fprintf(stderr,"sysmem_size is %lu back_size is %lu\n", sysmem_size, back_size); - if (dcacheHandle != DRM_AGP_NO_HANDLE) { - if (back_size > 4 * 1024 * 1024) { - fprintf(stderr,"[dri] Backsize is larger then 4 meg\n"); - sysmem_size = sysmem_size - 2 * back_size; - drmAgpFree(ctx->drmFD, dcacheHandle); - info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; - } else { - sysmem_size = sysmem_size - back_size; - } - } else { - sysmem_size = sysmem_size - 2 * back_size; - } - - info->SysMem.Start=0; - info->SysMem.Size = sysmem_size; - info->SysMem.End = sysmem_size; - - if (dcacheHandle != DRM_AGP_NO_HANDLE) { - if (drmAgpBind(ctx->drmFD, dcacheHandle, info->DepthOffset) == 0) { - memset(&info->DcacheMem, 0, sizeof(I810MemRange)); - fprintf(stderr,"[agp] GART: Found 4096K Z buffer memory\n"); - info->DcacheMem.Start = info->DepthOffset; - info->DcacheMem.Size = 1024 * 4096; - info->DcacheMem.End = info->DcacheMem.Start + info->DcacheMem.Size; - } else { - fprintf(stderr, "[agp] GART: dcache bind failed\n"); - drmAgpFree(ctx->drmFD, dcacheHandle); - info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; - } - } else { - fprintf(stderr, "[agp] GART: no dcache memory found\n"); - } - - drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle); - info->backHandle = agpHandle; - - if (agpHandle != DRM_AGP_NO_HANDLE) { - if (drmAgpBind(ctx->drmFD, agpHandle, info->BackOffset) == 0) { - fprintf(stderr, "[agp] Bound backbuffer memory\n"); - - info->BackBuffer.Start = info->BackOffset; - info->BackBuffer.Size = back_size; - info->BackBuffer.End = (info->BackBuffer.Start + - info->BackBuffer.Size); - } else { - fprintf(stderr,"[agp] Unable to bind backbuffer. Disabling DRI.\n"); - return 0; - } - } else { - fprintf(stderr, "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n"); - return 0; - } - - if (dcacheHandle == DRM_AGP_NO_HANDLE) { - drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle); - - info->zHandle = agpHandle; - - if (agpHandle != DRM_AGP_NO_HANDLE) { - if (drmAgpBind(ctx->drmFD, agpHandle, info->DepthOffset) == 0) { - fprintf(stderr,"[agp] Bound depthbuffer memory\n"); - info->DepthBuffer.Start = info->DepthOffset; - info->DepthBuffer.Size = back_size; - info->DepthBuffer.End = (info->DepthBuffer.Start + - info->DepthBuffer.Size); - } else { - fprintf(stderr,"[agp] Unable to bind depthbuffer. Disabling DRI.\n"); - return 0; - } - } else { - fprintf(stderr,"[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n"); - return 0; - } - } - - /* Now allocate and bind the agp space. This memory will include the - * regular framebuffer as well as texture memory. - */ - drmAgpAlloc(ctx->drmFD, sysmem_size, 0, NULL, &agpHandle); - info->sysmemHandle = agpHandle; - - if (agpHandle != DRM_AGP_NO_HANDLE) { - if (drmAgpBind(ctx->drmFD, agpHandle, 0) == 0) { - fprintf(stderr, "[agp] Bound System Texture Memory\n"); - } else { - fprintf(stderr, "[agp] Unable to bind system texture memory. Disabling DRI.\n"); - return 0; - } - } else { - fprintf(stderr, "[agp] Unable to allocate system texture memory. Disabling DRI.\n"); - return 0; - } - - info->auxPitch = i810_pitches[pitch_idx]; - info->auxPitchBits = i810_pitch_flags[pitch_idx]; - - return 1; -} - - -/** - * \brief Initialize the kernel data structures and enable the CP engine. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * This function is a wrapper around the DRM_I810_CP_INIT command, passing - * all the parameters in a drmI810Init structure. - */ -static int I810DRIKernelInit( const DRIDriverContext *ctx, - I810Ptr info) -{ - int cpp = ctx->bpp / 8; - drmI810Init drmInfo; - int ret; - I810RingBuffer *ring = &(info->LpRing); - - /* This is the struct passed to the kernel module for its initialization */ - memset(&drmInfo, 0, sizeof(drmI810Init)); - - /* make sure we have at least 1.4 */ - drmInfo.func = I810_INIT_DMA_1_4; - - drmInfo.ring_start = ring->mem.Start; - drmInfo.ring_end = ring->mem.End; - drmInfo.ring_size = ring->mem.Size; - - drmInfo.mmio_offset = (unsigned int)info->regs; - drmInfo.buffers_offset = (unsigned int)info->buffer_map; - drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); - - drmInfo.front_offset = 0; - drmInfo.back_offset = info->BackBuffer.Start; - drmInfo.depth_offset = info->DepthBuffer.Start; - - drmInfo.w = ctx->shared.virtualWidth; - drmInfo.h = ctx->shared.virtualHeight; - drmInfo.pitch = info->auxPitch; - drmInfo.pitch_bits = info->auxPitchBits; - - - ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &drmInfo, - sizeof(drmI810Init)); - - return ret >= 0; -} - - -/** - * \brief Add a map for the vertex buffers that will be accessed by any - * DRI-based clients. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Calls drmAddBufs() with the previously allocated vertex buffers. - */ -static int I810DRIBufInit( const DRIDriverContext *ctx, I810Ptr info ) -{ - /* Initialize vertex buffers */ - info->bufNumBufs = drmAddBufs(ctx->drmFD, - I810_DMA_BUF_NR, - I810_DMA_BUF_SZ, - DRM_AGP_BUFFER, - info->BufferMem.Start); - - if (info->bufNumBufs <= 0) { - fprintf(stderr, - "[drm] Could not create vertex/indirect buffers list\n"); - return 0; - } - fprintf(stderr, - "[drm] Added %d %d byte vertex/indirect buffers\n", - info->bufNumBufs, I810_DMA_BUF_SZ); - - return 1; -} - -/** - * \brief Install an IRQ handler. - * - * \param ctx display handle. - * \param info driver private data. - * - * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to - * IRQ-free operation on failure. - */ -static void I810DRIIrqInit(const DRIDriverContext *ctx, - I810Ptr info) -{ - if (!info->irq) { - info->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) { - fprintf(stderr, - "[drm] failure adding irq handler, " - "there is a device already using that irq\n" - "[drm] falling back to irq-free operation\n"); - info->irq = 0; - } - } - - if (info->irq) - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - info->irq); -} - -static int I810CheckDRMVersion( const DRIDriverContext *ctx, - I810Ptr info ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - i810_drm_version = (version->version_major<<16) | version->version_minor; - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I810DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i810.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - info->drmMinor = version->version_minor; - drmFreeVersion(version); - } - - return 1; -} - -static int I810MemoryInit( const DRIDriverContext *ctx, I810Ptr info ) -{ - int width_bytes = ctx->shared.virtualWidth * ctx->cpp; - int cpp = ctx->cpp; - int bufferSize = (ctx->shared.virtualHeight * width_bytes); - int depthSize = (((ctx->shared.virtualHeight+15) & ~15) * width_bytes); - int l; - - if (drmAddMap(ctx->drmFD, (drm_handle_t) info->BackBuffer.Start, - info->BackBuffer.Size, DRM_AGP, 0, - &info->backbuffer) < 0) { - fprintf(stderr, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); - return 0; - } - - if (drmAddMap(ctx->drmFD, (drm_handle_t) info->DepthBuffer.Start, - info->DepthBuffer.Size, DRM_AGP, 0, - &info->depthbuffer) < 0) { - fprintf(stderr, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n"); - return 0; - } - - if (!I810AllocLow(&(info->FrontBuffer), &(info->SysMem), (((ctx->shared.virtualHeight * width_bytes) + 4095) & ~4095))) - { - fprintf(stderr,"Framebuffer allocation failed\n"); - return 0; - } - else - fprintf(stderr,"Frame buffer at 0x%.8x (%luk, %lu bytes)\n", - info->FrontBuffer.Start, - info->FrontBuffer.Size / 1024, info->FrontBuffer.Size); - - memset(&(info->LpRing), 0, sizeof(I810RingBuffer)); - if (I810AllocLow(&(info->LpRing.mem), &(info->SysMem), 16 * 4096)) { - fprintf(stderr, - "Ring buffer at 0x%.8x (%luk, %lu bytes)\n", - info->LpRing.mem.Start, - info->LpRing.mem.Size / 1024, info->LpRing.mem.Size); - - info->LpRing.tail_mask = info->LpRing.mem.Size - 1; - info->LpRing.virtual_start = info->LpRing.mem.Start; - info->LpRing.head = 0; - info->LpRing.tail = 0; - info->LpRing.space = 0; - } else { - fprintf(stderr, "Ring buffer allocation failed\n"); - return (0); - } - - /* Allocate buffer memory */ - I810AllocHigh(&(info->BufferMem), &(info->SysMem), - I810_DMA_BUF_NR * I810_DMA_BUF_SZ); - - - fprintf(stderr, "[dri] Buffer map : %lx\n", - info->BufferMem.Start); - - if (info->BufferMem.Start == 0 || - info->BufferMem.End - info->BufferMem.Start > - I810_DMA_BUF_NR * I810_DMA_BUF_SZ) { - fprintf(stderr,"[dri] Not enough memory for dma buffers. Disabling DRI.\n"); - return 0; - } - - if (drmAddMap(ctx->drmFD, (drm_handle_t) info->BufferMem.Start, - info->BufferMem.Size, DRM_AGP, 0, &info->buffer_map) < 0) { - fprintf(stderr, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n"); - return 0; - } - - if (drmAddMap(ctx->drmFD, (drm_handle_t) info->LpRing.mem.Start, - info->LpRing.mem.Size, DRM_AGP, 0, &info->ring_map) < 0) { - fprintf(stderr, "[drm] drmAddMap(ring_map) failed. Disabling DRI. \n"); - return 0; - } - - /* Front, back and depth buffers - everything else texture?? - */ - info->textureSize = info->SysMem.Size; - - if (info->textureSize < 0) - return 0; - - - l = I810MinBits((info->textureSize-1) / I810_NR_TEX_REGIONS); - if (l < I810_LOG_MIN_TEX_REGION_SIZE) l = I810_LOG_MIN_TEX_REGION_SIZE; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->logTextureGranularity = l; - info->textureSize = (info->textureSize >> l) << l; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - I810AllocLow(&(info->TexMem), &(info->SysMem), info->textureSize); - - if (drmAddMap(ctx->drmFD, (drm_handle_t) info->TexMem.Start, - info->TexMem.Size, DRM_AGP, 0, &info->textures) < 0) { - fprintf(stderr, - "[drm] drmAddMap(textures) failed. Disabling DRI.\n"); - return 0; - } - - /* Reserve space for textures */ - fprintf(stderr, - "Will use back buffer at offset 0x%x\n", - info->BackOffset); - fprintf(stderr, - "Will use depth buffer at offset 0x%x\n", - info->DepthOffset); - fprintf(stderr, - "Will use %d kb for textures at offset 0x%x\n", - info->TexMem.Size/1024, info->TexMem.Start); - - return 1; -} - - - -/** - * Called at the start of each server generation. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Performs static frame buffer allocation. Opens the DRM device and add maps - * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more - * information. Creates a \e server context to grab the lock for the - * initialization ioctls and calls the other initilization functions in this - * file. Starts the CP engine via the DRM_I810_CP_START command. - * - * Setups a I810DRIRec structure to be passed to i810_dri.so for its - * initialization. - */ -static int I810ScreenInit( DRIDriverContext *ctx, I810Ptr info ) -{ - I810DRIPtr pI810DRI; - int err; - - usleep(100); - /*assert(!ctx->IsClient);*/ - - /* from XFree86 driver */ - info->DepthOffset = 0x3000000; - info->BackOffset = 0x3800000; - { - int width_bytes = (ctx->shared.virtualWidth * ctx->cpp); - int maxy = ctx->shared.fbSize / width_bytes; - - - if (maxy <= ctx->shared.virtualHeight * 3) { - fprintf(stderr, - "Static buffer allocation failed -- " - "need at least %d kB video memory (have %d kB)\n", - (ctx->shared.virtualWidth * ctx->shared.virtualHeight * - ctx->cpp * 3 + 1023) / 1024, - ctx->shared.fbSize / 1024); - return 0; - } - } - - - info->regsSize = ctx->MMIOSize; - ctx->shared.SAREASize = 0x2000; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i810", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &info->regs) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", info->regs); - - I810DRIAgpPreInit(ctx, info); - /* Need to AddMap the framebuffer and mmio regions here: - */ - if (drmAddMap( ctx->drmFD, - (drm_handle_t)ctx->FBStart, - ctx->FBSize, - DRM_FRAME_BUFFER, -#ifndef _EMBEDDED - 0, -#else - DRM_READ_ONLY, -#endif - &ctx->shared.hFrameBuffer) < 0) - { - fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); - return 0; - } - - fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", - ctx->shared.hFrameBuffer); - - /* Check the i810 DRM version */ - if (!I810CheckDRMVersion(ctx, info)) { - return 0; - } - - /* Initialize AGP */ - if (!I810DRIAgpInit(ctx, info)) { - return 0; - } - - - /* Memory manager setup */ - if (!I810MemoryInit(ctx, info)) { - return 0; - } - - /* Initialize the SAREA private data structure */ - { - I810SAREAPtr pSAREAPriv; - pSAREAPriv = (I810SAREAPtr)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - // pSAREAPriv->pf_enabled=1; - } - - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the vertex buffers list */ - if (!I810DRIBufInit(ctx, info)) { - fprintf(stderr, "I810DRIBufInit failed\n"); - DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); - return 0; - } - - /* Initialize the kernel data structures */ - if (!I810DRIKernelInit(ctx, info)) { - fprintf(stderr, "I810DRIKernelInit failed\n"); - DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); - return 0; - } - - /* Initialize IRQ */ - I810DRIIrqInit(ctx, info); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ -#if 0 - memset((char *)ctx->FBAddress, - 0, - info->auxPitch * ctx->cpp * ctx->shared.virtualHeight ); - - memset((char *)info->backbuffer, - 0, - info->auxPitch * ctx->cpp * ctx->shared.virtualHeight ); -#endif - - /* This is the struct passed to i810_dri.so for its initialization */ - ctx->driverClientMsg = malloc(sizeof(I810DRIRec)); - ctx->driverClientMsgSize = sizeof(I810DRIRec); - pI810DRI = (I810DRIPtr)ctx->driverClientMsg; - - pI810DRI->regs = info->regs; - pI810DRI->regsSize = info->regsSize; - // regsMap is unused - - pI810DRI->backbufferSize = info->BackBuffer.Size; - pI810DRI->backbuffer = info->backbuffer; - - pI810DRI->depthbufferSize = info->DepthBuffer.Size; - pI810DRI->depthbuffer = info->depthbuffer; - - pI810DRI->textures = info->textures; - pI810DRI->textureSize = info->textureSize; - - pI810DRI->agp_buffers = info->buffer_map; - pI810DRI->agp_buf_size = info->BufferMem.Size; - - pI810DRI->deviceID = info->Chipset; - pI810DRI->width = ctx->shared.virtualWidth; - pI810DRI->height = ctx->shared.virtualHeight; - pI810DRI->mem = ctx->shared.fbSize; - pI810DRI->cpp = ctx->bpp / 8; - pI810DRI->bitsPerPixel = ctx->bpp; - pI810DRI->fbOffset = info->FrontBuffer.Start; - pI810DRI->fbStride = info->auxPitch; - - pI810DRI->backOffset = info->BackBuffer.Start; - pI810DRI->depthOffset = info->DepthBuffer.Start; - - pI810DRI->auxPitch = info->auxPitch; - pI810DRI->auxPitchBits = info->auxPitchBits; - - pI810DRI->logTextureGranularity = info->logTextureGranularity; - pI810DRI->textureOffset = info->TexMem.Start; - - pI810DRI->ringOffset = info->LpRing.mem.Start; - pI810DRI->ringSize = info->LpRing.mem.Size; - - // drmBufs looks unused - pI810DRI->irq = info->irq; - pI810DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - /* Don't release the lock now - let the VT switch handler do it. */ - return 1; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i810ValidateMode( const DRIDriverContext *ctx ) -{ - unsigned char *I810MMIO = ctx->MMIOAddress; - I810Ptr info = ctx->driverPrivate; - - return 1; -} - - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i810PostValidateMode( const DRIDriverContext *ctx ) -{ - unsigned char *I810MMIO = ctx->MMIOAddress; - I810Ptr info = ctx->driverPrivate; - - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i810InitFBDev( DRIDriverContext *ctx ) -{ - I810Ptr info = calloc(1, sizeof(*info)); - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - } - - ctx->driverPrivate = (void *)info; - - info->Chipset = ctx->chipset; - - if (!I810ScreenInit( ctx, info )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i810HaltFBDev( DRIDriverContext *ctx ) -{ - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i810ValidateMode, - i810PostValidateMode, - i810InitFBDev, - i810HaltFBDev, - I810EngineShutdown, - I810EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; diff --git a/src/mesa/drivers/dri/i915/server/intel_dri.c b/src/mesa/drivers/dri/i915/server/intel_dri.c deleted file mode 120000 index effdd26448a..00000000000 --- a/src/mesa/drivers/dri/i915/server/intel_dri.c +++ /dev/null @@ -1 +0,0 @@ -../../intel/server/intel_dri.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/server/intel_dri.c b/src/mesa/drivers/dri/i965/server/intel_dri.c deleted file mode 120000 index effdd26448a..00000000000 --- a/src/mesa/drivers/dri/i965/server/intel_dri.c +++ /dev/null @@ -1 +0,0 @@ -../../intel/server/intel_dri.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/server/intel_dri.c b/src/mesa/drivers/dri/intel/server/intel_dri.c deleted file mode 100644 index e49c4214ad4..00000000000 --- a/src/mesa/drivers/dri/intel/server/intel_dri.c +++ /dev/null @@ -1,1306 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - 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 THE COPYRIGHT HOLDERS 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 -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge, ig_dev; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - uint32_t aper_size; - uint32_t membase2 = 0; - - memset(&host_bridge, 0, sizeof(host_bridge)); - memset(&ig_dev, 0, sizeof(ig_dev)); - - ig_dev.dev = 2; - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - if (IS_I830(pI830) || IS_845G(pI830)) { - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - aper_size = 0x80000000; - } else { - aper_size = 0x40000000; - } - } else { - if (IS_I9XX(pI830)) { - int ret; - ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); - if (membase2 & 0x08000000) - aper_size = 0x8000000; - else - aper_size = 0x10000000; - - fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); - } else - aper_size = 0x8000000; - } - - pI830->aper_size = aper_size; - - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, long size, - unsigned long alignment, int flags) -{ - unsigned long ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) { - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - else { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - if (ret == 0) - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - return ret; -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - -#if 0 - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } -#endif - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; -#if 0 - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; -#endif - return TRUE; -} - -static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - - fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); - if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { - fprintf(stderr, - "DRM MM Initialization Failed\n"); - } else { - fprintf(stderr, - "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); - } - -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - -#if 0 - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); -#endif - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - SetupDRIMM(ctx, pI830); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->rotated_offset = -1; - pSAREAPriv->rotated_size = 0; - pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; -#if 0 - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; -#endif - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; diff --git a/src/mesa/drivers/dri/mga/server/mga_dri.c b/src/mesa/drivers/dri/mga/server/mga_dri.c deleted file mode 100644 index bc575e62ee8..00000000000 --- a/src/mesa/drivers/dri/mga/server/mga_dri.c +++ /dev/null @@ -1,1088 +0,0 @@ - -/* - * Copyright 2000 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 - * VA LINUX SYSTEMS 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 - * Gareth Hughes - */ - -#include -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" -#include "memops.h" - -#include "mga_reg.h" -#include "mga.h" -#include "mga_macros.h" -#include "mga_dri.h" - - -/* Quiescence, locking - */ -#define MGA_TIMEOUT 2048 - -static void MGAWaitForIdleDMA( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - drm_lock_t lock; - int ret; - int i = 0; - - memset( &lock, 0, sizeof(lock) ); - - for (;;) { - do { - /* first ask for quiescent and flush */ - lock.flags = DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH; - do { - ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH, - &lock, sizeof( lock ) ); - } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); - - /* if it's still busy just try quiescent */ - if ( ret == -EBUSY ) { - lock.flags = DRM_LOCK_QUIESCENT; - do { - ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH, - &lock, sizeof( lock ) ); - } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); - } - } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) ); - - if ( ret == 0 ) - return; - - fprintf( stderr, - "[dri] Idle timed out, resetting engine...\n" ); - - drmCommandNone( ctx->drmFD, DRM_MGA_RESET ); - } -} - -static unsigned int mylog2( unsigned int n ) -{ - unsigned int log2 = 1; - while ( n > 1 ) n >>= 1, log2++; - return log2; -} - -static int MGADRIAgpInit(struct DRIDriverContextRec *ctx, MGAPtr pMga) -{ - unsigned long mode; - unsigned int vendor, device; - int ret, count, i; - - if(pMga->agpSize < 12)pMga->agpSize = 12; - if(pMga->agpSize > 64)pMga->agpSize = 64; /* cap */ - - /* FIXME: Make these configurable... - */ - pMga->agp.size = pMga->agpSize * 1024 * 1024; - - pMga->warp.offset = 0; - pMga->warp.size = MGA_WARP_UCODE_SIZE; - - pMga->primary.offset = (pMga->warp.offset + - pMga->warp.size); - pMga->primary.size = 1024 * 1024; - - pMga->buffers.offset = (pMga->primary.offset + - pMga->primary.size); - pMga->buffers.size = MGA_NUM_BUFFERS * MGA_BUFFER_SIZE; - - - pMga->agpTextures.offset = (pMga->buffers.offset + - pMga->buffers.size); - - pMga->agpTextures.size = pMga->agp.size - - pMga->agpTextures.offset; - - if ( drmAgpAcquire( ctx->drmFD ) < 0 ) { - fprintf( stderr, "[agp] AGP not available\n" ); - return 0; - } - - mode = drmAgpGetMode( ctx->drmFD ); /* Default mode */ - vendor = drmAgpVendorId( ctx->drmFD ); - device = drmAgpDeviceId( ctx->drmFD ); - - mode &= ~MGA_AGP_MODE_MASK; - switch ( pMga->agpMode ) { - case 4: - mode |= MGA_AGP_4X_MODE; - case 2: - mode |= MGA_AGP_2X_MODE; - case 1: - default: - mode |= MGA_AGP_1X_MODE; - } - -#if 0 - fprintf( stderr, - "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", - mode, vendor, device, - ctx->pciVendor, - ctx->pciChipType ); -#endif - - if ( drmAgpEnable( ctx->drmFD, mode ) < 0 ) { - fprintf( stderr, "[agp] AGP not enabled\n" ); - drmAgpRelease( ctx->drmFD ); - return 0; - } - - if ( pMga->Chipset == PCI_CHIP_MGAG200 ) { - switch ( pMga->agpMode ) { - case 2: - fprintf( stderr, - "[drm] Enabling AGP 2x PLL encoding\n" ); - OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_ENABLE ); - break; - - case 1: - default: - fprintf( stderr, - "[drm] Disabling AGP 2x PLL encoding\n" ); - OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_DISABLE ); - pMga->agpMode = 1; - break; - } - } - - ret = drmAgpAlloc( ctx->drmFD, pMga->agp.size, - 0, NULL, &pMga->agp.handle ); - if ( ret < 0 ) { - fprintf( stderr, "[agp] Out of memory (%d)\n", ret ); - drmAgpRelease( ctx->drmFD ); - return 0; - } - fprintf( stderr, - "[agp] %d kB allocated with handle 0x%08x\n", - pMga->agp.size/1024, (unsigned int)pMga->agp.handle ); - - if ( drmAgpBind( ctx->drmFD, pMga->agp.handle, 0 ) < 0 ) { - fprintf( stderr, "[agp] Could not bind memory\n" ); - drmAgpFree( ctx->drmFD, pMga->agp.handle ); - drmAgpRelease( ctx->drmFD ); - return 0; - } - - /* WARP microcode space - */ - if ( drmAddMap( ctx->drmFD, - pMga->warp.offset, - pMga->warp.size, - DRM_AGP, DRM_READ_ONLY, - &pMga->warp.handle ) < 0 ) { - fprintf( stderr, - "[agp] Could not add WARP microcode mapping\n" ); - return 0; - } - fprintf( stderr, - "[agp] WARP microcode handle = 0x%08x\n", - pMga->warp.handle ); - - if ( drmMap( ctx->drmFD, - pMga->warp.handle, - pMga->warp.size, - &pMga->warp.map ) < 0 ) { - fprintf( stderr, - "[agp] Could not map WARP microcode\n" ); - return 0; - } - fprintf( stderr, - "[agp] WARP microcode mapped at 0x%08lx\n", - (unsigned long)pMga->warp.map ); - - /* Primary DMA space - */ - if ( drmAddMap( ctx->drmFD, - pMga->primary.offset, - pMga->primary.size, - DRM_AGP, DRM_READ_ONLY, - &pMga->primary.handle ) < 0 ) { - fprintf( stderr, - "[agp] Could not add primary DMA mapping\n" ); - return 0; - } - fprintf( stderr, - "[agp] Primary DMA handle = 0x%08x\n", - pMga->primary.handle ); - - if ( drmMap( ctx->drmFD, - pMga->primary.handle, - pMga->primary.size, - &pMga->primary.map ) < 0 ) { - fprintf( stderr, - "[agp] Could not map primary DMA\n" ); - return 0; - } - fprintf( stderr, - "[agp] Primary DMA mapped at 0x%08lx\n", - (unsigned long)pMga->primary.map ); - - /* DMA buffers - */ - if ( drmAddMap( ctx->drmFD, - pMga->buffers.offset, - pMga->buffers.size, - DRM_AGP, 0, - &pMga->buffers.handle ) < 0 ) { - fprintf( stderr, - "[agp] Could not add DMA buffers mapping\n" ); - return 0; - } - fprintf( stderr, - "[agp] DMA buffers handle = 0x%08x\n", - pMga->buffers.handle ); - - if ( drmMap( ctx->drmFD, - pMga->buffers.handle, - pMga->buffers.size, - &pMga->buffers.map ) < 0 ) { - fprintf( stderr, - "[agp] Could not map DMA buffers\n" ); - return 0; - } - fprintf( stderr, - "[agp] DMA buffers mapped at 0x%08lx\n", - (unsigned long)pMga->buffers.map ); - - count = drmAddBufs( ctx->drmFD, - MGA_NUM_BUFFERS, MGA_BUFFER_SIZE, - DRM_AGP_BUFFER, pMga->buffers.offset ); - if ( count <= 0 ) { - fprintf( stderr, - "[drm] failure adding %d %d byte DMA buffers\n", - MGA_NUM_BUFFERS, MGA_BUFFER_SIZE ); - return 0; - } - fprintf( stderr, - "[drm] Added %d %d byte DMA buffers\n", - count, MGA_BUFFER_SIZE ); - - i = mylog2(pMga->agpTextures.size / MGA_NR_TEX_REGIONS); - if(i < MGA_LOG_MIN_TEX_REGION_SIZE) - i = MGA_LOG_MIN_TEX_REGION_SIZE; - pMga->agpTextures.size = (pMga->agpTextures.size >> i) << i; - - if ( drmAddMap( ctx->drmFD, - pMga->agpTextures.offset, - pMga->agpTextures.size, - DRM_AGP, 0, - &pMga->agpTextures.handle ) < 0 ) { - fprintf( stderr, - "[agp] Could not add agpTexture mapping\n" ); - return 0; - } -/* should i map it ? */ - fprintf( stderr, - "[agp] agpTexture handle = 0x%08x\n", - pMga->agpTextures.handle ); - fprintf( stderr, - "[agp] agpTexture size: %d kb\n", pMga->agpTextures.size/1024 ); - - return 1; -} - -static int MGADRIMapInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - pMga->registers.size = MGAIOMAPSIZE; - - if ( drmAddMap( ctx->drmFD, - (drm_handle_t)pMga->IOAddress, - pMga->registers.size, - DRM_REGISTERS, DRM_READ_ONLY, - &pMga->registers.handle ) < 0 ) { - fprintf( stderr, - "[drm] Could not add MMIO registers mapping\n" ); - return 0; - } - fprintf( stderr, - "[drm] Registers handle = 0x%08lx\n", - pMga->registers.handle ); - - pMga->status.size = SAREA_MAX; - - if ( drmAddMap( ctx->drmFD, 0, pMga->status.size, - DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, - &pMga->status.handle ) < 0 ) { - fprintf( stderr, - "[drm] Could not add status page mapping\n" ); - return 0; - } - fprintf( stderr, - "[drm] Status handle = 0x%08x\n", - pMga->status.handle ); - - if ( drmMap( ctx->drmFD, - pMga->status.handle, - pMga->status.size, - &pMga->status.map ) < 0 ) { - fprintf( stderr, - "[agp] Could not map status page\n" ); - return 0; - } - fprintf( stderr, - "[agp] Status page mapped at 0x%08lx\n", - (unsigned long)pMga->status.map ); - - return 1; -} - -static int MGADRIKernelInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - drm_mga_init_t init; - int ret; - - memset( &init, 0, sizeof(init) ); - - init.func = MGA_INIT_DMA; - init.sarea_priv_offset = sizeof(drm_sarea_t); - - switch ( pMga->Chipset ) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - init.chipset = MGA_CARD_TYPE_G400; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - init.chipset = MGA_CARD_TYPE_G200; - break; - default: - return 0; - } - - init.sgram = 0; /* FIXME !pMga->HasSDRAM; */ - - - switch (ctx->bpp) - { - case 16: - init.maccess = MGA_MACCESS_PW16; - break; - case 32: - init.maccess = MGA_MACCESS_PW32; - break; - default: - fprintf( stderr, "[mga] invalid bpp (%d)\n", ctx->bpp ); - return 0; - } - - - init.fb_cpp = ctx->bpp / 8; - init.front_offset = pMga->frontOffset; - init.front_pitch = pMga->frontPitch / init.fb_cpp; - init.back_offset = pMga->backOffset; - init.back_pitch = pMga->backPitch / init.fb_cpp; - - init.depth_cpp = ctx->bpp / 8; - init.depth_offset = pMga->depthOffset; - init.depth_pitch = pMga->depthPitch / init.depth_cpp; - - init.texture_offset[0] = pMga->textureOffset; - init.texture_size[0] = pMga->textureSize; - - init.fb_offset = ctx->shared.hFrameBuffer; - init.mmio_offset = pMga->registers.handle; - init.status_offset = pMga->status.handle; - - init.warp_offset = pMga->warp.handle; - init.primary_offset = pMga->primary.handle; - init.buffers_offset = pMga->buffers.handle; - - init.texture_offset[1] = pMga->agpTextures.handle; - init.texture_size[1] = pMga->agpTextures.size; - - ret = drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(init)); - if ( ret < 0 ) { - fprintf( stderr, - "[drm] Failed to initialize DMA! (%d)\n", ret ); - return 0; - } - - return 1; -} - -static void MGADRIIrqInit(struct DRIDriverContextRec *ctx, MGAPtr pMga) -{ - if (!pMga->irq) - { - pMga->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - fprintf(stderr, "[drm] got IRQ %d\n", pMga->irq); - - if((drmCtlInstHandler(ctx->drmFD, pMga->irq)) != 0) - { - fprintf(stderr, - "[drm] failure adding irq handler, " - "there is a device already using that irq\n" - "[drm] falling back to irq-free operation\n"); - pMga->irq = 0; - } - else - { - pMga->reg_ien = INREG( MGAREG_IEN ); - } - } - - if (pMga->irq) - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pMga->irq); -} - -static int MGADRIBuffersInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - pMga->drmBuffers = drmMapBufs( ctx->drmFD ); - if ( !pMga->drmBuffers ) - { - fprintf( stderr, - "[drm] Failed to map DMA buffers list\n" ); - return 0; - } - - fprintf( stderr, - "[drm] Mapped %d DMA buffers\n", - pMga->drmBuffers->count ); - - return 1; -} - -static int MGAMemoryInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - int width_bytes = ctx->shared.virtualWidth * ctx->cpp; - int bufferSize = ((ctx->shared.virtualHeight * width_bytes - + MGA_BUFFER_ALIGN) - & ~MGA_BUFFER_ALIGN); - int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes - + MGA_BUFFER_ALIGN) - & ~MGA_BUFFER_ALIGN); - int l; - - pMga->frontOffset = 0; - pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp; - - fprintf(stderr, - "Using %d MB AGP aperture\n", pMga->agpSize); - fprintf(stderr, - "Using %d MB for vertex/indirect buffers\n", pMga->buffers.size>>20); - fprintf(stderr, - "Using %d MB for AGP textures\n", pMga->agpTextures.size>>20); - - /* Front, back and depth buffers - everything else texture?? - */ - pMga->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; - - if (pMga->textureSize < 0) - return 0; - - l = mylog2( pMga->textureSize / MGA_NR_TEX_REGIONS ); - if ( l < MGA_LOG_MIN_TEX_REGION_SIZE ) - l = MGA_LOG_MIN_TEX_REGION_SIZE; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - pMga->logTextureGranularity = l; - pMga->textureSize = (pMga->textureSize >> l) << l; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (pMga->textureSize < 512 * 1024) { - pMga->textureOffset = 0; - pMga->textureSize = 0; - } - - /* Reserve space for textures */ - pMga->textureOffset = ((ctx->shared.fbSize - pMga->textureSize + - MGA_BUFFER_ALIGN) & - ~MGA_BUFFER_ALIGN); - - /* Reserve space for the shared depth - * buffer. - */ - pMga->depthOffset = ((pMga->textureOffset - depthSize + - MGA_BUFFER_ALIGN) & - ~MGA_BUFFER_ALIGN); - pMga->depthPitch = ctx->shared.virtualWidth * ctx->cpp; - - pMga->backOffset = ((pMga->depthOffset - bufferSize + - MGA_BUFFER_ALIGN) & - ~MGA_BUFFER_ALIGN); - pMga->backPitch = ctx->shared.virtualWidth * ctx->cpp; - - - fprintf(stderr, - "Will use back buffer at offset 0x%x\n", - pMga->backOffset); - fprintf(stderr, - "Will use depth buffer at offset 0x%x\n", - pMga->depthOffset); - fprintf(stderr, - "Will use %d kb for textures at offset 0x%x\n", - pMga->textureSize/1024, pMga->textureOffset); - - return 1; -} - -static int MGACheckDRMVersion( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - drmVersionPtr version; - - /* Check the MGA DRM version */ - version = drmGetVersion(ctx->drmFD); - if ( version ) { - if ( version->version_major != 3 || - version->version_minor < 0 ) { - /* incompatible drm version */ - fprintf( stderr, - "[dri] MGADRIScreenInit failed because of a version mismatch.\n" - "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel ); - drmFreeVersion( version ); - return 0; - } - drmFreeVersion( version ); - } - - return 1; -} - -static void print_client_msg( MGADRIPtr pMGADRI ) -{ - fprintf( stderr, "chipset: %d\n", pMGADRI->chipset ); - - fprintf( stderr, "width: %d\n", pMGADRI->width ); - fprintf( stderr, "height: %d\n", pMGADRI->height ); - fprintf( stderr, "mem: %d\n", pMGADRI->mem ); - fprintf( stderr, "cpp: %d\n", pMGADRI->cpp ); - - fprintf( stderr, "agpMode: %d\n", pMGADRI->agpMode ); - - fprintf( stderr, "frontOffset: %d\n", pMGADRI->frontOffset ); - fprintf( stderr, "frontPitch: %d\n", pMGADRI->frontPitch ); - - fprintf( stderr, "backOffset: %d\n", pMGADRI->backOffset ); - fprintf( stderr, "backPitch: %d\n", pMGADRI->backPitch ); - - fprintf( stderr, "depthOffset: %d\n", pMGADRI->depthOffset ); - fprintf( stderr, "depthPitch: %d\n", pMGADRI->depthPitch ); - - fprintf( stderr, "textureOffset: %d\n", pMGADRI->textureOffset ); - fprintf( stderr, "textureSize: %d\n", pMGADRI->textureSize ); - - fprintf( stderr, "logTextureGranularity: %d\n", pMGADRI->logTextureGranularity ); - fprintf( stderr, "logAgpTextureGranularity: %d\n", pMGADRI->logAgpTextureGranularity ); - - fprintf( stderr, "agpTextureHandle: %u\n", (unsigned int)pMGADRI->agpTextureOffset ); - fprintf( stderr, "agpTextureSize: %u\n", (unsigned int)pMGADRI->agpTextureSize ); - -#if 0 - pMGADRI->registers.handle = pMga->registers.handle; - pMGADRI->registers.size = pMga->registers.size; - pMGADRI->status.handle = pMga->status.handle; - pMGADRI->status.size = pMga->status.size; - pMGADRI->primary.handle = pMga->primary.handle; - pMGADRI->primary.size = pMga->primary.size; - pMGADRI->buffers.handle = pMga->buffers.handle; - pMGADRI->buffers.size = pMga->buffers.size; - pMGADRI->sarea_priv_offset = sizeof(drm_sarea_t); -#endif -} - -static int MGAScreenInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) -{ - int i; - int err; - MGADRIPtr pMGADRI; - - usleep(100); - /*assert(!ctx->IsClient);*/ - - { - int width_bytes = (ctx->shared.virtualWidth * ctx->cpp); - int maxy = ctx->shared.fbSize / width_bytes; - - - if (maxy <= ctx->shared.virtualHeight * 3) { - fprintf(stderr, - "Static buffer allocation failed -- " - "need at least %d kB video memory (have %d kB)\n", - (ctx->shared.virtualWidth * ctx->shared.virtualHeight * - ctx->cpp * 3 + 1023) / 1024, - ctx->shared.fbSize / 1024); - return 0; - } - } - - switch(pMga->Chipset) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG200: -#if 0 - case PCI_CHIP_MGAG200_PCI: -#endif - break; - default: - fprintf(stderr, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n"); - return 0; - } - - fprintf( stderr, - "[drm] bpp: %d depth: %d\n", - ctx->bpp, ctx->bpp /* FIXME: depth */ ); - - if ( (ctx->bpp / 8) != 2 && - (ctx->bpp / 8) != 4 ) { - fprintf( stderr, - "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" ); - return 0; - } - - ctx->shared.SAREASize = SAREA_MAX; - - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("mga", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - /* Need to AddMap the framebuffer and mmio regions here: - */ - if (drmAddMap( ctx->drmFD, - (drm_handle_t)ctx->FBStart, - ctx->FBSize, - DRM_FRAME_BUFFER, - 0, - &ctx->shared.hFrameBuffer) < 0) - { - fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); - return 0; - } - fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", - ctx->shared.hFrameBuffer); - - -#if 0 /* will be done in MGADRIMapInit */ - if (drmAddMap(ctx->drmFD, - ctx->FixedInfo.mmio_start, - ctx->FixedInfo.mmio_len, - DRM_REGISTERS, - DRM_READ_ONLY, - &pMga->registers.handle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08lx\n", pMga->registers.handle); -#endif - - - /* Check the mga DRM version */ - if (!MGACheckDRMVersion(ctx, pMga)) { - return 0; - } - - if ( !MGADRIAgpInit( ctx, pMga ) ) { - return 0; - } - - if ( !MGADRIMapInit( ctx, pMga ) ) { - return 0; - } - - /* Memory manager setup */ - if (!MGAMemoryInit(ctx, pMga)) { - return 0; - } - - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the kernel data structures */ - if (!MGADRIKernelInit(ctx, pMga)) { - fprintf(stderr, "MGADRIKernelInit failed\n"); - DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); - return 0; - } - - /* Initialize the vertex buffers list */ - if (!MGADRIBuffersInit(ctx, pMga)) { - fprintf(stderr, "MGADRIBuffersInit failed\n"); - DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); - return 0; - } - - /* Initialize IRQ */ - MGADRIIrqInit(ctx, pMga); - - - /* Initialize the SAREA private data structure */ - { - drm_mga_sarea_t *pSAREAPriv; - pSAREAPriv = (drm_mga_sarea_t *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - } - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - drimemsetio((char *)ctx->FBAddress + pMga->frontOffset, - 0, - pMga->frontPitch * ctx->shared.virtualHeight ); - - drimemsetio((char *)ctx->FBAddress + pMga->backOffset, - 0, - pMga->backPitch * ctx->shared.virtualHeight ); - - /* Can release the lock now */ -/* DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/ - - /* This is the struct passed to radeon_dri.so for its initialization */ - ctx->driverClientMsg = malloc(sizeof(MGADRIRec)); - ctx->driverClientMsgSize = sizeof(MGADRIRec); - - pMGADRI = (MGADRIPtr)ctx->driverClientMsg; - - - switch(pMga->Chipset) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - pMGADRI->chipset = MGA_CARD_TYPE_G400; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - pMGADRI->chipset = MGA_CARD_TYPE_G200; - break; - default: - return 0; - } - pMGADRI->width = ctx->shared.virtualWidth; - pMGADRI->height = ctx->shared.virtualHeight; - pMGADRI->mem = ctx->shared.fbSize; - pMGADRI->cpp = ctx->bpp / 8; - - pMGADRI->agpMode = pMga->agpMode; - - pMGADRI->frontOffset = pMga->frontOffset; - pMGADRI->frontPitch = pMga->frontPitch; - pMGADRI->backOffset = pMga->backOffset; - pMGADRI->backPitch = pMga->backPitch; - pMGADRI->depthOffset = pMga->depthOffset; - pMGADRI->depthPitch = pMga->depthPitch; - pMGADRI->textureOffset = pMga->textureOffset; - pMGADRI->textureSize = pMga->textureSize; - pMGADRI->logTextureGranularity = pMga->logTextureGranularity; - - i = mylog2( pMga->agpTextures.size / MGA_NR_TEX_REGIONS ); - if ( i < MGA_LOG_MIN_TEX_REGION_SIZE ) - i = MGA_LOG_MIN_TEX_REGION_SIZE; - - pMGADRI->logAgpTextureGranularity = i; - pMGADRI->agpTextureOffset = (unsigned int)pMga->agpTextures.handle; - pMGADRI->agpTextureSize = (unsigned int)pMga->agpTextures.size; - - pMGADRI->registers.handle = pMga->registers.handle; - pMGADRI->registers.size = pMga->registers.size; - pMGADRI->status.handle = pMga->status.handle; - pMGADRI->status.size = pMga->status.size; - pMGADRI->primary.handle = pMga->primary.handle; - pMGADRI->primary.size = pMga->primary.size; - pMGADRI->buffers.handle = pMga->buffers.handle; - pMGADRI->buffers.size = pMga->buffers.size; - pMGADRI->sarea_priv_offset = sizeof(drm_sarea_t); - - print_client_msg( pMGADRI ); - - return 1; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa mgaValidateMode(). - */ -static int mgaValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa mgaValidateMode(). - */ -static int mgaPostValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls MGAScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memomry accessing it directly. - */ -static int mgaInitFBDev( struct DRIDriverContextRec *ctx ) -{ - MGAPtr pMga = calloc(1, sizeof(*pMga)); - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - } - - ctx->driverPrivate = (void *)pMga; - - pMga->agpMode = MGA_DEFAULT_AGP_MODE; - pMga->agpSize = MGA_DEFAULT_AGP_SIZE; - - pMga->Chipset = ctx->chipset; - - pMga->IOAddress = ctx->MMIOStart; - pMga->IOBase = ctx->MMIOAddress; - - pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp; - - if (!MGAScreenInit( ctx, pMga )) - return 0; - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void mgaHaltFBDev( struct DRIDriverContextRec *ctx ) -{ - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = NULL; - } -} - - -static int mgaEngineShutdown( const DRIDriverContext *ctx ) -{ - fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__); - - return 1; -} - -static int mgaEngineRestore( const DRIDriverContext *ctx ) -{ - fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__); - - return 1; -} - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -struct DRIDriverRec __driDriver = { - mgaValidateMode, - mgaPostValidateMode, - mgaInitFBDev, - mgaHaltFBDev, - mgaEngineShutdown, - mgaEngineRestore, - 0 -}; - - - - -#if 0 -void MGADRICloseScreen( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - MGAPtr pMga = MGAPTR(pScrn); - MGADRIServerPrivatePtr pMga = pMga->DRIServerInfo; - drmMGAInit init; - - if ( pMga->drmBuffers ) { - drmUnmapBufs( pMga->drmBuffers ); - pMga->drmBuffers = NULL; - } - - if (pMga->irq) { - drmCtlUninstHandler(ctx->drmFD); - pMga->irq = 0; - } - - /* Cleanup DMA */ - memset( &init, 0, sizeof(drmMGAInit) ); - init.func = MGA_CLEANUP_DMA; - drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit) ); - - if ( pMga->status.map ) { - drmUnmap( pMga->status.map, pMga->status.size ); - pMga->status.map = NULL; - } - if ( pMga->buffers.map ) { - drmUnmap( pMga->buffers.map, pMga->buffers.size ); - pMga->buffers.map = NULL; - } - if ( pMga->primary.map ) { - drmUnmap( pMga->primary.map, pMga->primary.size ); - pMga->primary.map = NULL; - } - if ( pMga->warp.map ) { - drmUnmap( pMga->warp.map, pMga->warp.size ); - pMga->warp.map = NULL; - } - - if ( pMga->agpTextures.map ) { - drmUnmap( pMga->agpTextures.map, pMga->agpTextures.size ); - pMga->agpTextures.map = NULL; - } - - if ( pMga->agp.handle ) { - drmAgpUnbind( ctx->drmFD, pMga->agp.handle ); - drmAgpFree( ctx->drmFD, pMga->agp.handle ); - pMga->agp.handle = 0; - drmAgpRelease( ctx->drmFD ); - } - - DRICloseScreen( pScreen ); - - if ( pMga->pDRIInfo ) { - if ( pMga->pDRIpMga->devPrivate ) { - xfree( pMga->pDRIpMga->devPrivate ); - pMga->pDRIpMga->devPrivate = 0; - } - DRIDestroyInfoRec( pMga->pDRIInfo ); - pMga->pDRIInfo = 0; - } - if ( pMga->DRIServerInfo ) { - xfree( pMga->DRIServerInfo ); - pMga->DRIServerInfo = 0; - } - if ( pMga->pVisualConfigs ) { - xfree( pMga->pVisualConfigs ); - } - if ( pMga->pVisualConfigsPriv ) { - xfree( pMga->pVisualConfigsPriv ); - } -} -#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_dri.c b/src/mesa/drivers/dri/r128/server/r128_dri.c deleted file mode 100644 index 6e3db948af7..00000000000 --- a/src/mesa/drivers/dri/r128/server/r128_dri.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, - * Precision Insight, Inc., Cedar Park, Texas, 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, PRECISION INSIGHT, 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 - * Rickard E. Faith - * Daryll Strauss - * Gareth Hughes - * - */ - -#include -#include -#include -#include -#include -// Fix this to use kernel pci_ids.h when all of these IDs make it into the kernel -#include "pci_ids.h" - -#include "driver.h" -#include "drm.h" -#include "memops.h" - -#include "r128.h" -#include "r128_dri.h" -#include "r128_macros.h" -#include "r128_reg.h" -#include "r128_version.h" -#include "r128_drm.h" - -static size_t r128_drm_page_size; - -/* Compute log base 2 of val. */ -static int R128MinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - -/* Initialize the AGP state. Request memory for use in AGP space, and - initialize the Rage 128 registers to point to that memory. */ -static GLboolean R128DRIAgpInit(const DRIDriverContext *ctx) -{ - unsigned char *R128MMIO = ctx->MMIOAddress; - R128InfoPtr info = ctx->driverPrivate; - unsigned long mode; - unsigned int vendor, device; - int ret; - unsigned long cntl, chunk; - int s, l; - int flags; - unsigned long agpBase; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[agp] AGP not available\n"); - return GL_FALSE; - } - - /* Modify the mode if the default mode is - not appropriate for this particular - combination of graphics card and AGP - chipset. */ - - mode = drmAgpGetMode(ctx->drmFD); /* Default mode */ - vendor = drmAgpVendorId(ctx->drmFD); - device = drmAgpDeviceId(ctx->drmFD); - - mode &= ~R128_AGP_MODE_MASK; - switch (info->agpMode) { - case 4: mode |= R128_AGP_4X_MODE; - case 2: mode |= R128_AGP_2X_MODE; - case 1: default: mode |= R128_AGP_1X_MODE; - } - - fprintf(stderr, - "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", - mode, vendor, device, - 0x1002, - info->Chipset); - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[agp] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return GL_FALSE; - } - - info->agpOffset = 0; - - if ((ret = drmAgpAlloc(ctx->drmFD, info->agpSize*1024*1024, 0, NULL, - &info->agpMemHandle)) < 0) { - fprintf(stderr, "[agp] Out of memory (%d)\n", ret); - drmAgpRelease(ctx->drmFD); - return GL_FALSE; - } - fprintf(stderr, - "[agp] %d kB allocated with handle 0x%08x\n", - info->agpSize*1024, info->agpMemHandle); - - if (drmAgpBind(ctx->drmFD, info->agpMemHandle, info->agpOffset) < 0) { - fprintf(stderr, "[agp] Could not bind\n"); - drmAgpFree(ctx->drmFD, info->agpMemHandle); - drmAgpRelease(ctx->drmFD); - return GL_FALSE; - } - - /* Initialize the CCE ring buffer data */ - info->ringStart = info->agpOffset; - info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; - info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = r128_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->agpTexStart = info->bufStart + info->bufMapSize; - s = (info->agpSize*1024*1024 - info->agpTexStart); - l = R128MinBits((s-1) / R128_NR_TEX_REGIONS); - if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; - info->agpTexMapSize = (s >> l) << l; - info->log2AGPTexGran = l; - - if (info->CCESecure) flags = DRM_READ_ONLY; - else flags = 0; - - if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, - DRM_AGP, flags, &info->ringHandle) < 0) { - fprintf(stderr, - "[agp] Could not add ring mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] ring handle = 0x%08x\n", info->ringHandle); - - if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, - (drmAddressPtr)&info->ring) < 0) { - fprintf(stderr, "[agp] Could not map ring\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] Ring mapped at 0x%08lx\n", - (unsigned long)info->ring); - - if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[agp] Could not add ring read ptr mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] ring read ptr handle = 0x%08x\n", - info->ringReadPtrHandle); - - if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, - (drmAddressPtr)&info->ringReadPtr) < 0) { - fprintf(stderr, - "[agp] Could not map ring read ptr\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] Ring read ptr mapped at 0x%08lx\n", - (unsigned long)info->ringReadPtr); - - if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, - DRM_AGP, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[agp] Could not add vertex/indirect buffers mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, - (drmAddressPtr)&info->buf) < 0) { - fprintf(stderr, - "[agp] Could not map vertex/indirect buffers\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", - (unsigned long)info->buf); - - if (drmAddMap(ctx->drmFD, info->agpTexStart, info->agpTexMapSize, - DRM_AGP, 0, &info->agpTexHandle) < 0) { - fprintf(stderr, - "[agp] Could not add AGP texture map mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] AGP texture map handle = 0x%08lx\n", - info->agpTexHandle); - - if (drmMap(ctx->drmFD, info->agpTexHandle, info->agpTexMapSize, - (drmAddressPtr)&info->agpTex) < 0) { - fprintf(stderr, - "[agp] Could not map AGP texture map\n"); - return GL_FALSE; - } - fprintf(stderr, - "[agp] AGP Texture map mapped at 0x%08lx\n", - (unsigned long)info->agpTex); - - /* Initialize Rage 128's AGP registers */ - cntl = INREG(R128_AGP_CNTL); - cntl &= ~R128_AGP_APER_SIZE_MASK; - switch (info->agpSize) { - case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; - case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; - case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; - case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; - case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; - case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; - case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; - default: - fprintf(stderr, - "[agp] Illegal aperture size %d kB\n", - info->agpSize*1024); - return GL_FALSE; - } - agpBase = drmAgpBase(ctx->drmFD); - OUTREG(R128_AGP_BASE, agpBase); - OUTREG(R128_AGP_CNTL, cntl); - - /* Disable Rage 128's PCIGART registers */ - chunk = INREG(R128_BM_CHUNK_0_VAL); - chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | - R128_BM_PM4_RD_FORCE_TO_PCI | - R128_BM_GLOBAL_FORCE_TO_PCI); - OUTREG(R128_BM_CHUNK_0_VAL, chunk); - - OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */ - - return GL_TRUE; -} - -static GLboolean R128DRIPciInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - unsigned char *R128MMIO = ctx->MMIOAddress; - uint32_t chunk; - int ret; - int flags; - - info->agpOffset = 0; - - ret = drmScatterGatherAlloc(ctx->drmFD, info->agpSize*1024*1024, - &info->pciMemHandle); - if (ret < 0) { - fprintf(stderr, "[pci] Out of memory (%d)\n", ret); - return GL_FALSE; - } - fprintf(stderr, - "[pci] %d kB allocated with handle 0x%08x\n", - info->agpSize*1024, info->pciMemHandle); - - /* Initialize the CCE ring buffer data */ - info->ringStart = info->agpOffset; - info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; - info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = r128_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; - - if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, - DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[pci] ring handle = 0x%08lx\n", info->ringHandle); - - if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, - (drmAddressPtr)&info->ring) < 0) { - fprintf(stderr, "[pci] Could not map ring\n"); - return GL_FALSE; - } - fprintf(stderr, - "[pci] Ring mapped at 0x%08lx\n", - (unsigned long)info->ring); - fprintf(stderr, - "[pci] Ring contents 0x%08lx\n", - *(unsigned long *)info->ring); - - if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring read ptr mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[pci] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, - (drmAddressPtr)&info->ringReadPtr) < 0) { - fprintf(stderr, - "[pci] Could not map ring read ptr\n"); - return GL_FALSE; - } - fprintf(stderr, - "[pci] Ring read ptr mapped at 0x%08lx\n", - (unsigned long)info->ringReadPtr); - fprintf(stderr, - "[pci] Ring read ptr contents 0x%08lx\n", - *(unsigned long *)info->ringReadPtr); - - if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, - DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[pci] Could not add vertex/indirect buffers mapping\n"); - return GL_FALSE; - } - fprintf(stderr, - "[pci] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, - (drmAddressPtr)&info->buf) < 0) { - fprintf(stderr, - "[pci] Could not map vertex/indirect buffers\n"); - return GL_FALSE; - } - fprintf(stderr, - "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", - (unsigned long)info->buf); - fprintf(stderr, - "[pci] Vertex/indirect buffers contents 0x%08lx\n", - *(unsigned long *)info->buf); - - if (!info->IsPCI) { - /* This is really an AGP card, force PCI GART mode */ - chunk = INREG(R128_BM_CHUNK_0_VAL); - chunk |= (R128_BM_PTR_FORCE_TO_PCI | - R128_BM_PM4_RD_FORCE_TO_PCI | - R128_BM_GLOBAL_FORCE_TO_PCI); - OUTREG(R128_BM_CHUNK_0_VAL, chunk); - OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ - } - - return GL_TRUE; -} - -/* Add a map for the MMIO registers that will be accessed by any - DRI-based clients. */ -static GLboolean R128DRIMapInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - int flags; - - if (info->CCESecure) flags = DRM_READ_ONLY; - else flags = 0; - - /* Map registers */ - if (drmAddMap(ctx->drmFD, ctx->MMIOStart, ctx->MMIOSize, - DRM_REGISTERS, flags, &info->registerHandle) < 0) { - return GL_FALSE; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", info->registerHandle); - - return GL_TRUE; -} - -/* Initialize the kernel data structures. */ -static int R128DRIKernelInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - drm_r128_init_t drmInfo; - - memset( &drmInfo, 0, sizeof(&drmInfo) ); - - drmInfo.func = R128_INIT_CCE; - drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); - drmInfo.is_pci = info->IsPCI; - drmInfo.cce_mode = info->CCEMode; - drmInfo.cce_secure = info->CCESecure; - drmInfo.ring_size = info->ringSize*1024*1024; - drmInfo.usec_timeout = info->CCEusecTimeout; - - drmInfo.fb_bpp = ctx->bpp; - drmInfo.depth_bpp = ctx->bpp; - - drmInfo.front_offset = info->frontOffset; - drmInfo.front_pitch = info->frontPitch; - - drmInfo.back_offset = info->backOffset; - drmInfo.back_pitch = info->backPitch; - - drmInfo.depth_offset = info->depthOffset; - drmInfo.depth_pitch = info->depthPitch; - drmInfo.span_offset = info->spanOffset; - - drmInfo.fb_offset = info->LinearAddr; - drmInfo.mmio_offset = info->registerHandle; - drmInfo.ring_offset = info->ringHandle; - drmInfo.ring_rptr_offset = info->ringReadPtrHandle; - drmInfo.buffers_offset = info->bufHandle; - drmInfo.agp_textures_offset = info->agpTexHandle; - - if (drmCommandWrite(ctx->drmFD, DRM_R128_INIT, - &drmInfo, sizeof(drmInfo)) < 0) - return GL_FALSE; - - return GL_TRUE; -} - -/* Add a map for the vertex buffers that will be accessed by any - DRI-based clients. */ -static GLboolean R128DRIBufInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - /* Initialize vertex buffers */ - if (info->IsPCI) { - info->bufNumBufs = drmAddBufs(ctx->drmFD, - info->bufMapSize / R128_BUFFER_SIZE, - R128_BUFFER_SIZE, - DRM_SG_BUFFER, - info->bufStart); - } else { - info->bufNumBufs = drmAddBufs(ctx->drmFD, - info->bufMapSize / R128_BUFFER_SIZE, - R128_BUFFER_SIZE, - DRM_AGP_BUFFER, - info->bufStart); - } - if (info->bufNumBufs <= 0) { - fprintf(stderr, - "[drm] Could not create vertex/indirect buffers list\n"); - return GL_FALSE; - } - fprintf(stderr, - "[drm] Added %d %d byte vertex/indirect buffers\n", - info->bufNumBufs, R128_BUFFER_SIZE); - - if (!(info->buffers = drmMapBufs(ctx->drmFD))) { - fprintf(stderr, - "[drm] Failed to map vertex/indirect buffers list\n"); - return GL_FALSE; - } - fprintf(stderr, - "[drm] Mapped %d vertex/indirect buffers\n", - info->buffers->count); - - return GL_TRUE; -} - -static void R128DRIIrqInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - unsigned char *R128MMIO = ctx->MMIOAddress; - - if (!info->irq) { - info->irq = drmGetInterruptFromBusID( - ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) { - fprintf(stderr, - "[drm] failure adding irq handler, " - "there is a device already using that irq\n" - "[drm] falling back to irq-free operation\n"); - info->irq = 0; - } else { - info->gen_int_cntl = INREG( R128_GEN_INT_CNTL ); - } - } - - if (info->irq) - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - info->irq); -} - -static int R128CCEStop(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - drm_r128_cce_stop_t stop; - int ret, i; - - stop.flush = 1; - stop.idle = 1; - - ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, - &stop, sizeof(stop) ); - - if ( ret == 0 ) { - return 0; - } else if ( errno != EBUSY ) { - return -errno; - } - - stop.flush = 0; - - i = 0; - do { - ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, - &stop, sizeof(stop) ); - } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); - - if ( ret == 0 ) { - return 0; - } else if ( errno != EBUSY ) { - return -errno; - } - - stop.idle = 0; - - if ( drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, - &stop, sizeof(stop) )) { - return -errno; - } else { - return 0; - } -} - -/* Initialize the CCE state, and start the CCE (if used by the X server) */ -static void R128DRICCEInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - - /* Turn on bus mastering */ - info->BusCntl &= ~R128_BUS_MASTER_DIS; - - /* CCEMode is initialized in r128_driver.c */ - switch (info->CCEMode) { - case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; - case R128_PM4_192PIO: info->CCEFifoSize = 192; break; - case R128_PM4_192BM: info->CCEFifoSize = 192; break; - case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; - case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; - case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; - case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; - case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; - case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; - case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; - } - - /* Make sure the CCE is on for the X server */ - R128CCE_START(ctx, info); -} - - -static int R128MemoryInit(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - int width_bytes = ctx->shared.virtualWidth * ctx->cpp; - int cpp = ctx->cpp; - int bufferSize = ((ctx->shared.virtualHeight * width_bytes - + R128_BUFFER_ALIGN) - & ~R128_BUFFER_ALIGN); - int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes - + R128_BUFFER_ALIGN) - & ~R128_BUFFER_ALIGN); - int l; - - info->frontOffset = 0; - info->frontPitch = ctx->shared.virtualWidth; - - fprintf(stderr, - "Using %d MB AGP aperture\n", info->agpSize); - fprintf(stderr, - "Using %d MB for the ring buffer\n", info->ringSize); - fprintf(stderr, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - fprintf(stderr, - "Using %d MB for AGP textures\n", info->agpTexSize); - - /* Front, back and depth buffers - everything else texture?? - */ - info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; - - if (info->textureSize < 0) - return 0; - - l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); - if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - /* Reserve space for textures */ - info->textureOffset = ((ctx->shared.fbSize - info->textureSize + - R128_BUFFER_ALIGN) & - ~R128_BUFFER_ALIGN); - - /* Reserve space for the shared depth - * buffer. - */ - info->depthOffset = ((info->textureOffset - depthSize + - R128_BUFFER_ALIGN) & - ~R128_BUFFER_ALIGN); - info->depthPitch = ctx->shared.virtualWidth; - - info->backOffset = ((info->depthOffset - bufferSize + - R128_BUFFER_ALIGN) & - ~R128_BUFFER_ALIGN); - info->backPitch = ctx->shared.virtualWidth; - - - fprintf(stderr, - "Will use back buffer at offset 0x%x\n", - info->backOffset); - fprintf(stderr, - "Will use depth buffer at offset 0x%x\n", - info->depthOffset); - fprintf(stderr, - "Will use %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - - return 1; -} - - -/* Initialize the screen-specific data structures for the DRI and the - Rage 128. This is the main entry point to the device-specific - initialization code. It calls device-independent DRI functions to - create the DRI data structures and initialize the DRI state. */ -static GLboolean R128DRIScreenInit(DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - R128DRIPtr pR128DRI; - int err, major, minor, patch; - drmVersionPtr version; - drm_r128_sarea_t *pSAREAPriv; - - switch (ctx->bpp) { - case 8: - /* These modes are not supported (yet). */ - case 15: - case 24: - fprintf(stderr, - "[dri] R128DRIScreenInit failed (depth %d not supported). " - "[dri] Disabling DRI.\n", ctx->bpp); - return GL_FALSE; - - /* Only 16 and 32 color depths are supports currently. */ - case 16: - case 32: - break; - } - r128_drm_page_size = getpagesize(); - - info->registerSize = ctx->MMIOSize; - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("r128", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - /* Check the r128 DRM version */ - version = drmGetVersion(ctx->drmFD); - if (version) { - if (version->version_major != 2 || - version->version_minor < 2) { - /* incompatible drm version */ - fprintf(stderr, - "[dri] R128DRIScreenInit failed because of a version mismatch.\n" - "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" - "[dri] Disabling the DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel); - drmFreeVersion(version); - return GL_FALSE; - } - info->drmMinor = version->version_minor; - drmFreeVersion(version); - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - /* Need to AddMap the framebuffer and mmio regions here: - */ - if (drmAddMap( ctx->drmFD, - (drm_handle_t)ctx->FBStart, - ctx->FBSize, - DRM_FRAME_BUFFER, - 0, - &ctx->shared.hFrameBuffer) < 0) - { - fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); - return 0; - } - - fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", - ctx->shared.hFrameBuffer); - - if (!R128MemoryInit(ctx)) - return GL_FALSE; - - /* Initialize AGP */ - if (!info->IsPCI && !R128DRIAgpInit(ctx)) { - info->IsPCI = GL_TRUE; - fprintf(stderr, - "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); - fprintf(stderr, - "[agp] Make sure you have the agpgart kernel module loaded.\n"); - } - - /* Initialize PCIGART */ - if (info->IsPCI && !R128DRIPciInit(ctx)) { - return GL_FALSE; - } - - /* DRIScreenInit doesn't add all the - common mappings. Add additional - mappings here. */ - if (!R128DRIMapInit(ctx)) { - return GL_FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the kernel data structures */ - if (!R128DRIKernelInit(ctx)) { - return GL_FALSE; - } - - /* Initialize the vertex buffers list */ - if (!R128DRIBufInit(ctx)) { - return GL_FALSE; - } - - /* Initialize IRQ */ - R128DRIIrqInit(ctx); - - /* Initialize and start the CCE if required */ - R128DRICCEInit(ctx); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - drimemsetio((char *)ctx->FBAddress + info->frontOffset, - 0, - info->frontPitch * ctx->cpp * ctx->shared.virtualHeight ); - - drimemsetio((char *)ctx->FBAddress + info->backOffset, - 0, - info->backPitch * ctx->cpp * ctx->shared.virtualHeight ); - - pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - /* This is the struct passed to radeon_dri.so for its initialization */ - ctx->driverClientMsg = malloc(sizeof(R128DRIRec)); - ctx->driverClientMsgSize = sizeof(R128DRIRec); - - pR128DRI = (R128DRIPtr)ctx->driverClientMsg; - pR128DRI->deviceID = info->Chipset; - pR128DRI->width = ctx->shared.virtualWidth; - pR128DRI->height = ctx->shared.virtualHeight; - pR128DRI->depth = ctx->bpp; - pR128DRI->bpp = ctx->bpp; - - pR128DRI->IsPCI = info->IsPCI; - pR128DRI->AGPMode = info->agpMode; - - pR128DRI->frontOffset = info->frontOffset; - pR128DRI->frontPitch = info->frontPitch; - pR128DRI->backOffset = info->backOffset; - pR128DRI->backPitch = info->backPitch; - pR128DRI->depthOffset = info->depthOffset; - pR128DRI->depthPitch = info->depthPitch; - pR128DRI->spanOffset = info->spanOffset; - pR128DRI->textureOffset = info->textureOffset; - pR128DRI->textureSize = info->textureSize; - pR128DRI->log2TexGran = info->log2TexGran; - - pR128DRI->registerHandle = info->registerHandle; - pR128DRI->registerSize = info->registerSize; - - pR128DRI->agpTexHandle = info->agpTexHandle; - pR128DRI->agpTexMapSize = info->agpTexMapSize; - pR128DRI->log2AGPTexGran = info->log2AGPTexGran; - pR128DRI->agpTexOffset = info->agpTexStart; - pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - return GL_TRUE; -} - -/* The screen is being closed, so clean up any state and free any - resources used by the DRI. */ -void R128DRICloseScreen(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - drm_r128_init_t drmInfo; - - /* Stop the CCE if it is still in use */ - R128CCE_STOP(ctx, info); - - if (info->irq) { - drmCtlUninstHandler(ctx->drmFD); - info->irq = 0; - } - - /* De-allocate vertex buffers */ - if (info->buffers) { - drmUnmapBufs(info->buffers); - info->buffers = NULL; - } - - /* De-allocate all kernel resources */ - memset(&drmInfo, 0, sizeof(drmInfo)); - drmInfo.func = R128_CLEANUP_CCE; - drmCommandWrite(ctx->drmFD, DRM_R128_INIT, - &drmInfo, sizeof(drmInfo)); - - /* De-allocate all AGP resources */ - if (info->agpTex) { - drmUnmap(info->agpTex, info->agpTexMapSize); - info->agpTex = NULL; - } - if (info->buf) { - drmUnmap(info->buf, info->bufMapSize); - info->buf = NULL; - } - if (info->ringReadPtr) { - drmUnmap(info->ringReadPtr, info->ringReadMapSize); - info->ringReadPtr = NULL; - } - if (info->ring) { - drmUnmap(info->ring, info->ringMapSize); - info->ring = NULL; - } - if (info->agpMemHandle != DRM_AGP_NO_HANDLE) { - drmAgpUnbind(ctx->drmFD, info->agpMemHandle); - drmAgpFree(ctx->drmFD, info->agpMemHandle); - info->agpMemHandle = 0; - drmAgpRelease(ctx->drmFD); - } - if (info->pciMemHandle) { - drmScatterGatherFree(ctx->drmFD, info->pciMemHandle); - info->pciMemHandle = 0; - } -} - -static GLboolean R128PreInitDRI(const DRIDriverContext *ctx) -{ - R128InfoPtr info = ctx->driverPrivate; - - /*info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;*/ - info->CCEMode = R128_DEFAULT_CCE_BM_MODE; - info->CCESecure = GL_TRUE; - - info->agpMode = R128_DEFAULT_AGP_MODE; - info->agpSize = R128_DEFAULT_AGP_SIZE; - info->ringSize = R128_DEFAULT_RING_SIZE; - info->bufSize = R128_DEFAULT_BUFFER_SIZE; - info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; - - info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; - - return GL_TRUE; -} - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls R128ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int R128InitFBDev( DRIDriverContext *ctx ) -{ - R128InfoPtr info = calloc(1, sizeof(*info)); - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - } - - ctx->driverPrivate = (void *)info; - - info->Chipset = ctx->chipset; - - switch (info->Chipset) { - case PCI_DEVICE_ID_ATI_RAGE128_LE: - case PCI_DEVICE_ID_ATI_RAGE128_RE: - case PCI_DEVICE_ID_ATI_RAGE128_RK: - case PCI_DEVICE_ID_ATI_RAGE128_PD: - case PCI_DEVICE_ID_ATI_RAGE128_PP: - case PCI_DEVICE_ID_ATI_RAGE128_PR: - /* This is a PCI card */ - info->IsPCI = GL_TRUE; - break; - default: - /* This is an AGP card */ - info->IsPCI = GL_FALSE; - break; - } - - info->frontPitch = ctx->shared.virtualWidth; - info->LinearAddr = ctx->FBStart & 0xfc000000; - - if (!R128PreInitDRI(ctx)) - return 0; - - if (!R128DRIScreenInit(ctx)) - return 0; - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void R128HaltFBDev( DRIDriverContext *ctx ) -{ - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa R128PostValidateMode(). - */ -static int R128ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa R128ValidateMode(). - */ -static int R128PostValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Shutdown the drawing engine. - * - * \param ctx display handle - * - * Turns off the command processor engine & restores the graphics card - * to a state that fbdev understands. - */ -static int R128EngineShutdown( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Restore the drawing engine. - * - * \param ctx display handle - * - * Resets the graphics card and sets initial values for several registers of - * the card's drawing engine. - * - * Turns on the R128 command processor engine (i.e., the ringbuffer). - */ -static int R128EngineRestore( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - R128ValidateMode, - R128PostValidateMode, - R128InitFBDev, - R128HaltFBDev, - R128EngineShutdown, - R128EngineRestore, - 0, -}; diff --git a/src/mesa/drivers/dri/r200/server/radeon_dri.c b/src/mesa/drivers/dri/r200/server/radeon_dri.c deleted file mode 120000 index d05847d650f..00000000000 --- a/src/mesa/drivers/dri/r200/server/radeon_dri.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_dri.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/server/radeon_dri.c b/src/mesa/drivers/dri/r300/server/radeon_dri.c deleted file mode 120000 index d05847d650f..00000000000 --- a/src/mesa/drivers/dri/r300/server/radeon_dri.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_dri.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/server/radeon_dri.c b/src/mesa/drivers/dri/r600/server/radeon_dri.c deleted file mode 120000 index d05847d650f..00000000000 --- a/src/mesa/drivers/dri/r600/server/radeon_dri.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_dri.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/server/radeon_dri.c b/src/mesa/drivers/dri/radeon/server/radeon_dri.c deleted file mode 100644 index 7ead588dac8..00000000000 --- a/src/mesa/drivers/dri/radeon/server/radeon_dri.c +++ /dev/null @@ -1,1337 +0,0 @@ -/** - * \file server/radeon_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - */ - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" -#include "memops.h" - -#include "radeon.h" -#include "radeon_dri.h" -#include "radeon_macros.h" -#include "radeon_reg.h" -#include "drm_sarea.h" - -static size_t radeon_drm_page_size; - -static int RadeonSetParam(const DRIDriverContext *ctx, int param, int value) -{ - drm_radeon_setparam_t sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_RADEON_SETPARAM, &sp, sizeof(sp))) { - return -1; - } - - return 0; -} - -/** - * \brief Wait for free FIFO entries. - * - * \param ctx display handle. - * \param entries number of free entries to wait. - * - * It polls the free entries from the chip until it reaches the requested value - * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out. - */ -static void RADEONWaitForFifo( const DRIDriverContext *ctx, - int entries ) -{ - unsigned char *RADEONMMIO = ctx->MMIOAddress; - int i; - - for (i = 0; i < 3000; i++) { - int fifo_slots = - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; - if (fifo_slots >= entries) return; - } - - /* There are recoveries possible, but I haven't seen them work - * in practice: - */ - fprintf(stderr, "FIFO timed out: %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS)); - exit(1); -} - -/** - * \brief Read a PLL register. - * - * \param ctx display handle. - * \param addr PLL register index. - * - * \return value of the PLL register. - */ -static unsigned int RADEONINPLL( const DRIDriverContext *ctx, int addr) -{ - unsigned char *RADEONMMIO = ctx->MMIOAddress; - unsigned int data; - - OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); - data = INREG(RADEON_CLOCK_CNTL_DATA); - - return data; -} - -/** - * \brief Reset graphics card to known state. - * - * \param ctx display handle. - * - * Resets the values of several Radeon registers. - */ -static void RADEONEngineReset( const DRIDriverContext *ctx ) -{ - unsigned char *RADEONMMIO = ctx->MMIOAddress; - unsigned int clock_cntl_index; - unsigned int mclk_cntl; - unsigned int rbbm_soft_reset; - unsigned int host_path_cntl; - int i; - - OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT, - RADEON_RB2D_DC_FLUSH_ALL, - ~RADEON_RB2D_DC_FLUSH_ALL); - for (i = 0; i < 512; i++) { - if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY)) - break; - } - - clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); - - mclk_cntl = INPLL(ctx, RADEON_MCLK_CNTL); - OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | - RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC | - RADEON_FORCEON_AIC)); - - /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some - * unexpected behaviour on some machines. Here we use - * RADEON_HOST_PATH_CNTL to reset it. - */ - host_path_cntl = INREG(RADEON_HOST_PATH_CNTL); - rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); - - OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | - RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB)); - INREG(RADEON_RBBM_SOFT_RESET); - OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & - (unsigned int) ~(RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB))); - INREG(RADEON_RBBM_SOFT_RESET); - - OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET); - INREG(RADEON_HOST_PATH_CNTL); - OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl); - - OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); - - OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); - OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); -} - -/** - * \brief Restore the drawing engine. - * - * \param ctx display handle - * - * Resets the graphics card and sets initial values for several registers of - * the card's drawing engine. - * - * Turns on the radeon command processor engine (i.e., the ringbuffer). - */ -static int RADEONEngineRestore( const DRIDriverContext *ctx ) -{ - RADEONInfoPtr info = ctx->driverPrivate; - unsigned char *RADEONMMIO = ctx->MMIOAddress; - int pitch64, datatype, dp_gui_master_cntl, err; - - fprintf(stderr, "%s\n", __FUNCTION__); - - OUTREG(RADEON_RB3D_CNTL, 0); - RADEONEngineReset( ctx ); - - switch (ctx->bpp) { - case 16: datatype = 4; break; - case 32: datatype = 6; break; - default: return 0; - } - - dp_gui_master_cntl = - ((datatype << RADEON_GMC_DST_DATATYPE_SHIFT) - | RADEON_GMC_CLR_CMP_CNTL_DIS); - - pitch64 = ((ctx->shared.virtualWidth * (ctx->bpp / 8) + 0x3f)) >> 6; - - RADEONWaitForFifo(ctx, 1); - OUTREG(RADEON_DEFAULT_OFFSET, ((INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000) - | (pitch64 << 22))); - - RADEONWaitForFifo(ctx, 1); - OUTREG(RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS); - - RADEONWaitForFifo(ctx, 1); - OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX - | RADEON_DEFAULT_SC_BOTTOM_MAX)); - - RADEONWaitForFifo(ctx, 1); - OUTREG(RADEON_DP_GUI_MASTER_CNTL, (dp_gui_master_cntl - | RADEON_GMC_BRUSH_SOLID_COLOR - | RADEON_GMC_SRC_DATATYPE_COLOR)); - - RADEONWaitForFifo(ctx, 7); - OUTREG(RADEON_DST_LINE_START, 0); - OUTREG(RADEON_DST_LINE_END, 0); - OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); - OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0); - OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff); - OUTREG(RADEON_DP_SRC_BKGD_CLR, 0); - OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff); - OUTREG(RADEON_AUX_SC_CNTL, 0); - -/* RADEONWaitForIdleMMIO(ctx); */ - usleep(100); - - - OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl); - if (info->colorTiling) - info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN; - OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl); - - /* Initialize and start the CP if required */ - if ((err = drmCommandNone(ctx->drmFD, DRM_RADEON_CP_START)) != 0) { - fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err); - return 0; - } - - return 1; -} - - -/** - * \brief Shutdown the drawing engine. - * - * \param ctx display handle - * - * Turns off the command processor engine & restores the graphics card - * to a state that fbdev understands. - */ -static int RADEONEngineShutdown( const DRIDriverContext *ctx ) -{ - drm_radeon_cp_stop_t stop; - int ret, i; - - stop.flush = 1; - stop.idle = 1; - - ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop, - sizeof(drm_radeon_cp_stop_t)); - - if (ret == 0) { - return 0; - } else if (errno != EBUSY) { - return -errno; - } - - stop.flush = 0; - - i = 0; - do { - ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop, - sizeof(drm_radeon_cp_stop_t)); - } while (ret && errno == EBUSY && i++ < 10); - - if (ret == 0) { - return 0; - } else if (errno != EBUSY) { - return -errno; - } - - stop.idle = 0; - - if (drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, - &stop, sizeof(drm_radeon_cp_stop_t))) { - return -errno; - } else { - return 0; - } -} - -/** - * \brief Compute base 2 logarithm. - * - * \param val value. - * - * \return base 2 logarithm of \p val. - */ -static int RADEONMinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - -/** - * \brief Initialize the AGP state - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Acquires and enables the AGP device. Reserves memory in the AGP space for - * the ring buffer, vertex buffers and textures. Initialize the Radeon - * registers to point to that memory and add client mappings. - */ -static int RADEONDRIAgpInit( const DRIDriverContext *ctx, RADEONInfoPtr info) -{ - unsigned char *RADEONMMIO = ctx->MMIOAddress; - unsigned long mode; - int ret; - int s, l; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - /* Modify the mode if the default mode is not appropriate for this - * particular combination of graphics card and AGP chipset. - */ - mode = drmAgpGetMode(ctx->drmFD); /* Default mode */ - - /* Disable fast write entirely - too many lockups. - */ - mode &= ~RADEON_AGP_MODE_MASK; - switch (ctx->agpmode) { - case 4: mode |= RADEON_AGP_4X_MODE; - case 2: mode |= RADEON_AGP_2X_MODE; - case 1: default: mode |= RADEON_AGP_1X_MODE; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - /* Workaround for some hardware bugs */ - if (info->ChipFamily < CHIP_FAMILY_R200) - OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000); - - info->gartOffset = 0; - - if ((ret = drmAgpAlloc(ctx->drmFD, info->gartSize*1024*1024, 0, NULL, - &info->gartMemHandle)) < 0) { - fprintf(stderr, "[gart] Out of memory (%d)\n", ret); - drmAgpRelease(ctx->drmFD); - return 0; - } - fprintf(stderr, - "[gart] %d kB allocated with handle 0x%08x\n", - info->gartSize*1024, (unsigned)info->gartMemHandle); - - if (drmAgpBind(ctx->drmFD, - info->gartMemHandle, info->gartOffset) < 0) { - fprintf(stderr, "[gart] Could not bind\n"); - drmAgpFree(ctx->drmFD, info->gartMemHandle); - drmAgpRelease(ctx->drmFD); - return 0; - } - - /* Initialize the CP ring buffer data */ - info->ringStart = info->gartOffset; - info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->gartTexStart = info->bufStart + info->bufMapSize; - s = (info->gartSize*1024*1024 - info->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->gartTexMapSize = (s >> l) << l; - info->log2GARTTexGran = l; - - if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) { - fprintf(stderr, "[gart] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, "[gart] ring handle = 0x%08x\n", info->ringHandle); - - - if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[gart] Could not add ring read ptr mapping\n"); - return 0; - } - - fprintf(stderr, - "[gart] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, - DRM_AGP, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[gart] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] vertex/indirect buffers handle = 0x%08x\n", - info->bufHandle); - - if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_AGP, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[gart] Could not add AGP texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] AGP texture map handle = 0x%08lx\n", - info->gartTexHandle); - - /* Initialize Radeon's AGP registers */ - /* Ring buffer is at AGP offset 0 */ - OUTREG(RADEON_AGP_BASE, info->ringHandle); - - return 1; -} - -/* Initialize the PCI GART state. Request memory for use in PCI space, - * and initialize the Radeon registers to point to that memory. - */ -static int RADEONDRIPciInit(const DRIDriverContext *ctx, RADEONInfoPtr info) -{ - int ret; - int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; - int s, l; - - ret = drmScatterGatherAlloc(ctx->drmFD, info->gartSize*1024*1024, - &info->gartMemHandle); - if (ret < 0) { - fprintf(stderr, "[pci] Out of memory (%d)\n", ret); - return 0; - } - fprintf(stderr, - "[pci] %d kB allocated with handle 0x%08lx\n", - info->gartSize*1024, info->gartMemHandle); - - info->gartOffset = 0; - - /* Initialize the CP ring buffer data */ - info->ringStart = info->gartOffset; - info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->gartTexStart = info->bufStart + info->bufMapSize; - s = (info->gartSize*1024*1024 - info->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->gartTexMapSize = (s >> l) << l; - info->log2GARTTexGran = l; - - if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, - DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] ring handle = 0x%08x\n", info->ringHandle); - - if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring read ptr mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, - DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[pci] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[pci] Could not add GART texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] GART texture map handle = 0x%08x\n", - info->gartTexHandle); - - return 1; -} - - -/** - * \brief Initialize the kernel data structures and enable the CP engine. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing - * all the parameters in a drm_radeon_init_t structure. - */ -static int RADEONDRIKernelInit( const DRIDriverContext *ctx, - RADEONInfoPtr info) -{ - int cpp = ctx->bpp / 8; - drm_radeon_init_t drmInfo; - int ret; - - memset(&drmInfo, 0, sizeof(drm_radeon_init_t)); - - if ( (info->ChipFamily == CHIP_FAMILY_R200) || - (info->ChipFamily == CHIP_FAMILY_RV250) || - (info->ChipFamily == CHIP_FAMILY_M9) || - (info->ChipFamily == CHIP_FAMILY_RV280) ) - drmInfo.func = RADEON_INIT_R200_CP; - else - drmInfo.func = RADEON_INIT_CP; - - /* This is the struct passed to the kernel module for its initialization */ - drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); - drmInfo.is_pci = ctx->isPCI; - drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE; - drmInfo.gart_size = info->gartSize*1024*1024; - drmInfo.ring_size = info->ringSize*1024*1024; - drmInfo.usec_timeout = 1000; - drmInfo.fb_bpp = ctx->bpp; - drmInfo.depth_bpp = ctx->bpp; - drmInfo.front_offset = info->frontOffset; - drmInfo.front_pitch = info->frontPitch * cpp; - drmInfo.back_offset = info->backOffset; - drmInfo.back_pitch = info->backPitch * cpp; - drmInfo.depth_offset = info->depthOffset; - drmInfo.depth_pitch = info->depthPitch * cpp; - drmInfo.fb_offset = info->LinearAddr; - drmInfo.mmio_offset = info->registerHandle; - drmInfo.ring_offset = info->ringHandle; - drmInfo.ring_rptr_offset = info->ringReadPtrHandle; - drmInfo.buffers_offset = info->bufHandle; - drmInfo.gart_textures_offset = info->gartTexHandle; - - ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_INIT, &drmInfo, - sizeof(drm_radeon_init_t)); - - return ret >= 0; -} - - -/** - * \brief Initialize the AGP heap. - * - * \param ctx display handle. - * \param info driver private data. - * - * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing - * all the parameters in a drm_radeon_mem_init_heap structure. - */ -static void RADEONDRIAgpHeapInit(const DRIDriverContext *ctx, - RADEONInfoPtr info) -{ - drm_radeon_mem_init_heap_t drmHeap; - - /* Start up the simple memory manager for gart space */ - drmHeap.region = RADEON_MEM_REGION_GART; - drmHeap.start = 0; - drmHeap.size = info->gartTexMapSize; - - if (drmCommandWrite(ctx->drmFD, DRM_RADEON_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - fprintf(stderr, - "[drm] Failed to initialized gart heap manager\n"); - } else { - fprintf(stderr, - "[drm] Initialized kernel gart heap manager, %d\n", - info->gartTexMapSize); - } -} - -/** - * \brief Add a map for the vertex buffers that will be accessed by any - * DRI-based clients. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Calls drmAddBufs() with the previously allocated vertex buffers. - */ -static int RADEONDRIBufInit( const DRIDriverContext *ctx, RADEONInfoPtr info ) -{ - /* Initialize vertex buffers */ - info->bufNumBufs = drmAddBufs(ctx->drmFD, - info->bufMapSize / RADEON_BUFFER_SIZE, - RADEON_BUFFER_SIZE, - ctx->isPCI ? DRM_SG_BUFFER : DRM_AGP_BUFFER, - info->bufStart); - - if (info->bufNumBufs <= 0) { - fprintf(stderr, - "[drm] Could not create vertex/indirect buffers list\n"); - return 0; - } - fprintf(stderr, - "[drm] Added %d %d byte vertex/indirect buffers\n", - info->bufNumBufs, RADEON_BUFFER_SIZE); - - return 1; -} - -/** - * \brief Install an IRQ handler. - * - * \param ctx display handle. - * \param info driver private data. - * - * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to - * IRQ-free operation on failure. - */ -static void RADEONDRIIrqInit(const DRIDriverContext *ctx, - RADEONInfoPtr info) -{ - if (!info->irq) { - info->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) { - fprintf(stderr, - "[drm] failure adding irq handler, " - "there is a device already using that irq\n" - "[drm] falling back to irq-free operation\n"); - info->irq = 0; - } - } - - if (info->irq) - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - info->irq); -} - -static int RADEONCheckDRMVersion( const DRIDriverContext *ctx, - RADEONInfoPtr info ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - if (version) { - int req_minor, req_patch; - - /* Need 1.8.x for proper cleanup-on-client-exit behaviour. - */ - req_minor = 8; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] RADEONDRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] radeon.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - info->drmMinor = version->version_minor; - drmFreeVersion(version); - } - - return 1; -} - -static int RADEONMemoryInit( const DRIDriverContext *ctx, RADEONInfoPtr info ) -{ - int width_bytes = ctx->shared.virtualWidth * ctx->cpp; - int cpp = ctx->cpp; - int bufferSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); - int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes - + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); - int l; - - info->frontOffset = 0; - info->frontPitch = ctx->shared.virtualWidth; - - fprintf(stderr, - "Using %d MB AGP aperture\n", info->gartSize); - fprintf(stderr, - "Using %d MB for the ring buffer\n", info->ringSize); - fprintf(stderr, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - fprintf(stderr, - "Using %d MB for AGP textures\n", info->gartTexSize); - - /* Front, back and depth buffers - everything else texture?? - */ - info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; - - if (ctx->colorTiling==1) - { - info->textureSize = ctx->shared.fbSize - ((ctx->shared.fbSize - info->textureSize + width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes*16); - } - - if (info->textureSize < 0) - return 0; - - l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - /* Reserve space for textures */ - if (ctx->colorTiling==1) - { - info->textureOffset = ((ctx->shared.fbSize - info->textureSize) / - (width_bytes * 16)) * (width_bytes*16); - } - else - { - info->textureOffset = ((ctx->shared.fbSize - info->textureSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - } - /* Reserve space for the shared depth - * buffer. - */ - info->depthOffset = ((info->textureOffset - depthSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - info->depthPitch = ctx->shared.virtualWidth; - - info->backOffset = ((info->depthOffset - bufferSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - info->backPitch = ctx->shared.virtualWidth; - - - fprintf(stderr, - "Will use back buffer at offset 0x%x\n", - info->backOffset); - fprintf(stderr, - "Will use depth buffer at offset 0x%x\n", - info->depthOffset); - fprintf(stderr, - "Will use %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - - info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | - (info->frontOffset >> 10)); - - info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | - (info->backOffset >> 10)); - - info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | - (info->depthOffset >> 10)); - - return 1; -} - -static int RADEONColorTilingInit( const DRIDriverContext *ctx, RADEONInfoPtr info ) -{ - int width_bytes = ctx->shared.virtualWidth * ctx->cpp; - int bufferSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - /* Setup color tiling */ - if (info->drmMinor<14) - info->colorTiling=0; - - if (info->colorTiling) - { - - int colorTilingFlag; - drm_radeon_surface_alloc_t front,back; - - RadeonSetParam(ctx, RADEON_SETPARAM_SWITCH_TILING, info->colorTiling ? 1 : 0); - - /* Setup the surfaces */ - if (info->ChipFamily < CHIP_FAMILY_R200) - colorTilingFlag=RADEON_SURF_TILE_COLOR_MACRO; - else - colorTilingFlag=R200_SURF_TILE_COLOR_MACRO; - - front.address = info->frontOffset; - front.size = bufferSize; - front.flags = (width_bytes) | colorTilingFlag; - drmCommandWrite(ctx->drmFD, DRM_RADEON_SURF_ALLOC, &front,sizeof(front)); - - back.address = info->backOffset; - back.size = bufferSize; - back.flags = (width_bytes) | colorTilingFlag; - drmCommandWrite(ctx->drmFD, DRM_RADEON_SURF_ALLOC, &back,sizeof(back)); - - } - return 1; -} - - - -/** - * Called at the start of each server generation. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Performs static frame buffer allocation. Opens the DRM device and add maps - * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more - * information. Creates a \e server context to grab the lock for the - * initialization ioctls and calls the other initilization functions in this - * file. Starts the CP engine via the DRM_RADEON_CP_START command. - * - * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its - * initialization. - */ -static int RADEONScreenInit( DRIDriverContext *ctx, RADEONInfoPtr info ) -{ - RADEONDRIPtr pRADEONDRI; - int err; - - usleep(100); - /*assert(!ctx->IsClient);*/ - - { - int width_bytes = (ctx->shared.virtualWidth * ctx->cpp); - int maxy = ctx->shared.fbSize / width_bytes; - - - if (maxy <= ctx->shared.virtualHeight * 3) { - fprintf(stderr, - "Static buffer allocation failed -- " - "need at least %d kB video memory (have %d kB)\n", - (ctx->shared.virtualWidth * ctx->shared.virtualHeight * - ctx->cpp * 3 + 1023) / 1024, - ctx->shared.fbSize / 1024); - return 0; - } - } - - - if (info->ChipFamily >= CHIP_FAMILY_R300) { - fprintf(stderr, - "Direct rendering not yet supported on " - "Radeon 9700 and newer cards\n"); - return 0; - } - - radeon_drm_page_size = getpagesize(); - - info->registerSize = ctx->MMIOSize; - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("radeon", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - /* Need to AddMap the framebuffer and mmio regions here: - */ - if (drmAddMap( ctx->drmFD, - (drm_handle_t)ctx->FBStart, - ctx->FBSize, - DRM_FRAME_BUFFER, -#ifndef _EMBEDDED - 0, -#else - DRM_READ_ONLY, -#endif - &ctx->shared.hFrameBuffer) < 0) - { - fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); - return 0; - } - - fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", - ctx->shared.hFrameBuffer); - - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &info->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08lx\n", info->registerHandle); - - /* Check the radeon DRM version */ - if (!RADEONCheckDRMVersion(ctx, info)) { - return 0; - } - - if (ctx->isPCI) { - /* Initialize PCI */ - if (!RADEONDRIPciInit(ctx, info)) - return 0; - } - else { - /* Initialize AGP */ - if (!RADEONDRIAgpInit(ctx, info)) - return 0; - } - - /* Memory manager setup */ - if (!RADEONMemoryInit(ctx, info)) { - return 0; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the kernel data structures */ - if (!RADEONDRIKernelInit(ctx, info)) { - fprintf(stderr, "RADEONDRIKernelInit failed\n"); - DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); - return 0; - } - - /* Initialize the vertex buffers list */ - if (!RADEONDRIBufInit(ctx, info)) { - fprintf(stderr, "RADEONDRIBufInit failed\n"); - DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); - return 0; - } - - RADEONColorTilingInit(ctx, info); - - /* Initialize IRQ */ - RADEONDRIIrqInit(ctx, info); - - /* Initialize kernel gart memory manager */ - RADEONDRIAgpHeapInit(ctx, info); - - fprintf(stderr,"color tiling %sabled\n", info->colorTiling?"en":"dis"); - fprintf(stderr,"page flipping %sabled\n", info->page_flip_enable?"en":"dis"); - /* Initialize the SAREA private data structure */ - { - drm_radeon_sarea_t *pSAREAPriv; - pSAREAPriv = (drm_radeon_sarea_t *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - pSAREAPriv->pfState = info->page_flip_enable; - } - - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - drimemsetio((char *)ctx->FBAddress + info->frontOffset, - 0, - info->frontPitch * ctx->cpp * ctx->shared.virtualHeight ); - - drimemsetio((char *)ctx->FBAddress + info->backOffset, - 0, - info->backPitch * ctx->cpp * ctx->shared.virtualHeight ); - - /* This is the struct passed to radeon_dri.so for its initialization */ - ctx->driverClientMsg = malloc(sizeof(RADEONDRIRec)); - ctx->driverClientMsgSize = sizeof(RADEONDRIRec); - pRADEONDRI = (RADEONDRIPtr)ctx->driverClientMsg; - pRADEONDRI->deviceID = info->Chipset; - pRADEONDRI->width = ctx->shared.virtualWidth; - pRADEONDRI->height = ctx->shared.virtualHeight; - pRADEONDRI->depth = ctx->bpp; /* XXX: depth */ - pRADEONDRI->bpp = ctx->bpp; - pRADEONDRI->IsPCI = ctx->isPCI; - pRADEONDRI->AGPMode = ctx->agpmode; - pRADEONDRI->frontOffset = info->frontOffset; - pRADEONDRI->frontPitch = info->frontPitch; - pRADEONDRI->backOffset = info->backOffset; - pRADEONDRI->backPitch = info->backPitch; - pRADEONDRI->depthOffset = info->depthOffset; - pRADEONDRI->depthPitch = info->depthPitch; - pRADEONDRI->textureOffset = info->textureOffset; - pRADEONDRI->textureSize = info->textureSize; - pRADEONDRI->log2TexGran = info->log2TexGran; - pRADEONDRI->registerHandle = info->registerHandle; - pRADEONDRI->registerSize = info->registerSize; - pRADEONDRI->statusHandle = info->ringReadPtrHandle; - pRADEONDRI->statusSize = info->ringReadMapSize; - pRADEONDRI->gartTexHandle = info->gartTexHandle; - pRADEONDRI->gartTexMapSize = info->gartTexMapSize; - pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran; - pRADEONDRI->gartTexOffset = info->gartTexStart; - pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t); - - /* Don't release the lock now - let the VT switch handler do it. */ - - return 1; -} - - -/** - * \brief Get Radeon chip family from chipset number. - * - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily - * according to the value of RADEONInfoRec::Chipset. Fails if the - * chipset is unrecognized or not appropriate for this driver (i.e., not - * an r100 style radeon) - */ -static int get_chipfamily_from_chipset( RADEONInfoPtr info ) -{ - switch (info->Chipset) { - case PCI_CHIP_RADEON_LY: - case PCI_CHIP_RADEON_LZ: - info->ChipFamily = CHIP_FAMILY_M6; - break; - - case PCI_CHIP_RADEON_QY: - case PCI_CHIP_RADEON_QZ: - info->ChipFamily = CHIP_FAMILY_VE; - break; - - case PCI_CHIP_R200_QL: - case PCI_CHIP_R200_QN: - case PCI_CHIP_R200_QO: - case PCI_CHIP_R200_Ql: - case PCI_CHIP_R200_BB: - info->ChipFamily = CHIP_FAMILY_R200; - break; - - case PCI_CHIP_RV200_QW: /* RV200 desktop */ - case PCI_CHIP_RV200_QX: - info->ChipFamily = CHIP_FAMILY_RV200; - break; - - case PCI_CHIP_RADEON_LW: - case PCI_CHIP_RADEON_LX: - info->ChipFamily = CHIP_FAMILY_M7; - break; - - case PCI_CHIP_RV250_Id: - case PCI_CHIP_RV250_Ie: - case PCI_CHIP_RV250_If: - case PCI_CHIP_RV250_Ig: - info->ChipFamily = CHIP_FAMILY_RV250; - break; - - case PCI_CHIP_RV250_Ld: - case PCI_CHIP_RV250_Le: - case PCI_CHIP_RV250_Lf: - case PCI_CHIP_RV250_Lg: - info->ChipFamily = CHIP_FAMILY_M9; - break; - - case PCI_CHIP_RV280_Y_: - case PCI_CHIP_RV280_Ya: - case PCI_CHIP_RV280_Yb: - case PCI_CHIP_RV280_Yc: - info->ChipFamily = CHIP_FAMILY_RV280; - break; - - case PCI_CHIP_R300_ND: - case PCI_CHIP_R300_NE: - case PCI_CHIP_R300_NF: - case PCI_CHIP_R300_NG: - info->ChipFamily = CHIP_FAMILY_R300; - break; - - default: - /* Original Radeon/7200 */ - info->ChipFamily = CHIP_FAMILY_RADEON; - } - - return 1; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int radeonValidateMode( const DRIDriverContext *ctx ) -{ - unsigned char *RADEONMMIO = ctx->MMIOAddress; - RADEONInfoPtr info = ctx->driverPrivate; - - info->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL); - info->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); - - if (info->colorTiling) - info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN; - return 1; -} - - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa radeonValidateMode(). - */ -static int radeonPostValidateMode( const DRIDriverContext *ctx ) -{ - unsigned char *RADEONMMIO = ctx->MMIOAddress; - RADEONInfoPtr info = ctx->driverPrivate; - - RADEONColorTilingInit( ctx, info); - OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl); - if (info->colorTiling) - info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN; - OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl); - - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls RADEONScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int radeonInitFBDev( DRIDriverContext *ctx ) -{ - RADEONInfoPtr info = calloc(1, sizeof(*info)); - - { - int dummy = ctx->shared.virtualWidth; - - if (ctx->colorTiling==1) - { - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 255) & ~255; break; - case 2: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 63) & ~63; break; - } - } else { - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = dummy; - } - - fprintf(stderr,"shared virtual width is %d\n", ctx->shared.virtualWidth); - ctx->driverPrivate = (void *)info; - - info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE; - info->gartSize = RADEON_DEFAULT_AGP_SIZE; - info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; - info->bufSize = RADEON_DEFAULT_BUFFER_SIZE; - info->ringSize = RADEON_DEFAULT_RING_SIZE; - info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP; - info->colorTiling = ctx->colorTiling; - - info->Chipset = ctx->chipset; - - if (!get_chipfamily_from_chipset( info )) { - fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n"); - fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n"); - return 0; - } - - info->frontPitch = ctx->shared.virtualWidth; - info->LinearAddr = ctx->FBStart & 0xfc000000; - - - if (!RADEONScreenInit( ctx, info )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void radeonHaltFBDev( DRIDriverContext *ctx ) -{ - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void radeonNotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - radeonValidateMode, - radeonPostValidateMode, - radeonInitFBDev, - radeonHaltFBDev, - RADEONEngineShutdown, - RADEONEngineRestore, -#ifndef _EMBEDDED - 0, -#else - radeonNotifyFocus, -#endif -}; diff --git a/src/mesa/drivers/dri/tdfx/server/tdfx_dri.c b/src/mesa/drivers/dri/tdfx/server/tdfx_dri.c deleted file mode 100644 index 63fe875f59e..00000000000 --- a/src/mesa/drivers/dri/tdfx/server/tdfx_dri.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul 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 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 - * BRIAN PAUL 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 - * Daniel Borca - */ - - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" -#include "imports.h" - -#include "dri_util.h" - -#include "tdfx_context.h" -#include "tdfx_dri.h" -#include "xf86drm.h" - - -#define TILE_WIDTH 128 -#define TILE_HEIGHT 32 - -#define CMDFIFO_PAGES 64 - - -static int -calcBufferStride (int xres, int tiled, int cpp) -{ - int strideInTiles; - - if (tiled) { - /* Calculate tile width stuff */ - strideInTiles = (xres+TILE_WIDTH-1)/TILE_WIDTH; - - return strideInTiles*cpp*TILE_WIDTH; - } else { - return xres*cpp; - } -} /* calcBufferStride */ - - -static int -calcBufferHeightInTiles (int yres) -{ - int heightInTiles; /* Height of buffer in tiles */ - - /* Calculate tile height stuff */ - heightInTiles = yres >> 5; - - if (yres & (TILE_HEIGHT - 1)) - heightInTiles++; - - return heightInTiles; - -} /* calcBufferHeightInTiles */ - - -static int -calcBufferSize (int xres, int yres, int tiled, int cpp) -{ - int stride, height, bufSize; - - if (tiled) { - stride = calcBufferStride(xres, tiled, cpp); - height = TILE_HEIGHT * calcBufferHeightInTiles(yres); - } else { - stride = xres*cpp; - height = yres; - } - - bufSize = stride * height; - - return bufSize; -} /* calcBufferSize */ - - -static void allocateMemory (const DRIDriverContext *ctx, TDFXDRIPtr pTDFX) -{ - int memRemaining, fifoSize, screenSizeInTiles; - int fbSize; - char *str; - int pixmapCacheLinesMin; - int cursorOffset, cursorSize; - - pTDFX->stride = calcBufferStride(pTDFX->width, !0, pTDFX->cpp); - - /* enough to do DVD */ - pixmapCacheLinesMin = ((720*480*pTDFX->cpp) + - pTDFX->stride - 1)/pTDFX->stride; - - if (pTDFX->deviceID > PCI_CHIP_VOODOO3) { - if ((pixmapCacheLinesMin + pTDFX->height) > 4095) - pixmapCacheLinesMin = 4095 - pTDFX->height; - } else { - if ((pixmapCacheLinesMin + pTDFX->height) > 2047) - pixmapCacheLinesMin = 2047 - pTDFX->height; - } - - if (pTDFX->cpp!=3) { - screenSizeInTiles=calcBufferSize(pTDFX->width, pTDFX->height, - !0, pTDFX->cpp); - } - else { - /* cpp==3 needs to bump up to 4 */ - screenSizeInTiles=calcBufferSize(pTDFX->width, pTDFX->height, - !0, 4); - } - - /* - * Layout is: - * cursor, fifo, fb, tex, bb, db - */ - - fbSize = (pTDFX->height + pixmapCacheLinesMin) * pTDFX->stride; - - memRemaining=(pTDFX->mem - 1) &~ 0xFFF; - /* Note that a page is 4096 bytes, and a */ - /* tile is 32 x 128 = 4096 bytes. So, */ - /* page and tile boundaries are the same */ - /* Place the depth offset first, forcing */ - /* it to be on an *odd* page boundary. */ - pTDFX->depthOffset = (memRemaining - screenSizeInTiles) &~ 0xFFF; - if ((pTDFX->depthOffset & (0x1 << 12)) == 0) { - pTDFX->depthOffset -= (0x1 << 12); - } - /* Now, place the back buffer, forcing it */ - /* to be on an *even* page boundary. */ - pTDFX->backOffset = (pTDFX->depthOffset - screenSizeInTiles) &~ 0xFFF; - if (pTDFX->backOffset & (0x1 << 12)) { - pTDFX->backOffset -= (0x1 << 12); - } - /* Give the cmd fifo at least */ - /* CMDFIFO_PAGES pages, but no more than */ - /* 64. NOTE: Don't go higher than 64, as */ - /* there is suspect code in Glide3 ! */ - fifoSize = ((64 <= CMDFIFO_PAGES) ? 64 : CMDFIFO_PAGES) << 12; - - /* We give 4096 bytes to the cursor */ - cursorSize = 0/*4096*/; - cursorOffset = 0; - - pTDFX->fifoOffset = cursorOffset + cursorSize; - pTDFX->fifoSize = fifoSize; - /* Now, place the front buffer, forcing */ - /* it to be on a page boundary too, just */ - /* for giggles. */ - pTDFX->fbOffset = pTDFX->fifoOffset + pTDFX->fifoSize; - pTDFX->textureOffset = pTDFX->fbOffset + fbSize; - if (pTDFX->depthOffset <= pTDFX->textureOffset || - pTDFX->backOffset <= pTDFX->textureOffset) { - /* - * pTDFX->textureSize < 0 means that the DRI is disabled. pTDFX->backOffset - * is used to calculate the maximum amount of memory available for - * 2D offscreen use. With DRI disabled, set this to the top of memory. - */ - - pTDFX->textureSize = -1; - pTDFX->backOffset = pTDFX->mem; - pTDFX->depthOffset = -1; - fprintf(stderr, - "Not enough video memory available for textures and depth buffer\n" - "\tand/or back buffer. Disabling DRI. To use DRI try lower\n" - "\tresolution modes and/or a smaller virtual screen size\n"); - } else { - pTDFX->textureSize = pTDFX->backOffset - pTDFX->textureOffset; - } -} - - -static int createScreen (DRIDriverContext *ctx, TDFXDRIPtr pTDFX) -{ - int err; - - { - int width_bytes = (ctx->shared.virtualWidth * ctx->cpp); - int maxy = ctx->shared.fbSize / width_bytes; - - - if (maxy <= ctx->shared.virtualHeight * 3) { - fprintf(stderr, - "Static buffer allocation failed -- " - "need at least %d kB video memory (have %d kB)\n", - (ctx->shared.virtualWidth * ctx->shared.virtualHeight * - ctx->cpp * 3 + 1023) / 1024, - ctx->shared.fbSize / 1024); - return 0; - } - } - - ctx->shared.SAREASize = SAREA_MAX; - pTDFX->regsSize = ctx->MMIOSize; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("tdfx", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - /* Need to AddMap the framebuffer and mmio regions here: - */ - if (drmAddMap( ctx->drmFD, - (drm_handle_t)ctx->FBStart, - ctx->FBSize, - DRM_FRAME_BUFFER, -#ifndef _EMBEDDED - 0, -#else - DRM_READ_ONLY, -#endif - &ctx->shared.hFrameBuffer) < 0) - { - fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); - return 0; - } - - fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", - ctx->shared.hFrameBuffer); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pTDFX->regs) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08lx\n", pTDFX->regs); - - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the kernel data structures */ - - /* Initialize kernel gart memory manager */ - allocateMemory(ctx, pTDFX); - - /* Initialize the SAREA private data structure */ - - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - - - /* This is the struct passed to tdfx_dri.so for its initialization */ - ctx->driverClientMsg = malloc(sizeof(TDFXDRIRec)); - ctx->driverClientMsgSize = sizeof(TDFXDRIRec); - memcpy(ctx->driverClientMsg, pTDFX, ctx->driverClientMsgSize); - pTDFX = (TDFXDRIPtr)ctx->driverClientMsg; - - /* Don't release the lock now - let the VT switch handler do it. */ - - return 1; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa tdfxValidateMode(). - */ -static int tdfxValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa tdfxValidateMode(). - */ -static int tdfxPostValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int tdfxInitFBDev( DRIDriverContext *ctx ) -{ - TDFXDRIPtr pTDFX = calloc(1, sizeof(TDFXDRIRec)); - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - } - - ctx->driverPrivate = (void *)pTDFX; - - pTDFX->deviceID = ctx->chipset; - pTDFX->width = ctx->shared.virtualWidth; - pTDFX->height = ctx->shared.virtualHeight; - pTDFX->cpp = ctx->cpp; - pTDFX->mem = ctx->FBSize; /* ->shared.fbSize? mem probe? */ - pTDFX->sarea_priv_offset = sizeof(drm_sarea_t); - - if (!createScreen(ctx, pTDFX)) - return 0; - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void tdfxHaltFBDev( DRIDriverContext *ctx ) -{ - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -/** - * \brief Shutdown the drawing engine. - * - * \param ctx display handle - * - * Turns off the 3D engine & restores the graphics card - * to a state that fbdev understands. - */ -static int tdfxEngineShutdown( const DRIDriverContext *ctx ) -{ - fprintf(stderr, "%s: not implemented\n", __FUNCTION__); - return 1; -} - - -/** - * \brief Restore the drawing engine. - * - * \param ctx display handle - * - * Resets the graphics card and sets initial values for several registers of - * the card's drawing engine. - * - * Turns on 3dfx - */ -static int tdfxEngineRestore( const DRIDriverContext *ctx ) -{ - fprintf(stderr, "%s: not implemented\n", __FUNCTION__); - return 1; -} - - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -struct DRIDriverRec __driDriver = { - tdfxValidateMode, - tdfxPostValidateMode, - tdfxInitFBDev, - tdfxHaltFBDev, - tdfxEngineShutdown, - tdfxEngineRestore, - 0 -}; diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c deleted file mode 100644 index 74034485e28..00000000000 --- a/src/mesa/drivers/dri/unichrome/server/via_dri.c +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. - * Copyright 2001-2003 S3 Graphics, 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 - * VIA, S3 GRAPHICS, 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 -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" -#include "imports.h" - -#include "dri_util.h" - -#include "via_context.h" -#include "via_dri.h" -#include "via_driver.h" -#include "xf86drm.h" - -static void VIAEnableMMIO(DRIDriverContext * ctx); -static void VIADisableMMIO(DRIDriverContext * ctx); -static void VIADisableExtendedFIFO(DRIDriverContext *ctx); -static void VIAEnableExtendedFIFO(DRIDriverContext *ctx); -static void VIAInitialize2DEngine(DRIDriverContext *ctx); -static void VIAInitialize3DEngine(DRIDriverContext *ctx); - -static int VIADRIScreenInit(DRIDriverContext * ctx); -static void VIADRICloseScreen(DRIDriverContext * ctx); -static int VIADRIFinishScreenInit(DRIDriverContext * ctx); - -/* _SOLO : missing macros normally defined by X code */ -#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__) -#define MMIO_IN8(base, addr) ((*(((volatile uint8_t*)base)+(addr)))+0) -#define MMIO_OUT8(base, addr, val) ((*(((volatile uint8_t*)base)+(addr)))=((uint8_t)val)) -#define MMIO_OUT16(base, addr, val) ((*(volatile uint16_t*)(((uint8_t*)base)+(addr)))=((uint16_t)val)) - -#define VIDEO 0 -#define AGP 1 -#define AGP_PAGE_SIZE 4096 -#define AGP_PAGES 8192 -#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES) -#define AGP_CMDBUF_PAGES 512 -#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES) - -static char VIAKernelDriverName[] = "via"; -static char VIAClientDriverName[] = "unichrome"; - -static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia); -static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia); -static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia); -static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia); -static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia); - -static void VIADRIIrqInit( DRIDriverContext *ctx ) -{ - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI = pVia->devPrivate; - - pVIADRI->irqEnabled = drmGetInterruptFromBusID(pVia->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) { - xf86DrvMsg(pScreen->myNum, X_WARNING, - "[drm] Failure adding irq handler. " - "Falling back to irq-free operation.\n"); - pVIADRI->irqEnabled = 0; - } - - if (pVIADRI->irqEnabled) - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] Irq handler installed, using IRQ %d.\n", - pVIADRI->irqEnabled); -} - -static void VIADRIIrqExit( DRIDriverContext *ctx ) { - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI = pVia->devPrivate; - - if (pVIADRI->irqEnabled) { - if (drmCtlUninstHandler(pVia->drmFD)) { - xf86DrvMsg(pScreen-myNum, X_INFO,"[drm] Irq handler uninstalled.\n"); - } else { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] Could not uninstall irq handler.\n"); - } - } -} - -static void VIADRIRingBufferCleanup(DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI = pVia->devPrivate; - drm_via_dma_init_t ringBufInit; - - if (pVIADRI->ringBufActive) { - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] Cleaning up DMA ring-buffer.\n"); - ringBufInit.func = VIA_CLEANUP_DMA; - if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit, - sizeof(ringBufInit))) { - xf86DrvMsg(pScreen->myNum, X_WARNING, - "[drm] Failed to clean up DMA ring-buffer: %d\n", errno); - } - pVIADRI->ringBufActive = 0; - } -} - -static int VIADRIRingBufferInit(DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI = pVia->devPrivate; - drm_via_dma_init_t ringBufInit; - drmVersionPtr drmVer; - - pVIADRI->ringBufActive = 0; - - if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) { - return GL_FALSE; - } - - if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) { - return GL_FALSE; - } - - /* - * Info frome code-snippet on DRI-DEVEL list; Erdi Chen. - */ - - switch (pVia->ChipId) { - case PCI_CHIP_VT3259: - ringBufInit.reg_pause_addr = 0x40c; - break; - default: - ringBufInit.reg_pause_addr = 0x418; - break; - } - - ringBufInit.offset = pVia->agpSize; - ringBufInit.size = AGP_CMDBUF_SIZE; - ringBufInit.func = VIA_INIT_DMA; - if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit, - sizeof(ringBufInit))) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] Failed to initialize DMA ring-buffer: %d\n", errno); - return GL_FALSE; - } - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n", - ringBufInit.size, ringBufInit.offset); - - pVIADRI->ringBufActive = 1; - return GL_TRUE; -} - -static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia) -{ - unsigned long agp_phys; - drmAddress agpaddr; - VIADRIPtr pVIADRI; - pVIADRI = pVia->devPrivate; - pVia->agpSize = 0; - - if (drmAgpAcquire(pVia->drmFD) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno); - return GL_FALSE; - } - - if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n"); - return GL_FALSE; - } - - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n"); - - if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAgpAlloc failed\n"); - drmAgpRelease(pVia->drmFD); - return GL_FALSE; - } - - if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAgpBind failed\n"); - drmAgpFree(pVia->drmFD, pVia->agpHandle); - drmAgpRelease(pVia->drmFD); - - return GL_FALSE; - } - - /* - * Place the ring-buffer last in the AGP region, and restrict the - * public map not to include the buffer for security reasons. - */ - - pVia->agpSize = AGP_SIZE - AGP_CMDBUF_SIZE; - pVia->agpAddr = drmAgpBase(pVia->drmFD); - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr); - - pVIADRI->agp.size = pVia->agpSize; - if (drmAddMap(pVia->drmFD, (drm_handle_t)0, - pVIADRI->agp.size, DRM_AGP, 0, - &pVIADRI->agp.handle) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] Failed to map public agp area\n"); - pVIADRI->agp.size = 0; - return GL_FALSE; - } - /* Map AGP from kernel to Xserver - Not really needed */ - drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size, &agpaddr); - - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr); - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] agpSize = 0x%08lx\n", pVia->agpSize); - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] agp physical addr = 0x%08lx\n", agp_phys); - - { - drm_via_agp_t agp; - agp.offset = 0; - agp.size = AGP_SIZE-AGP_CMDBUF_SIZE; - if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp, - sizeof(drm_via_agp_t)) < 0) { - drmUnmap(&agpaddr,pVia->agpSize); - drmRmMap(pVia->drmFD,pVIADRI->agp.handle); - drmAgpUnbind(pVia->drmFD, pVia->agpHandle); - drmAgpFree(pVia->drmFD, pVia->agpHandle); - drmAgpRelease(pVia->drmFD); - return GL_FALSE; - } - } - - return GL_TRUE; -} - -static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia) -{ - int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart; - int FBOffset = pVia->FBFreeStart; - VIADRIPtr pVIADRI = pVia->devPrivate; - pVIADRI->fbOffset = FBOffset; - pVIADRI->fbSize = pVia->videoRambytes; - - { - drm_via_fb_t fb; - fb.offset = FBOffset; - fb.size = FBSize; - - if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb, - sizeof(drm_via_fb_t)) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] failed to init frame buffer area\n"); - return GL_FALSE; - } else { - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x " - "FBSize= 0x%08x\n", - pVia->FBFreeStart, pVia->FBFreeEnd, FBSize); - return GL_TRUE; - } - } -} - -static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia) -{ - return GL_TRUE; -} - -static int VIADRIScreenInit(DRIDriverContext * ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI; - int err; - -#if 0 - ctx->shared.SAREASize = ((sizeof(drm_sarea_t) + 0xfff) & 0x1000); -#else - if (sizeof(drm_sarea_t)+sizeof(drm_via_sarea_t) > SAREA_MAX) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Data does not fit in SAREA\n"); - return GL_FALSE; - } - ctx->shared.SAREASize = SAREA_MAX; -#endif - - ctx->drmFD = drmOpen(VIAKernelDriverName, NULL); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - pVia->drmFD = ctx->drmFD; - - err = drmSetBusid(ctx->drmFD, ctx->pciBusID); - if (err < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM, - DRM_CONTAINS_LOCK, &ctx->shared.hSAREA); - if (err < 0) { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap(ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - /* Need to AddMap the framebuffer and mmio regions here: - */ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)ctx->FBStart, - ctx->FBSize, - DRM_FRAME_BUFFER, -#ifndef _EMBEDDED - 0, -#else - DRM_READ_ONLY, -#endif - &ctx->shared.hFrameBuffer) < 0) - { - fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); - return 0; - } - - fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", - ctx->shared.hFrameBuffer); - - pVIADRI = (VIADRIPtr) CALLOC(sizeof(VIADRIRec)); - if (!pVIADRI) { - drmClose(ctx->drmFD); - return GL_FALSE; - } - pVia->devPrivate = pVIADRI; - ctx->driverClientMsg = pVIADRI; - ctx->driverClientMsgSize = sizeof(*pVIADRI); - - /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */ - if (!VIADRIMapInit(ctx, pVia)) { - VIADRICloseScreen(ctx); - return GL_FALSE; - } - - pVIADRI->regs.size = VIA_MMIO_REGSIZE; - pVIADRI->regs.handle = pVia->registerHandle; - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n", - pVIADRI->regs.handle); - - if (drmMap(pVia->drmFD, - pVIADRI->regs.handle, - pVIADRI->regs.size, - (drmAddress *)&pVia->MapBase) != 0) - { - VIADRICloseScreen(ctx); - return GL_FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" ); - - VIAEnableMMIO(ctx); - - /* Get video memory clock. */ - VGAOUT8(0x3D4, 0x3D); - pVia->MemClk = (VGAIN8(0x3D5) & 0xF0) >> 4; - xf86DrvMsg(0, X_INFO, "[dri] MemClk (0x%x)\n", pVia->MemClk); - - /* 3D rendering has noise if not enabled. */ - VIAEnableExtendedFIFO(ctx); - - VIAInitialize2DEngine(ctx); - - /* Must disable MMIO or 3D won't work. */ - VIADisableMMIO(ctx); - - VIAInitialize3DEngine(ctx); - - pVia->IsPCI = !VIADRIAgpInit(ctx, pVia); - - if (pVia->IsPCI) { - VIADRIPciInit(ctx, pVia); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" ); - } - else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" ); - - if (!(VIADRIFBInit(ctx, pVia))) { - VIADRICloseScreen(ctx); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialize fail .\n" ); - return GL_FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" ); - - return VIADRIFinishScreenInit(ctx); -} - -static void -VIADRICloseScreen(DRIDriverContext * ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate; - - VIADRIRingBufferCleanup(ctx); - - if (pVia->MapBase) { - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Unmapping MMIO registers\n"); - drmUnmap(pVia->MapBase, pVIADRI->regs.size); - } - - if (pVia->agpSize) { - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n"); - drmAgpFree(pVia->drmFD, pVia->agpHandle); - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n"); - drmAgpRelease(pVia->drmFD); - } - -#if 0 - if (pVia->DRIIrqEnable) -#endif - VIADRIIrqExit(ctx); -} - -static int -VIADRIFinishScreenInit(DRIDriverContext * ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - VIADRIPtr pVIADRI; - int err; - - err = drmCreateContext(ctx->drmFD, &ctx->serverContext); - if (err != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return GL_FALSE; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - - if (!VIADRIKernelInit(ctx, pVia)) { - VIADRICloseScreen(ctx); - return GL_FALSE; - } - xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n"); - - /* set SAREA value */ - { - drm_via_sarea_t *saPriv; - - saPriv=(drm_via_sarea_t*)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - assert(saPriv); - memset(saPriv, 0, sizeof(*saPriv)); - saPriv->ctxOwner = -1; - } - pVIADRI=(VIADRIPtr)pVia->devPrivate; - pVIADRI->deviceID=pVia->Chipset; - pVIADRI->width=ctx->shared.virtualWidth; - pVIADRI->height=ctx->shared.virtualHeight; - pVIADRI->mem=ctx->shared.fbSize; - pVIADRI->bytesPerPixel= (ctx->bpp+7) / 8; - pVIADRI->sarea_priv_offset = sizeof(drm_sarea_t); - /* TODO */ - pVIADRI->scrnX=pVIADRI->width; - pVIADRI->scrnY=pVIADRI->height; - - /* Initialize IRQ */ -#if 0 - if (pVia->DRIIrqEnable) -#endif - VIADRIIrqInit(ctx); - - pVIADRI->ringBufActive = 0; - VIADRIRingBufferInit(ctx); - - return GL_TRUE; -} - -/* Initialize the kernel data structures. */ -static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia) -{ - drm_via_init_t drmInfo; - memset(&drmInfo, 0, sizeof(drm_via_init_t)); - drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); - drmInfo.func = VIA_INIT_MAP; - drmInfo.fb_offset = pVia->FrameBufferBase; - drmInfo.mmio_offset = pVia->registerHandle; - if (pVia->IsPCI) - drmInfo.agpAddr = (uint32_t)NULL; - else - drmInfo.agpAddr = (uint32_t)pVia->agpAddr; - - if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo, - sizeof(drm_via_init_t))) < 0) - return GL_FALSE; - - return GL_TRUE; -} -/* Add a map for the MMIO registers */ -static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia) -{ - int flags = 0; - - if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE, - DRM_REGISTERS, flags, &pVia->registerHandle) < 0) { - return GL_FALSE; - } - - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] register handle = 0x%08lx\n", pVia->registerHandle); - - return GL_TRUE; -} - -static int viaValidateMode(const DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - - return 1; -} - -static int viaPostValidateMode(const DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - - return 1; -} - -static void VIAEnableMMIO(DRIDriverContext * ctx) -{ - /*vgaHWPtr hwp = VGAHWPTR(ctx);*/ - VIAPtr pVia = VIAPTR(ctx); - unsigned char val; - -#if 0 - if (xf86IsPrimaryPci(pVia->PciInfo)) { - /* If we are primary card, we still use std vga port. If we use - * MMIO, system will hang in vgaHWSave when our card used in - * PLE and KLE (integrated Trident MVP4) - */ - vgaHWSetStdFuncs(hwp); - } - else { - vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); - } -#endif - - val = VGAIN8(0x3c3); - VGAOUT8(0x3c3, val | 0x01); - val = VGAIN8(0x3cc); - VGAOUT8(0x3c2, val | 0x01); - - /* Unlock Extended IO Space */ - VGAOUT8(0x3c4, 0x10); - VGAOUT8(0x3c5, 0x01); - - /* Enable MMIO */ - if(!pVia->IsSecondary) { - VGAOUT8(0x3c4, 0x1a); - val = VGAIN8(0x3c5); -#ifdef DEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val); -#endif - VGAOUT8(0x3c5, val | 0x68); - } - else { - VGAOUT8(0x3c4, 0x1a); - val = VGAIN8(0x3c5); -#ifdef DEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val); -#endif - VGAOUT8(0x3c5, val | 0x38); - } - - /* Unlock CRTC registers */ - VGAOUT8(0x3d4, 0x47); - VGAOUT8(0x3d5, 0x00); - - return; -} - -static void VIADisableMMIO(DRIDriverContext * ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - unsigned char val; - - VGAOUT8(0x3c4, 0x1a); - val = VGAIN8(0x3c5); - VGAOUT8(0x3c5, val & 0x97); - - return; -} - -static void VIADisableExtendedFIFO(DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - uint32_t dwGE230, dwGE298; - - /* Cause of exit XWindow will dump back register value, others chipset no - * need to set extended fifo value */ - if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15 && - (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary)) { - /* Turn off Extend FIFO */ - /* 0x298[29] */ - dwGE298 = VIAGETREG(0x298); - VIASETREG(0x298, dwGE298 | 0x20000000); - /* 0x230[21] */ - dwGE230 = VIAGETREG(0x230); - VIASETREG(0x230, dwGE230 & ~0x00200000); - /* 0x298[29] */ - dwGE298 = VIAGETREG(0x298); - VIASETREG(0x298, dwGE298 & ~0x20000000); - } -} - -static void VIAEnableExtendedFIFO(DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - uint8_t bRegTemp; - uint32_t dwGE230, dwGE298; - - switch (pVia->Chipset) { - case VIA_CLE266: - if (pVia->ChipRev > 14) { /* For 3123Cx */ - if (pVia->HasSecondary) { /* SAMM or DuoView case */ - if (ctx->shared.virtualWidth >= 1024) - { - /* 3c5.16[0:5] */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x1C; - VGAOUT8(0x3C5, bRegTemp); - /* 3c5.17[0:6] */ - VGAOUT8(0x3C4, 0x17); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x7F; - bRegTemp |= 0x3F; - VGAOUT8(0x3C5, bRegTemp); - pVia->EnableExtendedFIFO = GL_TRUE; - } - } - else /* Single view or Simultaneoue case */ - { - if (ctx->shared.virtualWidth > 1024) - { - /* 3c5.16[0:5] */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x17; - VGAOUT8(0x3C5, bRegTemp); - /* 3c5.17[0:6] */ - VGAOUT8(0x3C4, 0x17); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x7F; - bRegTemp |= 0x2F; - VGAOUT8(0x3C5, bRegTemp); - pVia->EnableExtendedFIFO = GL_TRUE; - } - } - /* 3c5.18[0:5] */ - VGAOUT8(0x3C4, 0x18); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x17; - bRegTemp |= 0x40; /* force the preq always higher than treq */ - VGAOUT8(0x3C5, bRegTemp); - } - else { /* for 3123Ax */ - if (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary) { - /* Turn on Extend FIFO */ - /* 0x298[29] */ - dwGE298 = VIAGETREG(0x298); - VIASETREG(0x298, dwGE298 | 0x20000000); - /* 0x230[21] */ - dwGE230 = VIAGETREG(0x230); - VIASETREG(0x230, dwGE230 | 0x00200000); - /* 0x298[29] */ - dwGE298 = VIAGETREG(0x298); - VIASETREG(0x298, dwGE298 & ~0x20000000); - - /* 3c5.16[0:5] */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x17; - /* bRegTemp |= 0x10; */ - VGAOUT8(0x3C5, bRegTemp); - /* 3c5.17[0:6] */ - VGAOUT8(0x3C4, 0x17); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x7F; - bRegTemp |= 0x2F; - /*bRegTemp |= 0x1F;*/ - VGAOUT8(0x3C5, bRegTemp); - /* 3c5.18[0:5] */ - VGAOUT8(0x3C4, 0x18); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x17; - bRegTemp |= 0x40; /* force the preq always higher than treq */ - VGAOUT8(0x3C5, bRegTemp); - pVia->EnableExtendedFIFO = GL_TRUE; - } - } - break; - case VIA_KM400: - if (pVia->HasSecondary) { /* SAMM or DuoView case */ - if ((ctx->shared.virtualWidth >= 1600) && - (pVia->MemClk <= VIA_MEM_DDR200)) { - /* enable CRT extendded FIFO */ - VGAOUT8(0x3C4, 0x17); - VGAOUT8(0x3C5, 0x1C); - /* revise second display queue depth and read threshold */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp = (bRegTemp) | (0x09); - VGAOUT8(0x3C5, bRegTemp); - } - else { - /* enable CRT extendded FIFO */ - VGAOUT8(0x3C4, 0x17); - VGAOUT8(0x3C5,0x3F); - /* revise second display queue depth and read threshold */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp = (bRegTemp) | (0x1C); - VGAOUT8(0x3C5, bRegTemp); - } - /* 3c5.18[0:5] */ - VGAOUT8(0x3C4, 0x18); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x17; - bRegTemp |= 0x40; /* force the preq always higher than treq */ - VGAOUT8(0x3C5, bRegTemp); - pVia->EnableExtendedFIFO = GL_TRUE; - } - else { - if ( (ctx->shared.virtualWidth > 1024) && (ctx->shared.virtualWidth <= 1280) ) - { - /* enable CRT extendded FIFO */ - VGAOUT8(0x3C4, 0x17); - VGAOUT8(0x3C5, 0x3F); - /* revise second display queue depth and read threshold */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp = (bRegTemp) | (0x17); - VGAOUT8(0x3C5, bRegTemp); - pVia->EnableExtendedFIFO = GL_TRUE; - } - else if ((ctx->shared.virtualWidth > 1280)) - { - /* enable CRT extendded FIFO */ - VGAOUT8(0x3C4, 0x17); - VGAOUT8(0x3C5, 0x3F); - /* revise second display queue depth and read threshold */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp = (bRegTemp) | (0x1C); - VGAOUT8(0x3C5, bRegTemp); - pVia->EnableExtendedFIFO = GL_TRUE; - } - else - { - /* enable CRT extendded FIFO */ - VGAOUT8(0x3C4, 0x17); - VGAOUT8(0x3C5, 0x3F); - /* revise second display queue depth and read threshold */ - VGAOUT8(0x3C4, 0x16); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp = (bRegTemp) | (0x10); - VGAOUT8(0x3C5, bRegTemp); - } - /* 3c5.18[0:5] */ - VGAOUT8(0x3C4, 0x18); - bRegTemp = VGAIN8(0x3C5); - bRegTemp &= ~0x3F; - bRegTemp |= 0x17; - bRegTemp |= 0x40; /* force the preq always higher than treq */ - VGAOUT8(0x3C5, bRegTemp); - } - break; - case VIA_K8M800: - /*=* R1 Display FIFO depth (384 /8 -1 -> 0xbf) SR17[7:0] (8bits) *=*/ - VGAOUT8(0x3c4, 0x17); - VGAOUT8(0x3c5, 0xbf); - - /*=* R2 Display fetch datum threshold value (328/4 -> 0x52) - SR16[5:0], SR16[7] (7bits) *=*/ - VGAOUT8(0x3c4, 0x16); - bRegTemp = VGAIN8(0x3c5) & ~0xBF; - bRegTemp |= (0x52 & 0x3F); - bRegTemp |= ((0x52 & 0x40) << 1); - VGAOUT8(0x3c5, bRegTemp); - - /*=* R3 Switch to the highest agent threshold value (74 -> 0x4a) - SR18[5:0], SR18[7] (7bits) *=*/ - VGAOUT8(0x3c4, 0x18); - bRegTemp = VGAIN8(0x3c5) & ~0xBF; - bRegTemp |= (0x4a & 0x3F); - bRegTemp |= ((0x4a & 0x40) << 1); - VGAOUT8(0x3c5, bRegTemp); -#if 0 - /*=* R4 Fetch Number for a scan line (unit: 8 bytes) - SR1C[7:0], SR1D[1:0] (10bits) *=*/ - wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4; - VGAOUT8(0x3c4, 0x1c); - VGAOUT8(0x3c5, (uint8_t)(wRegTemp & 0xFF)); - VGAOUT8(0x3c4, 0x1d); - bRegTemp = VGAIN8(0x3c5) & ~0x03; - VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8)); -#endif - if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32) - { - /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/ - VGAOUT8(0x3c4, 0x22); - bRegTemp = VGAIN8(0x3c5) & ~0x1F; - VGAOUT8(0x3c5, bRegTemp | 0x10); - } - else - { - /*=* Max. length for a request SR22[4:0] - (128/4 -> over flow 0x0) *=*/ - VGAOUT8(0x3c4, 0x22); - bRegTemp = VGAIN8(0x3c5) & ~0x1F; - VGAOUT8(0x3c5, bRegTemp); - } - break; - case VIA_PM800: - /*=* R1 Display FIFO depth (96-1 -> 0x5f) SR17[7:0] (8bits) *=*/ - VGAOUT8(0x3c4, 0x17); - VGAOUT8(0x3c5, 0x5f); - - /*=* R2 Display fetch datum threshold value (32 -> 0x20) - SR16[5:0], SR16[7] (7bits) *=*/ - VGAOUT8(0x3c4, 0x16); - bRegTemp = VGAIN8(0x3c5) & ~0xBF; - bRegTemp |= (0x20 & 0x3F); - bRegTemp |= ((0x20 & 0x40) << 1); - VGAOUT8(0x3c5, bRegTemp); - - /*=* R3 Switch to the highest agent threshold value (16 -> 0x10) - SR18[5:0], SR18[7] (7bits) *=*/ - VGAOUT8(0x3c4, 0x18); - bRegTemp = VGAIN8(0x3c5) & ~0xBF; - bRegTemp |= (0x10 & 0x3F); - bRegTemp |= ((0x10 & 0x40) << 1); - VGAOUT8(0x3c5, bRegTemp); -#if 0 - /*=* R4 Fetch Number for a scan line (unit: 8 bytes) - SR1C[7:0], SR1D[1:0] (10bits) *=*/ - wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4; - VGAOUT8(0x3c4, 0x1c); - VGAOUT8(0x3c5, (uint8_t)(wRegTemp & 0xFF)); - VGAOUT8(0x3c4, 0x1d); - bRegTemp = VGAIN8(0x3c5) & ~0x03; - VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8)); -#endif - if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32) - { - /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/ - VGAOUT8(0x3c4, 0x22); - bRegTemp = VGAIN8(0x3c5) & ~0x1F; - VGAOUT8(0x3c5, bRegTemp | 0x10); - } - else - { - /*=* Max. length for a request SR22[4:0] (0x1F) *=*/ - VGAOUT8(0x3c4, 0x22); - bRegTemp = VGAIN8(0x3c5) & ~0x1F; - VGAOUT8(0x3c5, bRegTemp | 0x1F); - } - break; - default: - break; - } -} - -static void VIAInitialize2DEngine(DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - uint32_t dwVQStartAddr, dwVQEndAddr; - uint32_t dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; - uint32_t dwGEMode; - - /* init 2D engine regs to reset 2D engine */ - VIASETREG(0x04, 0x0); - VIASETREG(0x08, 0x0); - VIASETREG(0x0c, 0x0); - VIASETREG(0x10, 0x0); - VIASETREG(0x14, 0x0); - VIASETREG(0x18, 0x0); - VIASETREG(0x1c, 0x0); - VIASETREG(0x20, 0x0); - VIASETREG(0x24, 0x0); - VIASETREG(0x28, 0x0); - VIASETREG(0x2c, 0x0); - VIASETREG(0x30, 0x0); - VIASETREG(0x34, 0x0); - VIASETREG(0x38, 0x0); - VIASETREG(0x3c, 0x0); - VIASETREG(0x40, 0x0); - - VIADisableMMIO(ctx); - - /* Init AGP and VQ regs */ - VIASETREG(0x43c, 0x00100000); - VIASETREG(0x440, 0x00000000); - VIASETREG(0x440, 0x00333004); - VIASETREG(0x440, 0x60000000); - VIASETREG(0x440, 0x61000000); - VIASETREG(0x440, 0x62000000); - VIASETREG(0x440, 0x63000000); - VIASETREG(0x440, 0x64000000); - VIASETREG(0x440, 0x7D000000); - - VIASETREG(0x43c, 0xfe020000); - VIASETREG(0x440, 0x00000000); - - if (pVia->VQStart != 0) { - /* Enable VQ */ - dwVQStartAddr = pVia->VQStart; - dwVQEndAddr = pVia->VQEnd; - dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); - dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); - dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) | - ((dwVQEndAddr & 0xFF000000) >> 16); - dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3); - - VIASETREG(0x43c, 0x00fe0000); - VIASETREG(0x440, 0x080003fe); - VIASETREG(0x440, 0x0a00027c); - VIASETREG(0x440, 0x0b000260); - VIASETREG(0x440, 0x0c000274); - VIASETREG(0x440, 0x0d000264); - VIASETREG(0x440, 0x0e000000); - VIASETREG(0x440, 0x0f000020); - VIASETREG(0x440, 0x1000027e); - VIASETREG(0x440, 0x110002fe); - VIASETREG(0x440, 0x200f0060); - - VIASETREG(0x440, 0x00000006); - VIASETREG(0x440, 0x40008c0f); - VIASETREG(0x440, 0x44000000); - VIASETREG(0x440, 0x45080c04); - VIASETREG(0x440, 0x46800408); - - VIASETREG(0x440, dwVQStartEndH); - VIASETREG(0x440, dwVQStartL); - VIASETREG(0x440, dwVQEndL); - VIASETREG(0x440, dwVQLen); - } - else { - /* Diable VQ */ - VIASETREG(0x43c, 0x00fe0000); - VIASETREG(0x440, 0x00000004); - VIASETREG(0x440, 0x40008c0f); - VIASETREG(0x440, 0x44000000); - VIASETREG(0x440, 0x45080c04); - VIASETREG(0x440, 0x46800408); - } - - dwGEMode = 0; - - switch (ctx->bpp) { - case 16: - dwGEMode |= VIA_GEM_16bpp; - break; - case 32: - dwGEMode |= VIA_GEM_32bpp; - break; - default: - dwGEMode |= VIA_GEM_8bpp; - break; - } - -#if 0 - switch (ctx->shared.virtualWidth) { - case 800: - dwGEMode |= VIA_GEM_800; - break; - case 1024: - dwGEMode |= VIA_GEM_1024; - break; - case 1280: - dwGEMode |= VIA_GEM_1280; - break; - case 1600: - dwGEMode |= VIA_GEM_1600; - break; - case 2048: - dwGEMode |= VIA_GEM_2048; - break; - default: - dwGEMode |= VIA_GEM_640; - break; - } -#endif - - VIAEnableMMIO(ctx); - - /* Set BPP and Pitch */ - VIASETREG(VIA_REG_GEMODE, dwGEMode); - - /* Set Src and Dst base address and pitch, pitch is qword */ - VIASETREG(VIA_REG_SRCBASE, 0x0); - VIASETREG(VIA_REG_DSTBASE, 0x0); - VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) | - (((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) << 16)); -} - -static int b3DRegsInitialized = 0; - -static void VIAInitialize3DEngine(DRIDriverContext *ctx) -{ - VIAPtr pVia = VIAPTR(ctx); - int i; - - if (!b3DRegsInitialized) - { - - VIASETREG(0x43C, 0x00010000); - - for (i = 0; i <= 0x7D; i++) - { - VIASETREG(0x440, (uint32_t) i << 24); - } - - VIASETREG(0x43C, 0x00020000); - - for (i = 0; i <= 0x94; i++) - { - VIASETREG(0x440, (uint32_t) i << 24); - } - - VIASETREG(0x440, 0x82400000); - - VIASETREG(0x43C, 0x01020000); - - - for (i = 0; i <= 0x94; i++) - { - VIASETREG(0x440, (uint32_t) i << 24); - } - - VIASETREG(0x440, 0x82400000); - VIASETREG(0x43C, 0xfe020000); - - for (i = 0; i <= 0x03; i++) - { - VIASETREG(0x440, (uint32_t) i << 24); - } - - VIASETREG(0x43C, 0x00030000); - - for (i = 0; i <= 0xff; i++) - { - VIASETREG(0x440, 0); - } - VIASETREG(0x43C, 0x00100000); - VIASETREG(0x440, 0x00333004); - VIASETREG(0x440, 0x10000002); - VIASETREG(0x440, 0x60000000); - VIASETREG(0x440, 0x61000000); - VIASETREG(0x440, 0x62000000); - VIASETREG(0x440, 0x63000000); - VIASETREG(0x440, 0x64000000); - - VIASETREG(0x43C, 0x00fe0000); - - if (pVia->ChipRev >= 3 ) - VIASETREG(0x440,0x40008c0f); - else - VIASETREG(0x440,0x4000800f); - - VIASETREG(0x440,0x44000000); - VIASETREG(0x440,0x45080C04); - VIASETREG(0x440,0x46800408); - VIASETREG(0x440,0x50000000); - VIASETREG(0x440,0x51000000); - VIASETREG(0x440,0x52000000); - VIASETREG(0x440,0x53000000); - - b3DRegsInitialized = 1; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "3D Engine has been initialized.\n"); - } - - VIASETREG(0x43C,0x00fe0000); - VIASETREG(0x440,0x08000001); - VIASETREG(0x440,0x0A000183); - VIASETREG(0x440,0x0B00019F); - VIASETREG(0x440,0x0C00018B); - VIASETREG(0x440,0x0D00019B); - VIASETREG(0x440,0x0E000000); - VIASETREG(0x440,0x0F000000); - VIASETREG(0x440,0x10000000); - VIASETREG(0x440,0x11000000); - VIASETREG(0x440,0x20000000); -} - -static int -WaitIdleCLE266(VIAPtr pVia) -{ - int loop = 0; - - /*mem_barrier();*/ - - while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) - ; - - while ((VIAGETREG(VIA_REG_STATUS) & - (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && - (loop++ < MAXLOOP)) - ; - - return loop >= MAXLOOP; -} - -static int viaInitFBDev(DRIDriverContext *ctx) -{ - VIAPtr pVia = CALLOC(sizeof(*pVia)); - - ctx->driverPrivate = (void *)pVia; - - switch (ctx->chipset) { - case PCI_CHIP_CLE3122: - case PCI_CHIP_CLE3022: - pVia->Chipset = VIA_CLE266; - break; - case PCI_CHIP_VT7205: - case PCI_CHIP_VT3205: - pVia->Chipset = VIA_KM400; - break; - case PCI_CHIP_VT3204: - case PCI_CHIP_VT3344: - pVia->Chipset = VIA_K8M800; - break; - case PCI_CHIP_VT3259: - pVia->Chipset = VIA_PM800; - break; - default: - xf86DrvMsg(0, X_ERROR, "VIA: Unknown device ID (0x%x)\n", ctx->chipset); - } - - /* _SOLO TODO XXX need to read ChipRev too */ - pVia->ChipRev = 0; - - pVia->videoRambytes = ctx->shared.fbSize; - pVia->MmioBase = ctx->MMIOStart; - pVia->FrameBufferBase = ctx->FBStart & 0xfc000000; - - pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp * - ctx->shared.virtualHeight; - -#if 1 - /* Alloc a second framebuffer for the second head */ - pVia->FBFreeStart += ctx->shared.virtualWidth * ctx->cpp * - ctx->shared.virtualHeight; -#endif - - pVia->VQStart = pVia->FBFreeStart; - pVia->VQEnd = pVia->FBFreeStart + VIA_VQ_SIZE - 1; - - pVia->FBFreeStart += VIA_VQ_SIZE; - - pVia->FBFreeEnd = pVia->videoRambytes; - - if (!VIADRIScreenInit(ctx)) - return 0; - - return 1; -} - -static void viaHaltFBDev(DRIDriverContext *ctx) -{ - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - -static int viaEngineShutdown(const DRIDriverContext *ctx) -{ - return 1; -} - -static int viaEngineRestore(const DRIDriverContext *ctx) -{ - return 1; -} - -const struct DRIDriverRec __driDriver = -{ - viaValidateMode, - viaPostValidateMode, - viaInitFBDev, - viaHaltFBDev, - viaEngineShutdown, - viaEngineRestore, - 0, -}; - -- cgit v1.2.3 From bbab68ae2db468cc72bf11b901d8e28ab86bd769 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Mar 2010 13:09:47 +0100 Subject: r300: remove unnecessary code _tnl_UpdateFixedFunctionProgram is already called in r300_draw.c --- src/mesa/drivers/dri/r300/r300_state.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 9d1ff6e2ba2..ba4a963d409 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1985,23 +1985,6 @@ void r300UpdateShaders(r300ContextPtr rmesa) if (rmesa->options.hw_tcl_enabled) { struct r300_vertex_program *vp; - if (rmesa->radeon.NewGLState) { - int i; - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - rmesa->temp_attrib[i] = - TNL_CONTEXT(ctx)->vb.AttribPtr[i]; - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - &rmesa->dummy_attrib[i]; - } - - _tnl_UpdateFixedFunctionProgram(ctx); - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - rmesa->temp_attrib[i]; - } - } - vp = r300SelectAndTranslateVertexShader(ctx); r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error); -- cgit v1.2.3 From e2d96b2bf805fef0bfb016be1895a49551e2faa7 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Mar 2010 13:18:11 +0100 Subject: r300: no need to flush on context init --- src/mesa/drivers/dri/r300/r300_state.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index ba4a963d409..6c2c367aabc 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1762,8 +1762,6 @@ static void r300ResetHwState(r300ContextPtr r300) if (RADEON_DEBUG & RADEON_STATE) fprintf(stderr, "%s\n", __FUNCTION__); - radeon_firevertices(&r300->radeon); - r300ColorMask(ctx, ctx->Color.ColorMask[0][RCOMP], ctx->Color.ColorMask[0][GCOMP], -- cgit v1.2.3 From 89ea4022371998467faf26c5e27ab987469b91ef Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Mar 2010 13:39:13 +0100 Subject: r300: recalculate point size, if point min/max size changes Fixes two wine d3d9 unit tests --- src/mesa/drivers/dri/r300/r300_state.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 6c2c367aabc..5a056f018d1 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -794,12 +794,14 @@ static void r300PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * pa R300_STATECHANGE(r300, ga_point_minmax); r300->hw.ga_point_minmax.cmd[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK; r300->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MinSize * 6.0); + r300PointSize(ctx, ctx->Point.Size); break; case GL_POINT_SIZE_MAX: R300_STATECHANGE(r300, ga_point_minmax); r300->hw.ga_point_minmax.cmd[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK; r300->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MaxSize * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT; + r300PointSize(ctx, ctx->Point.Size); break; case GL_POINT_DISTANCE_ATTENUATION: break; -- cgit v1.2.3 From 042779dc85191e51db79090613b5cc4498474e23 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 7 Mar 2010 12:02:28 +0100 Subject: r300: VAP flush is needed only when vertex program or constants are changed --- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 21 +-------------------- src/mesa/drivers/dri/r300/r300_context.h | 1 - src/mesa/drivers/dri/r300/r300_state.c | 1 - src/mesa/drivers/dri/r300/r300_vertprog.c | 4 +--- 4 files changed, 2 insertions(+), 25 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 4787bafc66a..6cfa5686f4a 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -90,8 +90,7 @@ void r300_emit_vpu(struct r300_context *r300, { BATCH_LOCALS(&r300->radeon); - BEGIN_BATCH_NO_AUTOSTATE(5 + len); - OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0); + BEGIN_BATCH_NO_AUTOSTATE(3 + len); OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr); OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, len-1) | RADEON_ONE_REG_WR); OUT_BATCH_TABLE(data, len); @@ -778,24 +777,6 @@ void r300InitCmdBuf(r300ContextPtr r300) /* VPU only on TCL */ if (has_tcl) { int i; - if (r300->radeon.radeonScreen->kernel_mm) { - ALLOC_STATE(vap_flush, always, 10, 0); - /* flush processing vertices */ - r300->hw.vap_flush.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); - r300->hw.vap_flush.cmd[1] = 0; - r300->hw.vap_flush.cmd[2] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DSTCACHE_CTLSTAT, 1); - r300->hw.vap_flush.cmd[3] = R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D; - r300->hw.vap_flush.cmd[4] = cmdpacket0(r300->radeon.radeonScreen, RADEON_WAIT_UNTIL, 1); - r300->hw.vap_flush.cmd[5] = RADEON_WAIT_3D_IDLECLEAN; - r300->hw.vap_flush.cmd[6] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); - r300->hw.vap_flush.cmd[7] = 0xffffff; - r300->hw.vap_flush.cmd[8] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1); - r300->hw.vap_flush.cmd[9] = 0; - } else { - ALLOC_STATE(vap_flush, never, 10, 0); - } - - ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); r300->hw.vpi.cmd[0] = cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 78ab43a99f9..df7115e7dae 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -355,7 +355,6 @@ struct r300_hw_state { struct radeon_state_atom zb_hiz_offset; /* (4F44) */ struct radeon_state_atom zb_hiz_pitch; /* (4F54) */ - struct radeon_state_atom vap_flush; struct radeon_state_atom vpi; /* vp instructions */ struct radeon_state_atom vpp; /* vp parameters */ struct radeon_state_atom vps; /* vertex point size (?) */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5a056f018d1..5979dedac4f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -366,7 +366,6 @@ static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) p = (GLint) plane - (GLint) GL_CLIP_PLANE0; ip = (GLint *)ctx->Transform._ClipUserPlane[p]; - R300_STATECHANGE( rmesa, vap_flush ); R300_STATECHANGE( rmesa, vpucp[p] ); rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0]; rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1]; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index cbe4cb83047..129004fee78 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -342,8 +342,6 @@ static void r300EmitVertexProgram(r300ContextPtr r300, int dest, struct r300_ver assert((code->length > 0) && (code->length % 4 == 0)); - R300_STATECHANGE( r300, vap_flush ); - switch ((dest >> 8) & 0xf) { case 0: R300_STATECHANGE(r300, vpi); @@ -381,7 +379,7 @@ void r300SetupVertexProgram(r300ContextPtr rmesa) ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; - R300_STATECHANGE(rmesa, vap_flush); + R300_STATECHANGE(rmesa, vap_cntl); R300_STATECHANGE(rmesa, vpp); param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); bump_vpu_count(rmesa->hw.vpp.cmd, param_count); -- cgit v1.2.3 From c0a0a1933d4c2a7d32284b5e7170e79ac6157043 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Feb 2010 18:25:36 +0100 Subject: r300: reset bos when validating buffers during blit --- src/mesa/drivers/dri/r300/r300_blit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index 2bc761bc208..f9c085e2832 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -381,6 +381,9 @@ static GLboolean validate_buffers(struct r300_context *r300, struct radeon_bo *dst_bo) { int ret; + + radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs); + ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, src_bo, RADEON_GEM_DOMAIN_VRAM, 0); if (ret) -- cgit v1.2.3 From ea3494b98cc764ead7e96746c0247ebc3a68e629 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Thu, 4 Mar 2010 18:35:55 +0100 Subject: r300: allow src and dst BOs to be placed in GTT during blit Fixes some relocation failures --- src/mesa/drivers/dri/r300/r300_blit.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index f9c085e2832..d870c7f852a 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -385,18 +385,12 @@ static GLboolean validate_buffers(struct r300_context *r300, radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs); ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, - src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); if (ret) return GL_FALSE; ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, - dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); - if (ret) - return GL_FALSE; - - ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, - first_elem(&r300->radeon.dma.reserved)->bo, - RADEON_GEM_DOMAIN_GTT, 0); + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT); if (ret) return GL_FALSE; -- cgit v1.2.3 From 9c0c6c26decfa533ad3fe39f83e7530d4cfc8c2f Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 14 Feb 2010 00:02:05 +0100 Subject: r300: don't enable EXT_packed_depth_stencil R300 hw doesn't support sampling from Z24_S8 or S8_Z24 formats. --- src/mesa/drivers/dri/r300/r300_context.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index df4cc11da42..ff35cd52753 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -109,7 +109,6 @@ static const struct dri_extension card_extensions[] = { {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_packed_depth_stencil", NULL}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions}, {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions }, @@ -456,6 +455,9 @@ static void r300InitGLExtensions(GLcontext *ctx) } if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV350) _mesa_enable_extension(ctx, "GL_ARB_half_float_vertex"); + + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + _mesa_enable_extension(ctx, "GL_EXT_packed_depth_stencil"); } static void r300InitIoctlFuncs(struct dd_function_table *functions) -- cgit v1.2.3 From 88a99bb305186fd0eaaae9bd0dbfa4c45f14cac7 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 16 Jan 2010 18:38:17 +0100 Subject: radeon: added tiling functions --- src/mesa/drivers/dri/r200/Makefile | 3 +- src/mesa/drivers/dri/r200/radeon_tile.c | 1 + src/mesa/drivers/dri/r200/radeon_tile.h | 1 + src/mesa/drivers/dri/r300/Makefile | 3 +- src/mesa/drivers/dri/r300/radeon_tile.c | 1 + src/mesa/drivers/dri/r300/radeon_tile.h | 1 + src/mesa/drivers/dri/r600/Makefile | 3 +- src/mesa/drivers/dri/r600/radeon_tile.c | 1 + src/mesa/drivers/dri/r600/radeon_tile.h | 1 + src/mesa/drivers/dri/radeon/Makefile | 3 +- src/mesa/drivers/dri/radeon/radeon_tile.c | 246 ++++++++++++++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_tile.h | 32 ++++ 12 files changed, 292 insertions(+), 4 deletions(-) create mode 120000 src/mesa/drivers/dri/r200/radeon_tile.c create mode 120000 src/mesa/drivers/dri/r200/radeon_tile.h create mode 120000 src/mesa/drivers/dri/r300/radeon_tile.c create mode 120000 src/mesa/drivers/dri/r300/radeon_tile.h create mode 120000 src/mesa/drivers/dri/r600/radeon_tile.c create mode 120000 src/mesa/drivers/dri/r600/radeon_tile.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_tile.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_tile.h (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 2e86e8b9415..d91e5482e93 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -24,7 +24,8 @@ RADEON_COMMON_SOURCES = \ radeon_queryobj.c \ radeon_span.c \ radeon_texture.c \ - radeon_tex_copy.c + radeon_tex_copy.c \ + radeon_tile.c DRIVER_SOURCES = r200_context.c \ r200_ioctl.c \ diff --git a/src/mesa/drivers/dri/r200/radeon_tile.c b/src/mesa/drivers/dri/r200/radeon_tile.c new file mode 120000 index 00000000000..d4bfe27da64 --- /dev/null +++ b/src/mesa/drivers/dri/r200/radeon_tile.c @@ -0,0 +1 @@ +../radeon/radeon_tile.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r200/radeon_tile.h b/src/mesa/drivers/dri/r200/radeon_tile.h new file mode 120000 index 00000000000..31074c581ea --- /dev/null +++ b/src/mesa/drivers/dri/r200/radeon_tile.h @@ -0,0 +1 @@ +../radeon/radeon_tile.h \ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 08934fc996a..730d801bb0f 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -34,7 +34,8 @@ RADEON_COMMON_SOURCES = \ radeon_span.c \ radeon_queryobj.c \ radeon_texture.c \ - radeon_tex_copy.c + radeon_tex_copy.c \ + radeon_tile.c DRIVER_SOURCES = \ radeon_screen.c \ diff --git a/src/mesa/drivers/dri/r300/radeon_tile.c b/src/mesa/drivers/dri/r300/radeon_tile.c new file mode 120000 index 00000000000..d4bfe27da64 --- /dev/null +++ b/src/mesa/drivers/dri/r300/radeon_tile.c @@ -0,0 +1 @@ +../radeon/radeon_tile.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/radeon_tile.h b/src/mesa/drivers/dri/r300/radeon_tile.h new file mode 120000 index 00000000000..31074c581ea --- /dev/null +++ b/src/mesa/drivers/dri/r300/radeon_tile.h @@ -0,0 +1 @@ +../radeon/radeon_tile.h \ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile index 2478b126587..b6d1c5f459e 100644 --- a/src/mesa/drivers/dri/r600/Makefile +++ b/src/mesa/drivers/dri/r600/Makefile @@ -34,7 +34,8 @@ RADEON_COMMON_SOURCES = \ radeon_span.c \ radeon_texture.c \ radeon_queryobj.c \ - radeon_tex_copy.c + radeon_tex_copy.c \ + radeon_tile.c DRIVER_SOURCES = \ radeon_screen.c \ diff --git a/src/mesa/drivers/dri/r600/radeon_tile.c b/src/mesa/drivers/dri/r600/radeon_tile.c new file mode 120000 index 00000000000..d4bfe27da64 --- /dev/null +++ b/src/mesa/drivers/dri/r600/radeon_tile.c @@ -0,0 +1 @@ +../radeon/radeon_tile.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/radeon_tile.h b/src/mesa/drivers/dri/r600/radeon_tile.h new file mode 120000 index 00000000000..31074c581ea --- /dev/null +++ b/src/mesa/drivers/dri/r600/radeon_tile.h @@ -0,0 +1 @@ +../radeon/radeon_tile.h \ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index fc6d1c8e897..f7e8059c4f8 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -25,7 +25,8 @@ RADEON_COMMON_SOURCES = \ radeon_queryobj.c \ radeon_span.c \ radeon_texture.c \ - radeon_tex_copy.c + radeon_tex_copy.c \ + radeon_tile.c DRIVER_SOURCES = \ radeon_context.c \ diff --git a/src/mesa/drivers/dri/radeon/radeon_tile.c b/src/mesa/drivers/dri/radeon/radeon_tile.c new file mode 100644 index 00000000000..56f2fc46d9c --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_tile.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2010 Maciej Cencora + * + * 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_tile.h" + +#include +#include + +#include
+ +#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, + gl_format format, unsigned width, unsigned height) +{ + assert(src_pitch >= width); + assert(dst_pitch >= width); + assert(dst_pitch * _mesa_get_format_bytes(format) % MICRO_TILE_SIZE == 0); + + 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; + } +} \ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/radeon_tile.h b/src/mesa/drivers/dri/radeon/radeon_tile.h new file mode 100644 index 00000000000..4985e552045 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_tile.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 Maciej Cencora + * + * 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
+ +void tile_image(const void * src, unsigned src_pitch, + void *dst, unsigned dst_pitch, + gl_format format, unsigned width, unsigned height); -- cgit v1.2.3 From ccbe3f0314c8278c55e1046a619969ae539564de Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 17 Jan 2010 12:47:46 +0100 Subject: radeon: move glGetTexImage handlers to seperate file --- src/mesa/drivers/dri/r200/Makefile | 1 + src/mesa/drivers/dri/r200/radeon_tex_getimage.c | 1 + src/mesa/drivers/dri/r300/Makefile | 1 + src/mesa/drivers/dri/r300/radeon_tex_getimage.c | 1 + src/mesa/drivers/dri/r600/Makefile | 1 + src/mesa/drivers/dri/r600/radeon_tex_getimage.c | 1 + src/mesa/drivers/dri/radeon/Makefile | 1 + src/mesa/drivers/dri/radeon/radeon_tex_getimage.c | 95 +++++++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_texture.c | 60 -------------- 9 files changed, 102 insertions(+), 60 deletions(-) create mode 120000 src/mesa/drivers/dri/r200/radeon_tex_getimage.c create mode 120000 src/mesa/drivers/dri/r300/radeon_tex_getimage.c create mode 120000 src/mesa/drivers/dri/r600/radeon_tex_getimage.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_tex_getimage.c (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index d91e5482e93..3f871005705 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -25,6 +25,7 @@ RADEON_COMMON_SOURCES = \ radeon_span.c \ radeon_texture.c \ radeon_tex_copy.c \ + radeon_tex_getimage.c \ radeon_tile.c DRIVER_SOURCES = r200_context.c \ diff --git a/src/mesa/drivers/dri/r200/radeon_tex_getimage.c b/src/mesa/drivers/dri/r200/radeon_tex_getimage.c new file mode 120000 index 00000000000..d9836d7326e --- /dev/null +++ b/src/mesa/drivers/dri/r200/radeon_tex_getimage.c @@ -0,0 +1 @@ +../radeon/radeon_tex_getimage.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 730d801bb0f..4257a32b89f 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -35,6 +35,7 @@ RADEON_COMMON_SOURCES = \ radeon_queryobj.c \ radeon_texture.c \ radeon_tex_copy.c \ + radeon_tex_getimage.c \ radeon_tile.c DRIVER_SOURCES = \ diff --git a/src/mesa/drivers/dri/r300/radeon_tex_getimage.c b/src/mesa/drivers/dri/r300/radeon_tex_getimage.c new file mode 120000 index 00000000000..d9836d7326e --- /dev/null +++ b/src/mesa/drivers/dri/r300/radeon_tex_getimage.c @@ -0,0 +1 @@ +../radeon/radeon_tex_getimage.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile index b6d1c5f459e..f76859d11e2 100644 --- a/src/mesa/drivers/dri/r600/Makefile +++ b/src/mesa/drivers/dri/r600/Makefile @@ -35,6 +35,7 @@ RADEON_COMMON_SOURCES = \ radeon_texture.c \ radeon_queryobj.c \ radeon_tex_copy.c \ + radeon_tex_getimage.c \ radeon_tile.c DRIVER_SOURCES = \ diff --git a/src/mesa/drivers/dri/r600/radeon_tex_getimage.c b/src/mesa/drivers/dri/r600/radeon_tex_getimage.c new file mode 120000 index 00000000000..d9836d7326e --- /dev/null +++ b/src/mesa/drivers/dri/r600/radeon_tex_getimage.c @@ -0,0 +1 @@ +../radeon/radeon_tex_getimage.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index f7e8059c4f8..6904ebbee3b 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -26,6 +26,7 @@ RADEON_COMMON_SOURCES = \ radeon_span.c \ radeon_texture.c \ radeon_tex_copy.c \ + radeon_tex_getimage.c \ radeon_tile.c DRIVER_SOURCES = \ diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_getimage.c b/src/mesa/drivers/dri/radeon/radeon_tex_getimage.c new file mode 100644 index 00000000000..7bf6dcc2e32 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_tex_getimage.c @@ -0,0 +1,95 @@ +/* + * 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 "radeon_common_context.h" +#include "radeon_texture.h" +#include "radeon_mipmap_tree.h" + +#include "main/texgetimage.h" + +/** + * Need to map texture image into memory before copying image data, + * then unmap it. + */ +static void +radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, int compressed) +{ + radeon_texture_image *image = get_radeon_texture_image(texImage); + + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p, tex %p, image %p) compressed %d.\n", + __func__, ctx, texObj, image, compressed); + + if (image->mt) { + /* Map the texture image read-only */ + radeon_teximage_map(image, GL_FALSE); + } else { + /* Image hasn't been uploaded to a miptree yet */ + assert(image->base.Data); + } + + if (compressed) { + /* FIXME: this can't work for small textures (mips) which + use different hw stride */ + _mesa_get_compressed_teximage(ctx, target, level, pixels, + texObj, texImage); + } else { + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + } + + if (image->mt) { + radeon_teximage_unmap(image); + } +} + +void +radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_get_tex_image(ctx, target, level, format, type, pixels, + texObj, texImage, 0); +} + +void +radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_get_tex_image(ctx, target, level, 0, 0, pixels, + texObj, texImage, 1); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 62dec2d4e06..6a8e70d47e6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -39,7 +39,6 @@ #include "main/texstore.h" #include "main/teximage.h" #include "main/texobj.h" -#include "main/texgetimage.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -998,62 +997,3 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, format, type, pixels, packing, texObj, texImage, 0); } - -/** - * Need to map texture image into memory before copying image data, - * then unmap it. - */ -static void -radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, int compressed) -{ - radeon_texture_image *image = get_radeon_texture_image(texImage); - - radeon_print(RADEON_TEXTURE, RADEON_NORMAL, - "%s(%p, tex %p, image %p) compressed %d.\n", - __func__, ctx, texObj, image, compressed); - - if (image->mt) { - /* Map the texture image read-only */ - radeon_teximage_map(image, GL_FALSE); - } else { - /* Image hasn't been uploaded to a miptree yet */ - assert(image->base.Data); - } - - if (compressed) { - /* FIXME: this can't work for small textures (mips) which - use different hw stride */ - _mesa_get_compressed_teximage(ctx, target, level, pixels, - texObj, texImage); - } else { - _mesa_get_teximage(ctx, target, level, format, type, pixels, - texObj, texImage); - } - - if (image->mt) { - radeon_teximage_unmap(image); - } -} - -void -radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_get_tex_image(ctx, target, level, format, type, pixels, - texObj, texImage, 0); -} - -void -radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, - GLvoid *pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_get_tex_image(ctx, target, level, 0, 0, pixels, - texObj, texImage, 1); -} -- cgit v1.2.3 From b1ab15c633b9307cf6e17b794949f9c7f4dc4226 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Mar 2010 13:09:47 +0100 Subject: r300: remove unnecessary code _tnl_UpdateFixedFunctionProgram is already called in r300_draw.c --- src/mesa/drivers/dri/r300/r300_state.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 9d1ff6e2ba2..ba4a963d409 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1985,23 +1985,6 @@ void r300UpdateShaders(r300ContextPtr rmesa) if (rmesa->options.hw_tcl_enabled) { struct r300_vertex_program *vp; - if (rmesa->radeon.NewGLState) { - int i; - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - rmesa->temp_attrib[i] = - TNL_CONTEXT(ctx)->vb.AttribPtr[i]; - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - &rmesa->dummy_attrib[i]; - } - - _tnl_UpdateFixedFunctionProgram(ctx); - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - rmesa->temp_attrib[i]; - } - } - vp = r300SelectAndTranslateVertexShader(ctx); r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error); -- cgit v1.2.3 From 44d92d4bbe7d4e90f9d7bb97af2fd74cbda3b2ee Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Mar 2010 13:18:11 +0100 Subject: r300: no need to flush on context init --- src/mesa/drivers/dri/r300/r300_state.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index ba4a963d409..6c2c367aabc 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1762,8 +1762,6 @@ static void r300ResetHwState(r300ContextPtr r300) if (RADEON_DEBUG & RADEON_STATE) fprintf(stderr, "%s\n", __FUNCTION__); - radeon_firevertices(&r300->radeon); - r300ColorMask(ctx, ctx->Color.ColorMask[0][RCOMP], ctx->Color.ColorMask[0][GCOMP], -- cgit v1.2.3 From 77ed4d1f5d2f73ec02478eb931296813c25b520c Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Mar 2010 13:39:13 +0100 Subject: r300: recalculate point size, if point min/max size changes Fixes two wine d3d9 unit tests --- src/mesa/drivers/dri/r300/r300_state.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 6c2c367aabc..5a056f018d1 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -794,12 +794,14 @@ static void r300PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * pa R300_STATECHANGE(r300, ga_point_minmax); r300->hw.ga_point_minmax.cmd[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK; r300->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MinSize * 6.0); + r300PointSize(ctx, ctx->Point.Size); break; case GL_POINT_SIZE_MAX: R300_STATECHANGE(r300, ga_point_minmax); r300->hw.ga_point_minmax.cmd[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK; r300->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MaxSize * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT; + r300PointSize(ctx, ctx->Point.Size); break; case GL_POINT_DISTANCE_ATTENUATION: break; -- cgit v1.2.3 From 2872c1cc328008dea166319f3023a3f568247bcf Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 7 Mar 2010 12:02:28 +0100 Subject: r300: VAP flush is needed only when vertex program or constants are changed --- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 21 +-------------------- src/mesa/drivers/dri/r300/r300_context.h | 1 - src/mesa/drivers/dri/r300/r300_state.c | 1 - src/mesa/drivers/dri/r300/r300_vertprog.c | 4 +--- 4 files changed, 2 insertions(+), 25 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 4787bafc66a..6cfa5686f4a 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -90,8 +90,7 @@ void r300_emit_vpu(struct r300_context *r300, { BATCH_LOCALS(&r300->radeon); - BEGIN_BATCH_NO_AUTOSTATE(5 + len); - OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0); + BEGIN_BATCH_NO_AUTOSTATE(3 + len); OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr); OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, len-1) | RADEON_ONE_REG_WR); OUT_BATCH_TABLE(data, len); @@ -778,24 +777,6 @@ void r300InitCmdBuf(r300ContextPtr r300) /* VPU only on TCL */ if (has_tcl) { int i; - if (r300->radeon.radeonScreen->kernel_mm) { - ALLOC_STATE(vap_flush, always, 10, 0); - /* flush processing vertices */ - r300->hw.vap_flush.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); - r300->hw.vap_flush.cmd[1] = 0; - r300->hw.vap_flush.cmd[2] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DSTCACHE_CTLSTAT, 1); - r300->hw.vap_flush.cmd[3] = R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D; - r300->hw.vap_flush.cmd[4] = cmdpacket0(r300->radeon.radeonScreen, RADEON_WAIT_UNTIL, 1); - r300->hw.vap_flush.cmd[5] = RADEON_WAIT_3D_IDLECLEAN; - r300->hw.vap_flush.cmd[6] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); - r300->hw.vap_flush.cmd[7] = 0xffffff; - r300->hw.vap_flush.cmd[8] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1); - r300->hw.vap_flush.cmd[9] = 0; - } else { - ALLOC_STATE(vap_flush, never, 10, 0); - } - - ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); r300->hw.vpi.cmd[0] = cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 78ab43a99f9..df7115e7dae 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -355,7 +355,6 @@ struct r300_hw_state { struct radeon_state_atom zb_hiz_offset; /* (4F44) */ struct radeon_state_atom zb_hiz_pitch; /* (4F54) */ - struct radeon_state_atom vap_flush; struct radeon_state_atom vpi; /* vp instructions */ struct radeon_state_atom vpp; /* vp parameters */ struct radeon_state_atom vps; /* vertex point size (?) */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5a056f018d1..5979dedac4f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -366,7 +366,6 @@ static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) p = (GLint) plane - (GLint) GL_CLIP_PLANE0; ip = (GLint *)ctx->Transform._ClipUserPlane[p]; - R300_STATECHANGE( rmesa, vap_flush ); R300_STATECHANGE( rmesa, vpucp[p] ); rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0]; rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1]; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index cbe4cb83047..129004fee78 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -342,8 +342,6 @@ static void r300EmitVertexProgram(r300ContextPtr r300, int dest, struct r300_ver assert((code->length > 0) && (code->length % 4 == 0)); - R300_STATECHANGE( r300, vap_flush ); - switch ((dest >> 8) & 0xf) { case 0: R300_STATECHANGE(r300, vpi); @@ -381,7 +379,7 @@ void r300SetupVertexProgram(r300ContextPtr rmesa) ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; - R300_STATECHANGE(rmesa, vap_flush); + R300_STATECHANGE(rmesa, vap_cntl); R300_STATECHANGE(rmesa, vpp); param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); bump_vpu_count(rmesa->hw.vpp.cmd, param_count); -- cgit v1.2.3 From 62b3321d7d9774ed235bc3d328b6a0f5da153dcf Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 6 Feb 2010 18:25:36 +0100 Subject: r300: reset bos when validating buffers during blit --- src/mesa/drivers/dri/r300/r300_blit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index 2bc761bc208..f9c085e2832 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -381,6 +381,9 @@ static GLboolean validate_buffers(struct r300_context *r300, struct radeon_bo *dst_bo) { int ret; + + radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs); + ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, src_bo, RADEON_GEM_DOMAIN_VRAM, 0); if (ret) -- cgit v1.2.3 From 4572ae1925e63227b2785fec446862d398ad0005 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Thu, 4 Mar 2010 18:35:55 +0100 Subject: r300: allow src and dst BOs to be placed in GTT during blit Fixes some relocation failures --- src/mesa/drivers/dri/r300/r300_blit.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index f9c085e2832..d870c7f852a 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -385,18 +385,12 @@ static GLboolean validate_buffers(struct r300_context *r300, radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs); ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, - src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); if (ret) return GL_FALSE; ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, - dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); - if (ret) - return GL_FALSE; - - ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, - first_elem(&r300->radeon.dma.reserved)->bo, - RADEON_GEM_DOMAIN_GTT, 0); + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT); if (ret) return GL_FALSE; -- cgit v1.2.3 From b3b6bd5da1241086bda75431ddde6002e9353268 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 14 Feb 2010 00:02:05 +0100 Subject: r300: don't enable EXT_packed_depth_stencil R300 hw doesn't support sampling from Z24_S8 or S8_Z24 formats. --- src/mesa/drivers/dri/r300/r300_context.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index df4cc11da42..ff35cd52753 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -109,7 +109,6 @@ static const struct dri_extension card_extensions[] = { {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_packed_depth_stencil", NULL}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions}, {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions }, @@ -456,6 +455,9 @@ static void r300InitGLExtensions(GLcontext *ctx) } if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV350) _mesa_enable_extension(ctx, "GL_ARB_half_float_vertex"); + + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + _mesa_enable_extension(ctx, "GL_EXT_packed_depth_stencil"); } static void r300InitIoctlFuncs(struct dd_function_table *functions) -- cgit v1.2.3 From ac2b7835d5e61629f0a1f8b6c35eb1efa2ffbfa2 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Tue, 9 Mar 2010 21:41:00 +0100 Subject: radeon: add hw accelerated glReadPixel support (not enabled yet) --- src/mesa/drivers/dri/r200/Makefile | 1 + src/mesa/drivers/dri/r200/radeon_pixel_read.c | 1 + src/mesa/drivers/dri/r300/Makefile | 3 +- src/mesa/drivers/dri/r300/radeon_pixel_read.c | 1 + src/mesa/drivers/dri/r600/Makefile | 3 +- src/mesa/drivers/dri/r600/radeon_pixel_read.c | 1 + src/mesa/drivers/dri/radeon/Makefile | 1 + src/mesa/drivers/dri/radeon/radeon_common.h | 6 + src/mesa/drivers/dri/radeon/radeon_pixel_read.c | 188 ++++++++++++++++++++++++ 9 files changed, 203 insertions(+), 2 deletions(-) create mode 120000 src/mesa/drivers/dri/r200/radeon_pixel_read.c create mode 120000 src/mesa/drivers/dri/r300/radeon_pixel_read.c create mode 120000 src/mesa/drivers/dri/r600/radeon_pixel_read.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_pixel_read.c (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 3f871005705..9ea81fd5059 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -21,6 +21,7 @@ RADEON_COMMON_SOURCES = \ radeon_fbo.c \ radeon_lock.c \ radeon_mipmap_tree.c \ + radeon_pixel_read.c \ radeon_queryobj.c \ radeon_span.c \ radeon_texture.c \ diff --git a/src/mesa/drivers/dri/r200/radeon_pixel_read.c b/src/mesa/drivers/dri/r200/radeon_pixel_read.c new file mode 120000 index 00000000000..3b03803126f --- /dev/null +++ b/src/mesa/drivers/dri/r200/radeon_pixel_read.c @@ -0,0 +1 @@ +../radeon/radeon_pixel_read.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 4257a32b89f..2245998c952 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -31,8 +31,9 @@ RADEON_COMMON_SOURCES = \ radeon_fbo.c \ radeon_lock.c \ radeon_mipmap_tree.c \ - radeon_span.c \ + radeon_pixel_read.c \ radeon_queryobj.c \ + radeon_span.c \ radeon_texture.c \ radeon_tex_copy.c \ radeon_tex_getimage.c \ diff --git a/src/mesa/drivers/dri/r300/radeon_pixel_read.c b/src/mesa/drivers/dri/r300/radeon_pixel_read.c new file mode 120000 index 00000000000..3b03803126f --- /dev/null +++ b/src/mesa/drivers/dri/r300/radeon_pixel_read.c @@ -0,0 +1 @@ +../radeon/radeon_pixel_read.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile index f76859d11e2..17915621ee4 100644 --- a/src/mesa/drivers/dri/r600/Makefile +++ b/src/mesa/drivers/dri/r600/Makefile @@ -31,9 +31,10 @@ RADEON_COMMON_SOURCES = \ radeon_fbo.c \ radeon_lock.c \ radeon_mipmap_tree.c \ + radeon_pixel_read.c \ + radeon_queryobj.c \ radeon_span.c \ radeon_texture.c \ - radeon_queryobj.c \ radeon_tex_copy.c \ radeon_tex_getimage.c \ radeon_tile.c diff --git a/src/mesa/drivers/dri/r600/radeon_pixel_read.c b/src/mesa/drivers/dri/r600/radeon_pixel_read.c new file mode 120000 index 00000000000..3b03803126f --- /dev/null +++ b/src/mesa/drivers/dri/r600/radeon_pixel_read.c @@ -0,0 +1 @@ +../radeon/radeon_pixel_read.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 6904ebbee3b..19df62742ec 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -22,6 +22,7 @@ RADEON_COMMON_SOURCES = \ radeon_fbo.c \ radeon_lock.c \ radeon_mipmap_tree.c \ + radeon_pixel_read.c \ radeon_queryobj.c \ radeon_span.c \ radeon_texture.c \ diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index cd01c9984e3..35b3f08fff9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -44,6 +44,12 @@ radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, struct radeon_renderbuffer * radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv); +void +radeonReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels); + void radeon_check_front_buffer_rendering(GLcontext *ctx); static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) { diff --git a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c new file mode 100644 index 00000000000..27841938e66 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2010 Maciej Cencora + * + * 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/image.h" +#include "main/state.h" +#include "swrast/swrast.h" + +#include "radeon_common_context.h" +#include "radeon_debug.h" +#include "radeon_mipmap_tree.h" + +static gl_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_RGB565; + case GL_UNSIGNED_SHORT_5_6_5_REV: + return MESA_FORMAT_RGB565_REV; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_BYTE: + return MESA_FORMAT_RGBA8888_REV; + case GL_FLOAT: + return MESA_FORMAT_RGBA_FLOAT32; + case GL_UNSIGNED_SHORT_4_4_4_4: + return MESA_FORMAT_ARGB4444; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return MESA_FORMAT_ARGB4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + return MESA_FORMAT_RGBA5551; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return MESA_FORMAT_ARGB1555_REV; + case GL_UNSIGNED_INT_8_8_8_8: + return MESA_FORMAT_ARGB8888; + case GL_UNSIGNED_INT_8_8_8_8_REV: + return MESA_FORMAT_ARGB8888_REV; + } + break; + } + + return MESA_FORMAT_NONE; +} + +static GLboolean +do_blit_readpixels(GLcontext * 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 gl_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; + + /* 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) || !radeon->vtbl.blit) { + return GL_FALSE; + } + + if (ctx->_ImageTransferState) { + 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); + dst_imagesize = get_texture_image_size(dst_format, + aligned_rowstride, + height, 1, 0); + dst_buffer = radeon_bo_open(radeon->radeonScreen->bom, 0, dst_imagesize, 1024, RADEON_GEM_DOMAIN_GTT, 0); + + /* Disable source Y flipping for FBOs */ + flip_y = (ctx->ReadBuffer->Name == 0); + if (pack->Invert) { + y = rrb->base.Height - height - y; + flip_y = !flip_y; + } + + if (radeon->vtbl.blit(ctx, + rrb->bo, + rrb->draw_offset, + rrb->base.Format, + rrb->pitch / rrb->cpp, + rrb->base.Width, + rrb->base.Height, + x, + y, + dst_buffer, + 0, /* dst_offset */ + dst_format, + aligned_rowstride / _mesa_get_format_bytes(dst_format), + width, + height, + 0, /* dst_x */ + 0, /* dst_y */ + width, + height, + flip_y)) + { + radeon_bo_map(dst_buffer, 0); + dst_rowstride *= _mesa_get_format_bytes(dst_format); + 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; + } else { + radeon_bo_unref(dst_buffer); + return GL_FALSE; + } +} + +void +radeonReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels)) + return; + + /* Update Mesa state before calling down into _swrast_ReadPixels, as + * the spans code requires the computed buffer states to be up to date, + * but _swrast_ReadPixels only updates Mesa state after setting up + * the spans code. + */ + + radeon_print(RADEON_FALLBACKS, RADEON_NORMAL, + "Falling back to sw for ReadPixels (format %s, type %s)\n", + _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); + + if (ctx->NewState) + _mesa_update_state(ctx); + + _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); +} -- cgit v1.2.3 From 67108b5d12e0526ebedcdf2dbeeadfdbd0782161 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Tue, 9 Mar 2010 21:42:00 +0100 Subject: r300: enable HW accelerated gl(Read/Copy/Draw)Pixels --- src/mesa/drivers/dri/r300/r300_state.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5979dedac4f..8739dcbafbb 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "main/api_arrayelt.h" +#include "drivers/common/meta.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "shader/prog_parameter.h" @@ -2326,8 +2327,12 @@ void r300InitStateFuncs(struct dd_function_table *functions) functions->ClipPlane = r300ClipPlane; functions->Scissor = radeonScissor; - functions->DrawBuffer = radeonDrawBuffer; - functions->ReadBuffer = radeonReadBuffer; + functions->DrawBuffer = radeonDrawBuffer; + functions->ReadBuffer = radeonReadBuffer; + + functions->CopyPixels = _mesa_meta_CopyPixels; + functions->DrawPixels = _mesa_meta_DrawPixels; + functions->ReadPixels = radeonReadPixels; } void r300InitShaderFunctions(r300ContextPtr r300) -- cgit v1.2.3 From a17563c7ddfa58fe7f09d22a62a10f3488ef3147 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 7 Mar 2010 14:34:21 +0100 Subject: radeon/r200/r300/r600: add is_format_renderable function --- src/mesa/drivers/dri/r200/r200_context.c | 1 + src/mesa/drivers/dri/r300/r300_context.c | 6 ++++ src/mesa/drivers/dri/r300/r300_tex.c | 39 ++++++++++++++++++++++ src/mesa/drivers/dri/r300/r300_tex.h | 3 ++ src/mesa/drivers/dri/r600/r600_context.c | 1 + .../drivers/dri/radeon/radeon_common_context.h | 1 + src/mesa/drivers/dri/radeon/radeon_context.c | 1 + src/mesa/drivers/dri/radeon/radeon_texture.c | 16 +++++++++ src/mesa/drivers/dri/radeon/radeon_texture.h | 2 ++ 9 files changed, 70 insertions(+) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index dad2580e08b..4f1a56658cc 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -266,6 +266,7 @@ static void r200_init_vtbl(radeonContextPtr radeon) radeon->vtbl.emit_query_finish = r200_emit_query_finish; radeon->vtbl.check_blit = r200_check_blit; radeon->vtbl.blit = r200_blit; + radeon->vtbl.is_format_renderable = radeonIsFormatRenderable; } diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index ff35cd52753..364e0ba6b61 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -321,6 +321,12 @@ static void r300_init_vtbl(radeonContextPtr radeon) radeon->vtbl.check_blit = r300_check_blit; radeon->vtbl.blit = r300_blit; + + if (radeon->radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + radeon->vtbl.is_format_renderable = r500IsFormatRenderable; + } else { + radeon->vtbl.is_format_renderable = r300IsFormatRenderable; + } } static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 8dd85073954..baef206bc26 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -308,6 +308,45 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, return &t->base; } +unsigned r300IsFormatRenderable(gl_format mesa_format) +{ + switch (mesa_format) + { + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_XRGB8888_REV: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: + case MESA_FORMAT_SL8: + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_Z16: + return 1; + default: + return 0; + } +} + +unsigned r500IsFormatRenderable(gl_format mesa_format) +{ + if (mesa_format == MESA_FORMAT_S8_Z24) { + return 1; + } else { + return r300IsFormatRenderable(mesa_format); + } +} + void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index 9694e703b83..aca44cd7669 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -53,4 +53,7 @@ extern void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_tab int32_t r300TranslateTexFormat(gl_format mesaFormat); +unsigned r300IsFormatRenderable(gl_format mesaFormat); +unsigned r500IsFormatRenderable(gl_format mesaFormat); + #endif /* __r300_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 134e97e7c33..76d5027649e 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -239,6 +239,7 @@ static void r600_init_vtbl(radeonContextPtr radeon) radeon->vtbl.emit_query_finish = r600_emit_query_finish; radeon->vtbl.check_blit = r600_check_blit; radeon->vtbl.blit = r600_blit; + radeon->vtbl.is_format_renderable = radeonIsFormatRenderable; } static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen) diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index d1a24e265f2..5156c5d0d0a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -539,6 +539,7 @@ struct radeon_context { unsigned reg_width, unsigned reg_height, unsigned flip_y); + unsigned (*is_format_renderable)(gl_format mesa_format); } vtbl; }; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 878a453bd53..56aba16e9e0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -200,6 +200,7 @@ static void r100_init_vtbl(radeonContextPtr radeon) radeon->vtbl.emit_query_finish = r100_emit_query_finish; radeon->vtbl.check_blit = r100_check_blit; radeon->vtbl.blit = r100_blit; + radeon->vtbl.is_format_renderable = radeonIsFormatRenderable; } /* Create the device specific context. diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 3ccc711253b..2b655fbd953 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -1006,3 +1006,19 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, format, type, pixels, packing, texObj, texImage, 0); } + +unsigned radeonIsFormatRenderable(gl_format mesa_format) +{ + if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 || + mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444) + return 1; + + switch (mesa_format) + { + case MESA_FORMAT_Z16: + case MESA_FORMAT_S8_Z24: + return 1; + default: + return 0; + } +} diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h index f09dd652142..4ce639ea34e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.h +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -135,4 +135,6 @@ void radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, GLint x, GLint y, GLsizei width, GLsizei height); +unsigned radeonIsFormatRenderable(gl_format mesa_format); + #endif -- cgit v1.2.3 From fd05067c9912e7ee83058a48d6e4c2cd7f262665 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 7 Mar 2010 14:26:21 +0100 Subject: r300: add support for more rendering formats --- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 35 ++++++++++--------- src/mesa/drivers/dri/r300/r300_state.c | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 17 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 6cfa5686f4a..e2dbb1dbf40 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -332,36 +332,37 @@ void r300_emit_cb_setup(struct r300_context *r300, assert(offset % 32 == 0); switch (format) { - case MESA_FORMAT_RGB565: - assert(_mesa_little_endian()); - cbpitch |= R300_COLOR_FORMAT_RGB565; + case MESA_FORMAT_SL8: + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + cbpitch |= R300_COLOR_FORMAT_I8; break; + case MESA_FORMAT_RGB565: case MESA_FORMAT_RGB565_REV: - assert(!_mesa_little_endian()); cbpitch |= R300_COLOR_FORMAT_RGB565; break; case MESA_FORMAT_ARGB4444: - assert(_mesa_little_endian()); - cbpitch |= R300_COLOR_FORMAT_ARGB4444; - break; case MESA_FORMAT_ARGB4444_REV: - assert(!_mesa_little_endian()); cbpitch |= R300_COLOR_FORMAT_ARGB4444; break; + case MESA_FORMAT_RGBA5551: case MESA_FORMAT_ARGB1555: - assert(_mesa_little_endian()); - cbpitch |= R300_COLOR_FORMAT_ARGB1555; - break; case MESA_FORMAT_ARGB1555_REV: - assert(!_mesa_little_endian()); cbpitch |= R300_COLOR_FORMAT_ARGB1555; break; + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888_REV: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: + cbpitch |= R300_COLOR_FORMAT_ARGB8888; + break; default: - if (cpp == 4) { - cbpitch |= R300_COLOR_FORMAT_ARGB8888; - } else { - _mesa_problem(r300->radeon.glCtx, "unexpected format in emit_cb_offset()");; - } + _mesa_problem(r300->radeon.glCtx, "unexpected format in emit_cb_offset()"); break; } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 8739dcbafbb..bdd12c6d220 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2238,6 +2238,63 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) } } +#define EASY_US_OUT_FMT(comps, c0, c1, c2, c3) \ + (R500_OUT_FMT_##comps | R500_C0_SEL_##c0 | R500_C1_SEL_##c1 | \ + R500_C2_SEL_##c2 | R500_C3_SEL_##c3) +static void r300SetupUsOutputFormat(GLcontext *ctx) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + uint32_t hw_format; + + switch (radeon_get_colorbuffer(&rmesa->radeon)->base.Format) + { + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_RGBA8888: + hw_format = EASY_US_OUT_FMT(C4_8, A, B, G, R); + break; + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_RGBA8888_REV: + hw_format = EASY_US_OUT_FMT(C4_8, R, G, B, A); + break; + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + hw_format = EASY_US_OUT_FMT(C4_8, B, G, R, A); + break; + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_XRGB8888_REV: + case MESA_FORMAT_ARGB8888_REV: + hw_format = EASY_US_OUT_FMT(C4_8, A, R, G, B); + break; + case MESA_FORMAT_SRGBA8: + hw_format = EASY_US_OUT_FMT(C4_10_GAMMA, A, B, G, R); + break; + case MESA_FORMAT_SARGB8: + hw_format = EASY_US_OUT_FMT(C4_10_GAMMA, B, G, R, A); + break; + case MESA_FORMAT_SL8: + hw_format = EASY_US_OUT_FMT(C4_10_GAMMA, A, A, R, A); + break; + case MESA_FORMAT_A8: + hw_format = EASY_US_OUT_FMT(C4_8, A, A, A, A); + break; + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + hw_format = EASY_US_OUT_FMT(C4_8, A, A, R, A); + break; + default: + assert(!"Unsupported format"); + break; + } + + R300_STATECHANGE(rmesa, us_out_fmt); + rmesa->hw.us_out_fmt.cmd[1] = hw_format; +} +#undef EASY_US_OUT_FMT + /** * Called by Mesa after an internal state update. */ @@ -2267,6 +2324,10 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) r300->hw.shade2.cmd[1] &= ~R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; } + if (new_state & _NEW_BUFFERS) { + r300SetupUsOutputFormat(ctx); + } + r300->radeon.NewGLState |= new_state; } -- cgit v1.2.3 From eeaf1e0519912b2ca3a8bce56c35548f9e0b73ca Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Tue, 9 Mar 2010 23:13:19 +0100 Subject: r300: don't crash if there's no colorbuffer --- src/mesa/drivers/dri/r300/r300_state.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index bdd12c6d220..87489412419 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2245,8 +2245,13 @@ static void r300SetupUsOutputFormat(GLcontext *ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); uint32_t hw_format; + struct radeon_renderbuffer *rrb = radeon_get_colorbuffer(&rmesa->radeon); - switch (radeon_get_colorbuffer(&rmesa->radeon)->base.Format) + if (!rrb) { + return; + } + + switch (rrb->base.Format) { case MESA_FORMAT_RGBA5551: case MESA_FORMAT_RGBA8888: -- cgit v1.2.3 From addedd091e81907837b3aa0680b242b8fdbde7ef Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Wed, 10 Mar 2010 22:28:53 +0100 Subject: r300: enable depth test only if depth buffer is available Fixes #23532 and piglit/fbo-nodepth-test piglit/fbo-nostencil-test --- src/mesa/drivers/dri/r300/r300_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 87489412419..e75c88e101b 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -590,7 +590,7 @@ static void r300SetDepthState(GLcontext * ctx) R500_STENCIL_REFMASK_FRONT_BACK); r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT); - if (ctx->Depth.Test) { + if (ctx->Depth.Test && ctx->DrawBuffer->_DepthBuffer) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_ENABLE; if (ctx->Depth.Mask) r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_WRITE_ENABLE; -- cgit v1.2.3 From fab1f07d6ad01463897ae792f4b33738afb07369 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Fri, 13 Jun 2008 09:50:43 -0500 Subject: Grammar and spelling fixes Signed-off-by: Jeff Smith Signed-off-by: Brian Paul --- docs/README.3DFX | 2 +- docs/egl.html | 2 +- progs/objviewer/glm.c | 2 +- progs/objviewer/glm.h | 2 +- progs/tests/vao-01.c | 2 +- progs/tests/vao-02.c | 2 +- src/gallium/auxiliary/os/os_time.h | 2 +- src/gallium/drivers/cell/ppu/cell_gen_fragment.c | 2 +- src/gallium/drivers/cell/ppu/cell_spu.c | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 2 +- src/gallium/drivers/r300/r300_reg.h | 4 ++-- src/gallium/state_trackers/wgl/stw_framebuffer.h | 2 +- src/glu/sgi/libnurbs/nurbtess/partitionY.h | 2 +- src/glu/sgi/libtess/normal.c | 2 +- src/mesa/drivers/dri/common/dri_util.c | 2 +- src/mesa/drivers/dri/r128/r128_tex.c | 2 +- src/mesa/drivers/dri/r200/r200_reg.h | 2 +- src/mesa/drivers/dri/r300/r300_reg.h | 4 ++-- src/mesa/drivers/dri/radeon/radeon_state.c | 2 +- src/mesa/drivers/x11/xmesa.h | 2 +- src/mesa/drivers/x11/xmesaP.h | 2 +- src/mesa/main/dd.h | 2 +- src/mesa/main/texcompress_fxt1.c | 2 +- src/mesa/math/m_debug_util.h | 2 +- src/mesa/math/m_matrix.c | 2 +- src/mesa/shader/prog_instruction.h | 4 ++-- src/mesa/shader/program_parser.h | 2 +- src/mesa/shader/slang/library/slang_common_builtin.gc | 2 +- src/mesa/swrast/s_depth.c | 2 +- src/mesa/vbo/vbo_save_loopback.c | 2 +- 30 files changed, 33 insertions(+), 33 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/docs/README.3DFX b/docs/README.3DFX index 037e8fa7cc6..7feda6f33f7 100644 --- a/docs/README.3DFX +++ b/docs/README.3DFX @@ -644,7 +644,7 @@ Hints and Special Features: - The Voodoo driver supports the GL_EXT_paletted_texture. it works only with GL_COLOR_INDEX8_EXT, GL_RGBA palettes and the alpha value - is ignored because this is a limitation of the the current Glide + is ignored because this is a limitation of the current Glide version and of the Voodoo hardware. See Mesa-3.1/3Dfx/demos/paltex.c for a demo of this extension. diff --git a/docs/egl.html b/docs/egl.html index 82cc06600bd..55907f6cfac 100644 --- a/docs/egl.html +++ b/docs/egl.html @@ -28,7 +28,7 @@ cards.

  1. -

    Run configure with the desired state trackers and and enable +

    Run configure with the desired state trackers and enable the Gallium driver for your hardware. For example

    diff --git a/progs/objviewer/glm.c b/progs/objviewer/glm.c
    index 7c964e489d1..77e62bfab11 100644
    --- a/progs/objviewer/glm.c
    +++ b/progs/objviewer/glm.c
    @@ -1041,7 +1041,7 @@ glmFacetNormals(GLMmodel* model)
     
     /* glmVertexNormals: Generates smooth vertex normals for a model.
      * First builds a list of all the triangles each vertex is in.  Then
    - * loops through each vertex in the the list averaging all the facet
    + * loops through each vertex in the list averaging all the facet
      * normals of the triangles each vertex is in.  Finally, sets the
      * normal index in the triangle for the vertex to the generated smooth
      * normal.  If the dot product of a facet normal and the facet normal
    diff --git a/progs/objviewer/glm.h b/progs/objviewer/glm.h
    index 8740b3684df..1a5646fa4c7 100644
    --- a/progs/objviewer/glm.h
    +++ b/progs/objviewer/glm.h
    @@ -153,7 +153,7 @@ glmFacetNormals(GLMmodel* model);
     
     /* glmVertexNormals: Generates smooth vertex normals for a model.
      * First builds a list of all the triangles each vertex is in.  Then
    - * loops through each vertex in the the list averaging all the facet
    + * loops through each vertex in the list averaging all the facet
      * normals of the triangles each vertex is in.  Finally, sets the
      * normal index in the triangle for the vertex to the generated smooth
      * normal.  If the dot product of a facet normal and the facet normal
    diff --git a/progs/tests/vao-01.c b/progs/tests/vao-01.c
    index e4a89cb19db..ee528d22439 100644
    --- a/progs/tests/vao-01.c
    +++ b/progs/tests/vao-01.c
    @@ -30,7 +30,7 @@
      * it (via \c glPopClientAttrib).  After popping, the state of the VAO is
      * examined.
      * 
    - * According the the APPLE_vertex_array_object spec, the contents of the VAO
    + * According to the APPLE_vertex_array_object spec, the contents of the VAO
      * should be restored to the values that they had when pushed.
      * 
      * \author Ian Romanick 
    diff --git a/progs/tests/vao-02.c b/progs/tests/vao-02.c
    index 9f7f5c27792..c23b4ab05a6 100644
    --- a/progs/tests/vao-02.c
    +++ b/progs/tests/vao-02.c
    @@ -30,7 +30,7 @@
      * it (via \c glPopClientAttrib).  After popping, the state of the VAO is
      * examined.
      * 
    - * According the the APPLE_vertex_array_object spec, the contents of the VAO
    + * According to the APPLE_vertex_array_object spec, the contents of the VAO
      * should be restored to the values that they had when pushed.
      * 
      * \author Ian Romanick 
    diff --git a/src/gallium/auxiliary/os/os_time.h b/src/gallium/auxiliary/os/os_time.h
    index 5b55c1b3747..7e0f67a76b0 100644
    --- a/src/gallium/auxiliary/os/os_time.h
    +++ b/src/gallium/auxiliary/os/os_time.h
    @@ -71,7 +71,7 @@ os_time_sleep(int64_t usecs);
     /*
      * Helper function for detecting time outs, taking in account overflow.
      *
    - * Returns true the the current time has elapsed beyond the specified interval.
    + * Returns true if the current time has elapsed beyond the specified interval.
      */
     static INLINE boolean
     os_time_timeout(int64_t start,
    diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
    index 576d514741d..c54576b3c32 100644
    --- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
    +++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
    @@ -1352,7 +1352,7 @@ gen_stencil_values(struct spe_function *f,
         */
        ASSERT(fbS_reg != newS_reg);
     
    -   /* The code also assumes the the stencil_max_value is of the form 
    +   /* The code also assumes that the stencil_max_value is of the form
         * 2^n-1 and can therefore be used as a mask for the valid bits in 
         * addition to a maximum.  Make sure this is the case as well.
         * The clever math below exploits the fact that incrementing a 
    diff --git a/src/gallium/drivers/cell/ppu/cell_spu.c b/src/gallium/drivers/cell/ppu/cell_spu.c
    index 28e5e6d706d..39284f3a5d1 100644
    --- a/src/gallium/drivers/cell/ppu/cell_spu.c
    +++ b/src/gallium/drivers/cell/ppu/cell_spu.c
    @@ -135,7 +135,7 @@ cell_thread_function(void *arg)
     
     /**
      * Create the SPU threads.  This is done once during driver initialization.
    - * This involves setting the the "init" message which is sent to each SPU.
    + * This involves setting the "init" message which is sent to each SPU.
      * The init message specifies an SPU id, total number of SPUs, location
      * and number of batch buffers, etc.
      */
    diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
    index b289eef0fc2..c93c5d127c4 100644
    --- a/src/gallium/drivers/nv40/nv40_vertprog.c
    +++ b/src/gallium/drivers/nv40/nv40_vertprog.c
    @@ -742,7 +742,7 @@ nv40_vertprog_translate(struct nv40_context *nv40,
     	}
     
     	/* Redirect post-transform vertex position to a temp if user clip
    -	 * planes are enabled.  We need to append code the the vtxprog
    +	 * planes are enabled.  We need to append code to the vtxprog
     	 * to handle clip planes later.
     	 */
     	if (vp->ucp.nr)  {
    diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
    index a249e8b36be..c67cc868713 100644
    --- a/src/gallium/drivers/r300/r300_reg.h
    +++ b/src/gallium/drivers/r300/r300_reg.h
    @@ -540,7 +540,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
     #       define R300_PVS_FIRST_INST(x)            ((x) << 0)
     #       define R300_PVS_XYZW_VALID_INST(x)       ((x) << 10)
     #       define R300_PVS_LAST_INST(x)             ((x) << 20)
    -/* Addresses are relative the the vertex program parameters area. */
    +/* Addresses are relative to the vertex program parameters area. */
     #define R300_VAP_PVS_CONST_CNTL             0x22D4
     #       define R300_PVS_CONST_BASE_OFFSET_SHIFT  0
     #       define R300_PVS_MAX_CONST_ADDR_SHIFT     16
    @@ -1857,7 +1857,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
      * The destination register index is in FPI1 (color) and FPI3 (alpha)
      * together with enable bits.
      * There are separate enable bits for writing into temporary registers
    - * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_*
    + * (DSTC_REG_* /DSTA_REG) and program output registers (DSTC_OUTPUT_*
      * /DSTA_OUTPUT). You can write to both at once, or not write at all (the
      * same index must be used for both).
      *
    diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
    index 08cc4973bce..e61e9bf9c26 100644
    --- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
    +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
    @@ -45,7 +45,7 @@ struct stw_framebuffer
        /**
         * This mutex has two purposes:
         * - protect the access to the mutable data members below
    -    * - prevent the the framebuffer from being deleted while being accessed.
    +    * - prevent the framebuffer from being deleted while being accessed.
         * 
         * It is OK to lock this mutex while holding the stw_device::fb_mutex lock, 
         * but the opposite must never happen.
    diff --git a/src/glu/sgi/libnurbs/nurbtess/partitionY.h b/src/glu/sgi/libnurbs/nurbtess/partitionY.h
    index 8dda409de1a..5570c183d79 100644
    --- a/src/glu/sgi/libnurbs/nurbtess/partitionY.h
    +++ b/src/glu/sgi/libnurbs/nurbtess/partitionY.h
    @@ -39,7 +39,7 @@
      *or both at or below v. In addition, at least one of the ajacent verteces is
      *strictly below or above v. 
      * A vertex is a relex vertex if the internals angle is strictly greater than 
    - *180. In other words, if the the signed area is negative:
    + *180. In other words, if the signed area is negative:
      *(x1, y1), (x2, y2), (x3, y3) are the three vertices along a polygon, the 
      *order is such that left hand side is inside the polygon. Then (x2,y2) is
      *reflex if: 
    diff --git a/src/glu/sgi/libtess/normal.c b/src/glu/sgi/libtess/normal.c
    index 0a2494be343..7ab83167bbd 100644
    --- a/src/glu/sgi/libtess/normal.c
    +++ b/src/glu/sgi/libtess/normal.c
    @@ -142,7 +142,7 @@ static void CheckOrientation( GLUtesselator *tess )
       GLUhalfEdge *e;
     
       /* When we compute the normal automatically, we choose the orientation
    -   * so that the the sum of the signed areas of all contours is non-negative.
    +   * so that the sum of the signed areas of all contours is non-negative.
        */
       area = 0;
       for( f = fHead->next; f != fHead; f = f->next ) {
    diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
    index 890ae513397..75c98825b79 100644
    --- a/src/mesa/drivers/dri/common/dri_util.c
    +++ b/src/mesa/drivers/dri/common/dri_util.c
    @@ -698,7 +698,7 @@ setupLoaderExtensions(__DRIscreen *psp,
      * \param drm_version Version of the kernel DRM.
      * \param frame_buffer Data describing the location and layout of the
      *                     framebuffer.
    - * \param pSAREA       Pointer the the SAREA.
    + * \param pSAREA       Pointer to the SAREA.
      * \param fd           Device handle for the DRM.
      * \param extensions   ??
      * \param driver_modes  Returns modes suppoted by the driver
    diff --git a/src/mesa/drivers/dri/r128/r128_tex.c b/src/mesa/drivers/dri/r128/r128_tex.c
    index 24fbf8f5194..4ec4be9a47b 100644
    --- a/src/mesa/drivers/dri/r128/r128_tex.c
    +++ b/src/mesa/drivers/dri/r128/r128_tex.c
    @@ -468,7 +468,7 @@ static void r128TexEnv( GLcontext *ctx, GLenum target,
     	  * certain point.  It is better than completely ignoring the LOD
     	  * bias.  Unfortunately there isn't much range in the bias, the
     	  * spec mentions strides that vary between 0.5 and 2.0 but these
    -	  * numbers don't seem to relate the the GL LOD bias value at all.
    +	  * numbers don't seem to relate to the GL LOD bias value at all.
     	  */
     	 if ( param[0] >= 1.0 ) {
     	    bias = -128;
    diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h
    index 59115212cee..b3a4940a7ad 100644
    --- a/src/mesa/drivers/dri/r200/r200_reg.h
    +++ b/src/mesa/drivers/dri/r200/r200_reg.h
    @@ -690,7 +690,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     #       define R200_PVS_CNTL_1_PROGRAM_START_SHIFT   0
     #       define R200_PVS_CNTL_1_POS_END_SHIFT         10
     #       define R200_PVS_CNTL_1_PROGRAM_END_SHIFT     20
    -/* Addresses are relative the the vertex program parameters area. */
    +/* Addresses are relative to the vertex program parameters area. */
     #define R200_VAP_PVS_CNTL_2                 0x22d4
     #       define R200_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
     #       define R200_PVS_CNTL_2_PARAM_COUNT_SHIFT  16
    diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
    index d18ebab8ff2..ac93563ed9e 100644
    --- a/src/mesa/drivers/dri/r300/r300_reg.h
    +++ b/src/mesa/drivers/dri/r300/r300_reg.h
    @@ -482,7 +482,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
     #       define R300_PVS_FIRST_INST_SHIFT         0
     #       define R300_PVS_XYZW_VALID_INST_SHIFT    10
     #       define R300_PVS_LAST_INST_SHIFT          20
    -/* Addresses are relative the the vertex program parameters area. */
    +/* Addresses are relative to the vertex program parameters area. */
     #define R300_VAP_PVS_CONST_CNTL             0x22D4
     #       define R300_PVS_CONST_BASE_OFFSET_SHIFT  0
     #       define R300_PVS_MAX_CONST_ADDR_SHIFT     16
    @@ -1760,7 +1760,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
      * The destination register index is in FPI1 (color) and FPI3 (alpha)
      * together with enable bits.
      * There are separate enable bits for writing into temporary registers
    - * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_*
    + * (DSTC_REG_* /DSTA_REG) and program output registers (DSTC_OUTPUT_*
      * /DSTA_OUTPUT). You can write to both at once, or not write at all (the
      * same index must be used for both).
      *
    diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
    index 0ce97e86972..583751d64df 100644
    --- a/src/mesa/drivers/dri/radeon/radeon_state.c
    +++ b/src/mesa/drivers/dri/radeon/radeon_state.c
    @@ -1900,7 +1900,7 @@ void radeonUploadTexMatrix( r100ContextPtr rmesa,
        So: if we need the q coord in the end (solely determined by the texture
        target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
        Additionally, if we don't have texgen but 4 tex coords submitted, we swap
    -   column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
    +   column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
        will get submitted in the "wrong", i.e. 3rd, slot.
        If an app submits 3 coords for 2d targets, we assume it is saving on vertex
        size and using the texture matrix to swap the r and q coords around (ut2k3
    diff --git a/src/mesa/drivers/x11/xmesa.h b/src/mesa/drivers/x11/xmesa.h
    index 98139af8336..f63626a9702 100644
    --- a/src/mesa/drivers/x11/xmesa.h
    +++ b/src/mesa/drivers/x11/xmesa.h
    @@ -287,7 +287,7 @@ extern void XMesaCopySubBuffer( XMesaBuffer b,
     
     
     /*
    - * Return a pointer to the the Pixmap or XImage being used as the back
    + * Return a pointer to the Pixmap or XImage being used as the back
      * color buffer of an XMesaBuffer.  This function is a way to get "under
      * the hood" of X/Mesa so one can manipulate the back buffer directly.
      * Input:  b - the XMesaBuffer
    diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
    index 3ffd7661e35..e0a6908228d 100644
    --- a/src/mesa/drivers/x11/xmesaP.h
    +++ b/src/mesa/drivers/x11/xmesaP.h
    @@ -431,7 +431,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
      * If pixelformat==PF_HPCR:
      *
      *      HP Color Recovery dithering               (ad@lms.be 30/08/95)
    - *      HP has on it's 8-bit 700-series computers, a feature called
    + *      HP has on its 8-bit 700-series computers, a feature called
      *      'Color Recovery'.  This allows near 24-bit output (so they say).
      *      It is enabled by selecting the 8-bit  TrueColor  visual AND
      *      corresponding  colormap (see tkInitWindow) AND doing some special
    diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
    index 197de09b22a..7c02faaa535 100644
    --- a/src/mesa/main/dd.h
    +++ b/src/mesa/main/dd.h
    @@ -1072,7 +1072,7 @@ struct dd_function_table {
      * These are the initial values to be installed into dispatch by
      * mesa.  If the T&L driver wants to modify the dispatch table
      * while installed, it must do so itself.  It would be possible for
    - * the vertexformat to install it's own initial values for these
    + * the vertexformat to install its own initial values for these
      * functions, but this way there is an obvious list of what is
      * expected of the driver.
      *
    diff --git a/src/mesa/main/texcompress_fxt1.c b/src/mesa/main/texcompress_fxt1.c
    index 149853f7acd..04acf05e528 100644
    --- a/src/mesa/main/texcompress_fxt1.c
    +++ b/src/mesa/main/texcompress_fxt1.c
    @@ -476,7 +476,7 @@ fxt1_lloyd (GLfloat vec[][MAX_COMP], GLint nv,
         *     for each sample color
         *         sort to nearest vector.
         *
    -    *     replace each vector with the centroid of it's matching colors.
    +    *     replace each vector with the centroid of its matching colors.
         *
         *     repeat until RMS doesn't improve.
         *
    diff --git a/src/mesa/math/m_debug_util.h b/src/mesa/math/m_debug_util.h
    index 2e67db8e55d..ed11c849ece 100644
    --- a/src/mesa/math/m_debug_util.h
    +++ b/src/mesa/math/m_debug_util.h
    @@ -61,7 +61,7 @@ extern long counter_overhead;
      */
     extern char *mesa_profile;
     
    -/* Modify the the number of tests if you like.
    +/* Modify the number of tests if you like.
      * We take the minimum of all results, because every error should be
      * positive (time used by other processes, task switches etc).
      * It is assumed that all calculations are done in the cache.
    diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c
    index ef8a40fbecb..4b33d0bbb37 100644
    --- a/src/mesa/math/m_matrix.c
    +++ b/src/mesa/math/m_matrix.c
    @@ -889,7 +889,7 @@ _math_matrix_rotate( GLmatrix *mat,
            *  Y-axis to bring the axis vector parallel with the X-axis.  The
            *  rotation about the X-axis is then performed.  Ry and Rz are
            *  simply the respective inverse transforms to bring the arbitrary
    -       *  axis back to it's original orientation.  The first transforms
    +       *  axis back to its original orientation.  The first transforms
            *  Rz' and Ry' are considered inverses, since the data from the
            *  arbitrary axis gives you info on how to get to it, not how
            *  to get away from it, and an inverse must be applied.
    diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
    index 224350caac6..28c797a4ba8 100644
    --- a/src/mesa/shader/prog_instruction.h
    +++ b/src/mesa/shader/prog_instruction.h
    @@ -97,8 +97,8 @@
     #define COND_EQ  2  /**< equal to zero */
     #define COND_LT  3  /**< less than zero */
     #define COND_UN  4  /**< unordered (NaN) */
    -#define COND_GE  5  /**< greater then or equal to zero */
    -#define COND_LE  6  /**< less then or equal to zero */
    +#define COND_GE  5  /**< greater than or equal to zero */
    +#define COND_LE  6  /**< less than or equal to zero */
     #define COND_NE  7  /**< not equal to zero */
     #define COND_TR  8  /**< always true */
     #define COND_FL  9  /**< always false */
    diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h
    index 730466c30f5..be952d4b9c8 100644
    --- a/src/mesa/shader/program_parser.h
    +++ b/src/mesa/shader/program_parser.h
    @@ -62,7 +62,7 @@ struct asm_symbol {
         */
        unsigned param_binding_swizzle;
     
    -   /* This is how many entries in the the program_parameter_list we take up
    +   /* This is how many entries in the program_parameter_list we take up
         * with our state tokens or constants. Note that this is _not_ the same as
         * the number of param registers we eventually use.
         */
    diff --git a/src/mesa/shader/slang/library/slang_common_builtin.gc b/src/mesa/shader/slang/library/slang_common_builtin.gc
    index 8b7771c2846..a25ca55bc42 100644
    --- a/src/mesa/shader/slang/library/slang_common_builtin.gc
    +++ b/src/mesa/shader/slang/library/slang_common_builtin.gc
    @@ -695,7 +695,7 @@ vec3 normalize(const vec3 v)
     {
     //   const float s = inversesqrt(dot(v, v));
     //   __retVal = v * s;
    -// XXX note, we _could_ use __retVal.w instead of tmp and and save a
    +// XXX note, we _could_ use __retVal.w instead of tmp and save a
     // register, but that's actually a compilation error because v is a vec3
     // and the .w suffix is illegal.  Oh well.
        float tmp;
    diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
    index 3e36cf9a7e5..ed637cac124 100644
    --- a/src/mesa/swrast/s_depth.c
    +++ b/src/mesa/swrast/s_depth.c
    @@ -526,7 +526,7 @@ _swrast_depth_clamp_span( GLcontext *ctx, SWspan *span )
     
        /* Convert floating point values in [0,1] to device Z coordinates in
         * [0, DepthMax].
    -    * ex: If the the Z buffer has 24 bits, DepthMax = 0xffffff.
    +    * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
         * 
         * XXX this all falls apart if we have 31 or more bits of Z because
         * the triangle rasterization code produces unsigned Z values.  Negative
    diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c
    index f253c854d2b..3f581ea02da 100644
    --- a/src/mesa/vbo/vbo_save_loopback.c
    +++ b/src/mesa/vbo/vbo_save_loopback.c
    @@ -78,7 +78,7 @@ struct loopback_attr {
     };
     
     /* Don't emit ends and begins on wrapped primitives.  Don't replay
    - * wrapped vertices.  If we get here, it's probably because the the
    + * wrapped vertices.  If we get here, it's probably because the
      * precalculated wrapping is wrong.
      */
     static void loopback_prim( GLcontext *ctx,
    -- 
    cgit v1.2.3
    
    
    From d1ca1599f0319f5c99852ce24420aa592e806db0 Mon Sep 17 00:00:00 2001
    From: Alex Deucher 
    Date: Fri, 12 Mar 2010 11:16:50 -0500
    Subject: r100/r200/r300/r300: only enable accelerated pixel ops with kms
    
    fixes fdo bug 27043
    ---
     src/mesa/drivers/dri/r200/r200_context.c   |  2 +-
     src/mesa/drivers/dri/r200/r200_state.c     | 11 +++++++----
     src/mesa/drivers/dri/r200/r200_state.h     |  2 +-
     src/mesa/drivers/dri/r300/r300_context.c   |  2 +-
     src/mesa/drivers/dri/r300/r300_state.c     | 10 ++++++----
     src/mesa/drivers/dri/r300/r300_state.h     |  2 +-
     src/mesa/drivers/dri/r600/r600_context.c   |  2 +-
     src/mesa/drivers/dri/r600/r700_state.c     | 11 ++++++-----
     src/mesa/drivers/dri/r600/r700_state.h     |  2 +-
     src/mesa/drivers/dri/radeon/radeon_state.c |  8 +++++---
     10 files changed, 30 insertions(+), 22 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
    index 5739443bdf2..36a29350ccc 100644
    --- a/src/mesa/drivers/dri/r200/r200_context.c
    +++ b/src/mesa/drivers/dri/r200/r200_context.c
    @@ -324,7 +324,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
        _mesa_init_driver_functions(&functions);
        r200InitDriverFuncs(&functions);
        r200InitIoctlFuncs(&functions);
    -   r200InitStateFuncs(&functions);
    +   r200InitStateFuncs(&rmesa->radeon, &functions);
        r200InitTextureFuncs(&rmesa->radeon, &functions);
        r200InitShaderFuncs(&functions);
        radeonInitQueryObjFunctions(&functions);
    diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
    index 71f764aaaef..9c2ac05ad6c 100644
    --- a/src/mesa/drivers/dri/r200/r200_state.c
    +++ b/src/mesa/drivers/dri/r200/r200_state.c
    @@ -2488,16 +2488,19 @@ static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask )
     }
     /* Initialize the driver's state functions.
      */
    -void r200InitStateFuncs( struct dd_function_table *functions )
    +void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions )
     {
        functions->UpdateState		= r200InvalidateState;
        functions->LightingSpaceChange	= r200LightingSpaceChange;
     
        functions->DrawBuffer		= radeonDrawBuffer;
        functions->ReadBuffer		= radeonReadBuffer;
    -   functions->CopyPixels                = _mesa_meta_CopyPixels;
    -   functions->DrawPixels                = _mesa_meta_DrawPixels;
    -   functions->ReadPixels                = radeonReadPixels;
    +
    +   if (radeon->radeonScreen->kernel_mm) {
    +	   functions->CopyPixels                = _mesa_meta_CopyPixels;
    +	   functions->DrawPixels                = _mesa_meta_DrawPixels;
    +	   functions->ReadPixels                = radeonReadPixels;
    +   }
     
        functions->AlphaFunc			= r200AlphaFunc;
        functions->BlendColor		= r200BlendColor;
    diff --git a/src/mesa/drivers/dri/r200/r200_state.h b/src/mesa/drivers/dri/r200/r200_state.h
    index 7b9b0c106aa..327ba837e25 100644
    --- a/src/mesa/drivers/dri/r200/r200_state.h
    +++ b/src/mesa/drivers/dri/r200/r200_state.h
    @@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     #include "r200_context.h"
     
     extern void r200InitState( r200ContextPtr rmesa );
    -extern void r200InitStateFuncs( struct dd_function_table *functions );
    +extern void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions );
     extern void r200InitTnlFuncs( GLcontext *ctx );
     
     extern void r200UpdateMaterial( GLcontext *ctx );
    diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
    index 364e0ba6b61..cfeb5407e91 100644
    --- a/src/mesa/drivers/dri/r300/r300_context.c
    +++ b/src/mesa/drivers/dri/r300/r300_context.c
    @@ -500,7 +500,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
     
     	_mesa_init_driver_functions(&functions);
     	r300InitIoctlFuncs(&functions);
    -	r300InitStateFuncs(&functions);
    +	r300InitStateFuncs(&r300->radeon, &functions);
     	r300InitTextureFuncs(&r300->radeon, &functions);
     	r300InitShaderFuncs(&functions);
     	radeonInitQueryObjFunctions(&functions);
    diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
    index e75c88e101b..749a2464e7c 100644
    --- a/src/mesa/drivers/dri/r300/r300_state.c
    +++ b/src/mesa/drivers/dri/r300/r300_state.c
    @@ -2354,7 +2354,7 @@ static void r300RenderMode(GLcontext * ctx, GLenum mode)
     /**
      * Initialize driver's state callback functions
      */
    -void r300InitStateFuncs(struct dd_function_table *functions)
    +void r300InitStateFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
     {
     
     	functions->UpdateState = r300InvalidateState;
    @@ -2396,9 +2396,11 @@ void r300InitStateFuncs(struct dd_function_table *functions)
     	functions->DrawBuffer = radeonDrawBuffer;
     	functions->ReadBuffer = radeonReadBuffer;
     
    -	functions->CopyPixels = _mesa_meta_CopyPixels;
    -	functions->DrawPixels = _mesa_meta_DrawPixels;
    -	functions->ReadPixels = radeonReadPixels;
    +	if (radeon->radeonScreen->kernel_mm) {
    +		functions->CopyPixels = _mesa_meta_CopyPixels;
    +		functions->DrawPixels = _mesa_meta_DrawPixels;
    +		functions->ReadPixels = radeonReadPixels;
    +	}
     }
     
     void r300InitShaderFunctions(r300ContextPtr r300)
    diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h
    index d46bf9f1796..e70f84f4e4b 100644
    --- a/src/mesa/drivers/dri/r300/r300_state.h
    +++ b/src/mesa/drivers/dri/r300/r300_state.h
    @@ -55,7 +55,7 @@ void r300UpdateDrawBuffer (GLcontext * ctx);
     void r300UpdateShaders (r300ContextPtr rmesa);
     void r300UpdateShaderStates (r300ContextPtr rmesa);
     void r300InitState (r300ContextPtr r300);
    -void r300InitStateFuncs (struct dd_function_table *functions);
    +void r300InitStateFuncs (radeonContextPtr radeon, struct dd_function_table *functions);
     void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, GLuint output_count, GLuint temp_count);
     void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten);
     
    diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
    index 76d5027649e..fddac2f9bdc 100644
    --- a/src/mesa/drivers/dri/r600/r600_context.c
    +++ b/src/mesa/drivers/dri/r600/r600_context.c
    @@ -384,7 +384,7 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
     	 */
     	_mesa_init_driver_functions(&functions);
     
    -	r700InitStateFuncs(&functions);
    +	r700InitStateFuncs(&r600->radeon, &functions);
     	r600InitTextureFuncs(&r600->radeon, &functions);
     	r700InitShaderFuncs(&functions);
     	radeonInitQueryObjFunctions(&functions);
    diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
    index 8797f8059a9..2953ffd0288 100644
    --- a/src/mesa/drivers/dri/r600/r700_state.c
    +++ b/src/mesa/drivers/dri/r600/r700_state.c
    @@ -1817,7 +1817,7 @@ void r700InitState(GLcontext * ctx) //-------------------
     
     }
     
    -void r700InitStateFuncs(struct dd_function_table *functions) //-----------------
    +void r700InitStateFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
     {
     	functions->UpdateState = r700InvalidateState;
     	functions->AlphaFunc = r700AlphaFunc;
    @@ -1861,9 +1861,10 @@ void r700InitStateFuncs(struct dd_function_table *functions) //-----------------
     	functions->DrawBuffer = radeonDrawBuffer;
     	functions->ReadBuffer = radeonReadBuffer;
     
    -	functions->CopyPixels = _mesa_meta_CopyPixels;
    -	functions->DrawPixels = _mesa_meta_DrawPixels;
    -	functions->ReadPixels = radeonReadPixels;
    -
    +	if (radeon->radeonScreen->kernel_mm) {
    +		functions->CopyPixels = _mesa_meta_CopyPixels;
    +		functions->DrawPixels = _mesa_meta_DrawPixels;
    +		functions->ReadPixels = radeonReadPixels;
    +	}
     }
     
    diff --git a/src/mesa/drivers/dri/r600/r700_state.h b/src/mesa/drivers/dri/r600/r700_state.h
    index 60c6a7f23ca..56885e0b154 100644
    --- a/src/mesa/drivers/dri/r600/r700_state.h
    +++ b/src/mesa/drivers/dri/r600/r700_state.h
    @@ -40,7 +40,7 @@ extern void r700UpdateShaderStates(GLcontext * ctx);
     extern void r700UpdateViewportOffset(GLcontext * ctx);
     
     extern void r700InitState (GLcontext * ctx);
    -extern void r700InitStateFuncs (struct dd_function_table *functions);
    +extern void r700InitStateFuncs (radeonContextPtr radeon, struct dd_function_table *functions);
     
     extern void r700SetScissor(context_t *context);
     
    diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
    index ec5612fdd7f..ebae0792aa5 100644
    --- a/src/mesa/drivers/dri/radeon/radeon_state.c
    +++ b/src/mesa/drivers/dri/radeon/radeon_state.c
    @@ -2249,9 +2249,11 @@ void radeonInitStateFuncs( GLcontext *ctx , GLboolean dri2 )
     
        ctx->Driver.DrawBuffer		= radeonDrawBuffer;
        ctx->Driver.ReadBuffer		= radeonReadBuffer;
    -   ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
    -   ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
    -   ctx->Driver.ReadPixels               = radeonReadPixels;
    +   if (dri2) {
    +	   ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
    +	   ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
    +	   ctx->Driver.ReadPixels               = radeonReadPixels;
    +   }
     
        ctx->Driver.AlphaFunc		= radeonAlphaFunc;
        ctx->Driver.BlendEquationSeparate	= radeonBlendEquationSeparate;
    -- 
    cgit v1.2.3
    
    
    From 18ecf41835059d4506402641833e7911d7de3ec4 Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sat, 13 Mar 2010 17:28:33 +0100
    Subject: r300: blits for small dst pitch work just fine
    
    ---
     src/mesa/drivers/dri/r300/r300_blit.c | 6 ------
     1 file changed, 6 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c
    index d870c7f852a..fa60628a5e0 100644
    --- a/src/mesa/drivers/dri/r300/r300_blit.c
    +++ b/src/mesa/drivers/dri/r300/r300_blit.c
    @@ -582,12 +582,6 @@ unsigned r300_blit(GLcontext *ctx,
         if (dst_pitch % 2 > 0)
             ++dst_pitch;
     
    -    /* Rendering to small buffer doesn't work.
    -     * Looks like a hw limitation.
    -     */
    -    if (dst_pitch < 32)
    -        return 0;
    -
         /* Need to clamp the region size to make sure
          * we don't read outside of the source buffer
          * or write outside of the destination buffer.
    -- 
    cgit v1.2.3
    
    
    From 3d72c4ae78cfdad7d160b0960adb792cbbbb863b Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sat, 20 Mar 2010 18:31:11 +0100
    Subject: r300/compiler: fix assertion failure in the r500-fragprog emission
     path
    
    ---
     src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    index 710cae727a1..4e84eefd658 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    @@ -469,9 +469,8 @@ void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
     	if (compiler->Base.Error)
     		return;
     
    -	assert(code->inst_end >= 0);
    -
    -	if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
    +	if (code->inst_end == -1 ||
    +	    (code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
     		/* This may happen when dead-code elimination is disabled or
     		 * when most of the fragment program logic is leading to a KIL */
     		if (code->inst_end >= 511) {
    -- 
    cgit v1.2.3
    
    
    From 7b38f946a05045323da0d367baff19bb62950af9 Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sat, 20 Mar 2010 18:31:11 +0100
    Subject: r300/compiler: fix assertion failure in the r500-fragprog emission
     path
    
    ---
     src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    index 710cae727a1..4e84eefd658 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    @@ -469,9 +469,8 @@ void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
     	if (compiler->Base.Error)
     		return;
     
    -	assert(code->inst_end >= 0);
    -
    -	if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
    +	if (code->inst_end == -1 ||
    +	    (code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
     		/* This may happen when dead-code elimination is disabled or
     		 * when most of the fragment program logic is leading to a KIL */
     		if (code->inst_end >= 511) {
    -- 
    cgit v1.2.3
    
    
    From 70929f4505d5cb1b9848a02e8359e9f7a8ef598c Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sun, 21 Mar 2010 11:19:02 +0100
    Subject: r300: clean fog_attr/wpos_attr if code accessing these attributes has
     been removed FP during compilation
    
    ---
     src/mesa/drivers/dri/r300/r300_fragprog_common.c | 13 +++++++++++++
     1 file changed, 13 insertions(+)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    index 61ea5e4d9a3..0646da46249 100644
    --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    @@ -256,6 +256,19 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
     
     	fp->InputsRead = compiler.Base.Program.InputsRead;
     
    +	/* Clear the fog/wpos_attr if code accessing these
    +	 * attributes has been removed during compilation
    +	 */
    +	if (fp->fog_attr != FRAG_ATTRIB_MAX) {
    +		if (!(fp->InputsRead & (1 << fp->fog_attr)))
    +			fp->fog_attr = FRAG_ATTRIB_MAX;
    +	}
    +
    +	if (fp->wpos_attr != FRAG_ATTRIB_MAX) {
    +		if (!(fp->InputsRead & (1 << fp->wpos_attr)))
    +			fp->wpos_attr = FRAG_ATTRIB_MAX;
    +	}
    +
     	rc_destroy(&compiler.Base);
     }
     
    -- 
    cgit v1.2.3
    
    
    From bed7d88708eba69118fe3805f95b104194872f3a Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sun, 21 Mar 2010 11:34:19 +0100
    Subject: r300: fix wpos/fog handling
    
    It may happen that the vertex attribute we were going to stuff
    the wpos/fog attrs in was already written by vertex program.
    In such cases we need to remove instruction accessing these
    attributes, so they don't overwrite the wpos/fog related
    instructions.
    
    This fixes non-textured models in many wine games.
    ---
     src/mesa/drivers/dri/r300/r300_vertprog.c | 22 ++++++++++++++++------
     1 file changed, 16 insertions(+), 6 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
    index 129004fee78..e77cd611f7a 100644
    --- a/src/mesa/drivers/dri/r300/r300_vertprog.c
    +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
    @@ -263,15 +263,25 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
     	rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X);
     
     	if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) {
    -		rc_copy_output(&compiler.Base,
    -			VERT_RESULT_HPOS,
    -			vp->key.WPosAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0);
    +		unsigned int vp_wpos_attr = vp->key.WPosAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0;
    +
    +		/* Set empty writemask for instructions writing to vp_wpos_attr
    +		 * before moving the wpos attr there.
    +		 * Such instructions will be removed by DCE.
    +		 */
    +		rc_move_output(&compiler.Base, vp_wpos_attr, vp->key.WPosAttr, 0);
    +		rc_copy_output(&compiler.Base, VERT_RESULT_HPOS, vp_wpos_attr);
     	}
     
     	if (vp->key.FogAttr != FRAG_ATTRIB_MAX) {
    -		rc_move_output(&compiler.Base,
    -			VERT_RESULT_FOGC,
    -			vp->key.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X);
    +		unsigned int vp_fog_attr = vp->key.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0;
    +
    +		/* Set empty writemask for instructions writing to vp_fog_attr
    +		 * before moving the fog attr there.
    +		 * Such instructions will be removed by DCE.
    +		 */
    +		rc_move_output(&compiler.Base, vp_fog_attr, vp->key.FogAttr, 0);
    +		rc_move_output(&compiler.Base, VERT_RESULT_FOGC, vp_fog_attr, WRITEMASK_X);
     	}
     
     	r3xx_compile_vertex_program(&compiler);
    -- 
    cgit v1.2.3
    
    
    From 7a77effb0b7eeefd5eb350aa9a487e10f62eb7ed Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sun, 21 Mar 2010 12:10:06 +0100
    Subject: r300: fix vertex programs with big number of params (>255) under KMS
    
    UMS will probably require some kernel work
    ---
     src/mesa/drivers/dri/r300/r300_cmdbuf.c   | 40 ++++++++++++++++++++++++++-----
     src/mesa/drivers/dri/r300/r300_vertprog.c |  6 ++++-
     2 files changed, 39 insertions(+), 7 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
    index 6cfa5686f4a..8eb596d1c5a 100644
    --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
    +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
    @@ -83,6 +83,23 @@ static int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
     	return cnt ? (cnt * 4) + extra : 0;
     }
     
    +static int check_vpp(GLcontext *ctx, struct radeon_state_atom *atom)
    +{
    +    r300ContextPtr r300 = R300_CONTEXT(ctx);
    +    int cnt;
    +    int extra = 1;
    +
    +    if (r300->radeon.radeonScreen->kernel_mm) {
    +        cnt = r300->selected_vp->code.constants.Count * 4;
    +        extra = 5;
    +    } else {
    +        cnt = vpu_count(atom->cmd);
    +        extra = 1;
    +    }
    +
    +    return cnt ? (cnt * 4) + extra : 0;
    +}
    +
     void r300_emit_vpu(struct r300_context *r300,
                        uint32_t *data,
                        unsigned len,
    @@ -101,15 +118,26 @@ static void emit_vpu_state(GLcontext *ctx, struct radeon_state_atom * atom)
     {
         r300ContextPtr r300 = R300_CONTEXT(ctx);
         drm_r300_cmd_header_t cmd;
    -    uint32_t addr, ndw;
    +    uint32_t addr;
     
         cmd.u = atom->cmd[0];
         addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
    -    ndw = atom->check(ctx, atom);
     
         r300_emit_vpu(r300, &atom->cmd[1], vpu_count(atom->cmd) * 4, addr);
     }
     
    +static void emit_vpp_state(GLcontext *ctx, struct radeon_state_atom * atom)
    +{
    +    r300ContextPtr r300 = R300_CONTEXT(ctx);
    +    drm_r300_cmd_header_t cmd;
    +    uint32_t addr;
    +
    +    cmd.u = atom->cmd[0];
    +    addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
    +
    +    r300_emit_vpu(r300, &atom->cmd[1], r300->selected_vp->code.constants.Count * 4, addr);
    +}
    +
     void r500_emit_fp(struct r300_context *r300,
                       uint32_t *data,
                       unsigned len,
    @@ -784,11 +812,11 @@ void r300InitCmdBuf(r300ContextPtr r300)
     			r300->hw.vpi.emit = emit_vpu_state;
     
     		if (is_r500) {
    -			ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
    +			ALLOC_STATE(vpp, vpp, R300_VPP_CMDSIZE, 0);
     			r300->hw.vpp.cmd[0] =
     				cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0);
     			if (r300->radeon.radeonScreen->kernel_mm)
    -				r300->hw.vpp.emit = emit_vpu_state;
    +				r300->hw.vpp.emit = emit_vpp_state;
     
     			ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
     			r300->hw.vps.cmd[0] =
    @@ -805,11 +833,11 @@ void r300InitCmdBuf(r300ContextPtr r300)
     					r300->hw.vpucp[i].emit = emit_vpu_state;
     			}
     		} else {
    -			ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
    +			ALLOC_STATE(vpp, vpp, R300_VPP_CMDSIZE, 0);
     			r300->hw.vpp.cmd[0] =
     				cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0);
     			if (r300->radeon.radeonScreen->kernel_mm)
    -				r300->hw.vpp.emit = emit_vpu_state;
    +				r300->hw.vpp.emit = emit_vpp_state;
     
     			ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
     			r300->hw.vps.cmd[0] =
    diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
    index e77cd611f7a..53fe948ab98 100644
    --- a/src/mesa/drivers/dri/r300/r300_vertprog.c
    +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
    @@ -392,7 +392,11 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
     	R300_STATECHANGE(rmesa, vap_cntl);
     	R300_STATECHANGE(rmesa, vpp);
     	param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
    -	bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
    +	if (!rmesa->radeon.radeonScreen->kernel_mm && param_count > 255 * 4) {
    +		WARN_ONCE("Too many VP params, expect rendering errors\n");
    +	}
    +	/* Prevent the overflow (vpu.count is u8) */
    +	bump_vpu_count(rmesa->hw.vpp.cmd, MIN2(255 * 4, param_count));
     	param_count /= 4;
     
     	r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->code));
    -- 
    cgit v1.2.3
    
    
    From 88f785935e43701a1ac56dae3952a915a9dd201b Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sun, 21 Mar 2010 12:12:05 +0100
    Subject: r300: fix off by one
    
    R300_PVS_MAX_CONST_ADDR field holds highest const addr, not
    const count.
    
    Fixes missing models and others rendering errors for vertex
    program using 256 params.
    ---
     src/mesa/drivers/dri/r300/r300_vertprog.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
    index 53fe948ab98..a1fe3780294 100644
    --- a/src/mesa/drivers/dri/r300/r300_vertprog.c
    +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
    @@ -409,6 +409,6 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
     	rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
     				(inst_count << R300_PVS_LAST_INST_SHIFT);
     
    -	rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
    +	rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | ((param_count - 1) << R300_PVS_MAX_CONST_ADDR_SHIFT);
     	rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
     }
    -- 
    cgit v1.2.3
    
    
    From fabc744999bf282e80baf44c45c58cab8a67d604 Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sun, 21 Mar 2010 12:43:38 +0100
    Subject: r300: report correct state atom size
    
    Spotted by Pauli Nieminen
    ---
     src/mesa/drivers/dri/r300/r300_cmdbuf.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
    index 8eb596d1c5a..788dc2f16e9 100644
    --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
    +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
    @@ -77,7 +77,7 @@ static int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
     	cnt = vpu_count(atom->cmd);
     
     	if (r300->radeon.radeonScreen->kernel_mm) {
    -		extra = 5;
    +		extra = 3;
     	}
     
     	return cnt ? (cnt * 4) + extra : 0;
    @@ -91,7 +91,7 @@ static int check_vpp(GLcontext *ctx, struct radeon_state_atom *atom)
     
         if (r300->radeon.radeonScreen->kernel_mm) {
             cnt = r300->selected_vp->code.constants.Count * 4;
    -        extra = 5;
    +        extra = 3;
         } else {
             cnt = vpu_count(atom->cmd);
             extra = 1;
    -- 
    cgit v1.2.3
    
    
    From d9a19d8649e49acfac98c240bff88931be7743d7 Mon Sep 17 00:00:00 2001
    From: Alex Deucher 
    Date: Fri, 12 Mar 2010 13:58:56 -0500
    Subject: r100/r200/r300/r600: enable accel for Copy/DrawPixels without kms
    
    meta ops should work ok without kms.
    ---
     src/mesa/drivers/dri/r200/r200_state.c     | 7 +++----
     src/mesa/drivers/dri/r300/r300_state.c     | 7 +++----
     src/mesa/drivers/dri/r600/r700_state.c     | 7 +++----
     src/mesa/drivers/dri/radeon/radeon_state.c | 7 +++----
     4 files changed, 12 insertions(+), 16 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
    index 9c2ac05ad6c..29d7bed8b6a 100644
    --- a/src/mesa/drivers/dri/r200/r200_state.c
    +++ b/src/mesa/drivers/dri/r200/r200_state.c
    @@ -2496,11 +2496,10 @@ void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *func
        functions->DrawBuffer		= radeonDrawBuffer;
        functions->ReadBuffer		= radeonReadBuffer;
     
    -   if (radeon->radeonScreen->kernel_mm) {
    -	   functions->CopyPixels                = _mesa_meta_CopyPixels;
    -	   functions->DrawPixels                = _mesa_meta_DrawPixels;
    +   functions->CopyPixels                = _mesa_meta_CopyPixels;
    +   functions->DrawPixels                = _mesa_meta_DrawPixels;
    +   if (radeon->radeonScreen->kernel_mm)
     	   functions->ReadPixels                = radeonReadPixels;
    -   }
     
        functions->AlphaFunc			= r200AlphaFunc;
        functions->BlendColor		= r200BlendColor;
    diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
    index 749a2464e7c..e660b1fb3bb 100644
    --- a/src/mesa/drivers/dri/r300/r300_state.c
    +++ b/src/mesa/drivers/dri/r300/r300_state.c
    @@ -2396,11 +2396,10 @@ void r300InitStateFuncs(radeonContextPtr radeon, struct dd_function_table *funct
     	functions->DrawBuffer = radeonDrawBuffer;
     	functions->ReadBuffer = radeonReadBuffer;
     
    -	if (radeon->radeonScreen->kernel_mm) {
    -		functions->CopyPixels = _mesa_meta_CopyPixels;
    -		functions->DrawPixels = _mesa_meta_DrawPixels;
    +	functions->CopyPixels = _mesa_meta_CopyPixels;
    +	functions->DrawPixels = _mesa_meta_DrawPixels;
    +	if (radeon->radeonScreen->kernel_mm)
     		functions->ReadPixels = radeonReadPixels;
    -	}
     }
     
     void r300InitShaderFunctions(r300ContextPtr r300)
    diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
    index 1ff233d91ee..1da31e7b2b4 100644
    --- a/src/mesa/drivers/dri/r600/r700_state.c
    +++ b/src/mesa/drivers/dri/r600/r700_state.c
    @@ -1861,10 +1861,9 @@ void r700InitStateFuncs(radeonContextPtr radeon, struct dd_function_table *funct
     	functions->DrawBuffer = radeonDrawBuffer;
     	functions->ReadBuffer = radeonReadBuffer;
     
    -	if (radeon->radeonScreen->kernel_mm) {
    -		functions->CopyPixels = _mesa_meta_CopyPixels;
    -		functions->DrawPixels = _mesa_meta_DrawPixels;
    +	functions->CopyPixels = _mesa_meta_CopyPixels;
    +	functions->DrawPixels = _mesa_meta_DrawPixels;
    +	if (radeon->radeonScreen->kernel_mm)
     		functions->ReadPixels = radeonReadPixels;
    -	}
     }
     
    diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
    index 0afbc19c127..539b067742f 100644
    --- a/src/mesa/drivers/dri/radeon/radeon_state.c
    +++ b/src/mesa/drivers/dri/radeon/radeon_state.c
    @@ -2249,11 +2249,10 @@ void radeonInitStateFuncs( GLcontext *ctx , GLboolean dri2 )
     
        ctx->Driver.DrawBuffer		= radeonDrawBuffer;
        ctx->Driver.ReadBuffer		= radeonReadBuffer;
    -   if (dri2) {
    -	   ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
    -	   ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
    +   ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
    +   ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
    +   if (dri2)
     	   ctx->Driver.ReadPixels               = radeonReadPixels;
    -   }
     
        ctx->Driver.AlphaFunc		= radeonAlphaFunc;
        ctx->Driver.BlendEquationSeparate	= radeonBlendEquationSeparate;
    -- 
    cgit v1.2.3
    
    
    From b6df7aed60189d5f28a139c6fe351022ca2907a4 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Fri, 26 Mar 2010 05:24:44 -0700
    Subject: r300/compiler: Lower CMP for vertex programs.
    
    I think my maths is right?
    ---
     .../drivers/dri/r300/compiler/radeon_program_alu.c | 41 ++++++++++++++++++++++
     1 file changed, 41 insertions(+)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    index b5c08aea49e..f5b7d57eab7 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    @@ -506,6 +506,46 @@ static void transform_r300_vertex_ABS(struct radeon_compiler* c,
     	inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW;
     }
     
    +static void transform_r300_vertex_CMP(struct radeon_compiler* c,
    +	struct rc_instruction* inst)
    +{
    +	/* There is no decent CMP available, so let's rig one up.
    +	 * CMP is defined as dst = src0 < 0.0 ? src1 : src2
    +	 * The following sequence consumes two temps and three extra slots,
    +	 * but should be equivalent:
    +	 *
    +	 * SLT tmp0, src0, 0.0
    +	 * SGE tmp1, src0, 0.0
    +	 * MUL tmp0, tmp0, src1
    +	 * MAD dst, src2, tmp1, tmp0
    +	 *
    +	 * Yes, I know, I'm a mad scientist. ~ C. */
    +	int tempreg0 = rc_find_free_temporary(c);
    +	int tempreg1 = rc_find_free_temporary(c);
    +
    +	/* SLT tmp0, src0, 0.0 */
    +	emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
    +		dstreg(RC_FILE_TEMPORARY, tempreg0),
    +		inst->U.I.SrcReg[0], builtin_zero);
    +
    +	/* SGE tmp1, src0, 0.0 */
    +	emit2(c, inst->Prev, RC_OPCODE_SGE, 0,
    +		dstreg(RC_FILE_TEMPORARY, tempreg1),
    +		inst->U.I.SrcReg[0], builtin_zero);
    +
    +	/* MUL tmp0, tmp0, src1 */
    +	emit2(c, inst->Prev, RC_OPCODE_MUL, 0,
    +		dstreg(RC_FILE_TEMPORARY, tempreg0),
    +		srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1]);
    +
    +	/* MAD dst, src2, tmp1, tmp0 */
    +	emit3(c, inst->Prev, RC_OPCODE_MAD, inst->U.I.SaturateMode,
    +		inst->U.I.DstReg,
    +		inst->U.I.SrcReg[2], srcreg(RC_FILE_TEMPORARY, tempreg1), srcreg(RC_FILE_TEMPORARY, tempreg0));
    +
    +	rc_remove_instruction(inst);
    +}
    +
     /**
      * For use with radeonLocalTransform, this transforms non-native ALU
      * instructions of the r300 up to r500 vertex engine.
    @@ -517,6 +557,7 @@ int r300_transform_vertex_alu(
     {
     	switch(inst->U.I.Opcode) {
     	case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
    +	case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1;
     	case RC_OPCODE_DP3: transform_DP3(c, inst); return 1;
     	case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
     	case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
    -- 
    cgit v1.2.3
    
    
    From 3623202834e9ca1073a4aa66f72f584812fb14df Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Tue, 30 Mar 2010 10:43:51 -0700
    Subject: r300/compiler: Unbreak DDX/DDY.
    
    Fixes progs/glsl/deriv.
    ---
     .../drivers/dri/r300/compiler/r500_fragprog_emit.c | 23 ++++++++++++++++++++--
     .../drivers/dri/r300/compiler/radeon_opcodes.c     |  4 ++--
     .../dri/r300/compiler/radeon_pair_translate.c      |  5 -----
     3 files changed, 23 insertions(+), 9 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    index 4e84eefd658..b6dfe28def9 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    @@ -190,6 +190,17 @@ static unsigned int use_source(struct r500_fragment_program_code* code, struct r
     	return 0;
     }
     
    +/**
    + * NOP the specified instruction if it is not a texture lookup.
    + */
    +static void alu_nop(struct r300_fragment_program_compiler *c, int ip)
    +{
    +	PROG_CODE;
    +
    +	if ((code->inst[ip].inst0 & 0x3) != R500_INST_TYPE_TEX) {
    +		code->inst[ip].inst0 |= R500_INST_NOP;
    +	}
    +}
     
     /**
      * Emit a paired ALU instruction.
    @@ -205,6 +216,14 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair
     
     	int ip = ++code->inst_end;
     
    +	/* Quirk: MDH/MDV (DDX/DDY) need a NOP on previous non-TEX instructions. */
    +	if (inst->RGB.Opcode == RC_OPCODE_DDX || inst->Alpha.Opcode == RC_OPCODE_DDX ||
    +		inst->RGB.Opcode == RC_OPCODE_DDY || inst->Alpha.Opcode == RC_OPCODE_DDY) {
    +		if (ip > 0) {
    +			alu_nop(c, ip - 1);
    +		}
    +	}
    +
     	code->inst[ip].inst5 = translate_rgb_op(c, inst->RGB.Opcode);
     	code->inst[ip].inst4 = translate_alpha_op(c, inst->Alpha.Opcode);
     
    @@ -252,8 +271,8 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair
     	code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT;
     	code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT;
     
    -    code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target);
    -    code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target);
    +	code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target);
    +	code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target);
     
     	if (inst->WriteALUResult) {
     		code->inst[ip].inst3 |= R500_ALU_RGB_WMASK;
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    index c1c0181fac1..9d289fce342 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    @@ -75,14 +75,14 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
     	{
     		.Opcode = RC_OPCODE_DDX,
     		.Name = "DDX",
    -		.NumSrcRegs = 1,
    +		.NumSrcRegs = 2,
     		.HasDstReg = 1,
     		.IsComponentwise = 1
     	},
     	{
     		.Opcode = RC_OPCODE_DDY,
     		.Name = "DDY",
    -		.NumSrcRegs = 1,
    +		.NumSrcRegs = 2,
     		.HasDstReg = 1,
     		.IsComponentwise = 1
     	},
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
    index fff5b0c2173..3a26e7daaf9 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
    @@ -159,11 +159,6 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
     	int nargs = opcode->NumSrcRegs;
     	int i;
     
    -	/* Special case for DDX/DDY (MDH/MDV). */
    -	if (inst->Opcode == RC_OPCODE_DDX || inst->Opcode == RC_OPCODE_DDY) {
    -		nargs++;
    -	}
    -
     	for(i = 0; i < opcode->NumSrcRegs; ++i) {
     		int source;
     		if (needrgb && !istranscendent) {
    -- 
    cgit v1.2.3
    
    
    From 073bae1ce441d175fd1ab60bcdef2cabe3074e00 Mon Sep 17 00:00:00 2001
    From: Dave Airlie 
    Date: Sat, 3 Apr 2010 12:17:57 +1000
    Subject: r300 compiler: add target output debugging.
    
    print the output target in the FP debug.
    
    Signed-off-by: Dave Airlie 
    ---
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    index b0fb8e970b7..b78d7d57157 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    @@ -433,19 +433,20 @@ void r500FragmentProgramDump(struct rX00_fragment_program_code *c)
     	      (inst >> 30));
           fprintf(stderr,"\t3 RGB_INST:  0x%08x:", code->inst[n].inst3);
           inst = code->inst[n].inst3;
    -      fprintf(stderr,"rgb_A_src:%d %s/%s/%s %d rgb_B_src:%d %s/%s/%s %d\n",
    +      fprintf(stderr,"rgb_A_src:%d %s/%s/%s %d rgb_B_src:%d %s/%s/%s %d targ: %d\n",
     	      (inst) & 0x3, toswiz((inst >> 2) & 0x7), toswiz((inst >> 5) & 0x7), toswiz((inst >> 8) & 0x7),
     	      (inst >> 11) & 0x3,
     	      (inst >> 13) & 0x3, toswiz((inst >> 15) & 0x7), toswiz((inst >> 18) & 0x7), toswiz((inst >> 21) & 0x7),
    -	      (inst >> 24) & 0x3);
    +	      (inst >> 24) & 0x3, (inst >> 29) & 0x3);
     
     
           fprintf(stderr,"\t4 ALPHA_INST:0x%08x:", code->inst[n].inst4);
           inst = code->inst[n].inst4;
    -      fprintf(stderr,"%s dest:%d%s alp_A_src:%d %s %d alp_B_src:%d %s %d w:%d\n", to_alpha_op(inst & 0xf),
    +      fprintf(stderr,"%s dest:%d%s alp_A_src:%d %s %d alp_B_src:%d %s %d targ %d w:%d\n", to_alpha_op(inst & 0xf),
     	      (inst >> 4) & 0x7f, inst & (1<<11) ? "(rel)":"",
     	      (inst >> 12) & 0x3, toswiz((inst >> 14) & 0x7), (inst >> 17) & 0x3,
     	      (inst >> 19) & 0x3, toswiz((inst >> 21) & 0x7), (inst >> 24) & 0x3,
    +	      (inst >> 29) & 0x3,
     	      (inst >> 31) & 0x1);
     
           fprintf(stderr,"\t5 RGBA_INST: 0x%08x:", code->inst[n].inst5);
    -- 
    cgit v1.2.3
    
    
    From e41a64591bf1a74465bf0adc7d35c991c4cfb4fe Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sun, 14 Feb 2010 23:57:46 +0100
    Subject: r300/compiler: make the max number of fragment shader temporaries
     adjustable
    
    ---
     src/gallium/drivers/r300/r300_fs.c                      | 1 +
     src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c | 2 +-
     src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c      | 5 +----
     src/mesa/drivers/dri/r300/compiler/radeon_compiler.h    | 1 +
     src/mesa/drivers/dri/r300/r300_fragprog_common.c        | 1 +
     5 files changed, 5 insertions(+), 5 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
    index e23fef8c9f7..116bb80007d 100644
    --- a/src/gallium/drivers/r300/r300_fs.c
    +++ b/src/gallium/drivers/r300/r300_fs.c
    @@ -169,6 +169,7 @@ static void r300_translate_fragment_shader(
         compiler.code = &shader->code;
         compiler.state = shader->compare_state;
         compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
    +    compiler.max_temp_regs = compiler.is_r500 ? 128 : 32;
         compiler.AllocateHwInputs = &allocate_hardware_inputs;
         compiler.UserData = &fs->inputs;
     
    diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
    index cc552aee176..37dafa77106 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
    @@ -353,7 +353,7 @@ void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
     		}
     	}
     
    -	if (code->pixsize >= R300_PFS_NUM_TEMP_REGS)
    +	if (code->pixsize >= compiler->max_temp_regs)
     		rc_error(&compiler->Base, "Too many hardware temporaries used.\n");
     
     	if (compiler->Base.Error)
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    index c2d5dc27b49..d06429254d8 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    @@ -156,10 +156,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     		fflush(stderr);
     	}
     
    -	if (c->is_r500)
    -		rc_pair_regalloc(c, 128);
    -	else
    -		rc_pair_regalloc(c, R300_PFS_NUM_TEMP_REGS);
    +	rc_pair_regalloc(c, c->max_temp_regs);
     
     	if (c->Base.Error)
     		return;
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
    index 6bfda0574f6..934ae28da56 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
    @@ -83,6 +83,7 @@ struct r300_fragment_program_compiler {
     	struct rX00_fragment_program_code *code;
     	struct r300_fragment_program_external_state state;
     	unsigned is_r500;
    +	unsigned max_temp_regs;
         /* Register corresponding to the depthbuffer. */
     	unsigned OutputDepth;
         /* Registers corresponding to the four colorbuffers. */
    diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    index 0646da46249..ba841229565 100644
    --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    @@ -220,6 +220,7 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
     	compiler.code = &fp->code;
     	compiler.state = fp->state;
     	compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
    +	compiler.max_temp_regs = (compiler.is_r500) ? 128 : 32;
     	compiler.OutputDepth = FRAG_RESULT_DEPTH;
     	memset(compiler.OutputColor, 0, 4 * sizeof(unsigned));
     	compiler.OutputColor[0] = FRAG_RESULT_COLOR;
    -- 
    cgit v1.2.3
    
    
    From 765dc9fc32cf9016473726fbf4827c2aa4cec0b1 Mon Sep 17 00:00:00 2001
    From: Michel Dänzer 
    Date: Wed, 7 Apr 2010 11:21:15 +0200
    Subject: r300: Initialize compiler.max_temp_regs for blits.
    
    Blits were broken since commit e41a64591bf1a74465bf0adc7d35c991c4cfb4fe
    ('r300/compiler: make the max number of fragment shader temporaries
    adjustable').
    ---
     src/mesa/drivers/dri/r300/r300_blit.c | 1 +
     1 file changed, 1 insertion(+)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c
    index fa60628a5e0..f6c3a85e51b 100644
    --- a/src/mesa/drivers/dri/r300/r300_blit.c
    +++ b/src/mesa/drivers/dri/r300/r300_blit.c
    @@ -118,6 +118,7 @@ static void create_fragment_program(struct r300_context *r300)
         compiler.OutputColor[0] = FRAG_RESULT_COLOR;
         compiler.OutputDepth = FRAG_RESULT_DEPTH;
         compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
    +    compiler.max_temp_regs = (compiler.is_r500) ? 128 : 32;
         compiler.code = &r300->blit.fp_code;
         compiler.AllocateHwInputs = fp_allocate_hw_inputs;
     
    -- 
    cgit v1.2.3
    
    
    From 95d3bdd338a1bc90ec382d5faa82ea3d0a2b3c67 Mon Sep 17 00:00:00 2001
    From: Vinson Lee 
    Date: Sat, 10 Apr 2010 20:12:32 -0700
    Subject: r300/compiler: Remove unused variable.
    
    ---
     src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c | 1 -
     1 file changed, 1 deletion(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
    index 3a26e7daaf9..407a0a55ee2 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
    @@ -156,7 +156,6 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
     	}
     
     	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
    -	int nargs = opcode->NumSrcRegs;
     	int i;
     
     	for(i = 0; i < opcode->NumSrcRegs; ++i) {
    -- 
    cgit v1.2.3
    
    
    From e13e1c068da1f51707086325ce4ebae5d4ec1676 Mon Sep 17 00:00:00 2001
    From: Vinson Lee 
    Date: Sat, 10 Apr 2010 22:03:29 -0700
    Subject: r300: Remove unnecessary header.
    
    ---
     src/mesa/drivers/dri/r300/r300_state.c | 1 -
     1 file changed, 1 deletion(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
    index e660b1fb3bb..02ba300eb02 100644
    --- a/src/mesa/drivers/dri/r300/r300_state.c
    +++ b/src/mesa/drivers/dri/r300/r300_state.c
    @@ -53,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     #include "shader/prog_statevars.h"
     #include "vbo/vbo.h"
     #include "tnl/tnl.h"
    -#include "tnl/t_vp_build.h"
     
     #include "r300_context.h"
     #include "r300_state.h"
    -- 
    cgit v1.2.3
    
    
    From 6a5518861e541db76bae0fa69d1d025805d90f2c Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Fri, 9 Apr 2010 21:14:15 +0200
    Subject: r300: set proper vertex index limits also in non indexed mode
    
    Fixes #27521, broken menus in UT2004 and broken water refraction in Sauerbraten.
    ---
     src/mesa/drivers/dri/r300/r300_render.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
    index 95961314863..11eafd3aeea 100644
    --- a/src/mesa/drivers/dri/r300/r300_render.c
    +++ b/src/mesa/drivers/dri/r300/r300_render.c
    @@ -386,6 +386,14 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
     			WARN_ONCE("Fixme: can't handle spliting prim %d\n", prim);
     			return;
     		}
    +
    +		if (rmesa->radeon.radeonScreen->kernel_mm) {
    +			BEGIN_BATCH_NO_AUTOSTATE(2);
    +			OUT_BATCH_REGSEQ(R300_VAP_VF_MAX_VTX_INDX, 1);
    +			OUT_BATCH(rmesa->radeon.tcl.aos[0].count);
    +			END_BATCH();
    +		}
    +
     		r300_emit_scissor(rmesa->radeon.glCtx);
     		while (num_verts > 0) {
     			int nr;
    -- 
    cgit v1.2.3
    
    
    From 2657325c4a73a2bfa94888a936d06466000e7fbf Mon Sep 17 00:00:00 2001
    From: Maciej Cencora 
    Date: Sun, 11 Apr 2010 12:39:54 +0200
    Subject: r300: respect radeon common code fallbacks
    
    Fixes progs/demos/shadowtex under KMS
    ---
     src/mesa/drivers/dri/r300/r300_context.c | 3 +++
     src/mesa/drivers/dri/r300/r300_render.c  | 8 ++++++--
     src/mesa/drivers/dri/r300/r300_render.h  | 1 +
     3 files changed, 10 insertions(+), 2 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
    index ff35cd52753..689bb138133 100644
    --- a/src/mesa/drivers/dri/r300/r300_context.c
    +++ b/src/mesa/drivers/dri/r300/r300_context.c
    @@ -61,6 +61,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     #include "r300_state.h"
     #include "r300_tex.h"
     #include "r300_emit.h"
    +#include "r300_render.h"
     #include "r300_swtcl.h"
     #include "radeon_bocs_wrapper.h"
     #include "radeon_buffer_objects.h"
    @@ -226,6 +227,8 @@ static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
     		r300->radeon.Fallback |= bit;
     	else
     		r300->radeon.Fallback &= ~bit;
    +
    +	r300SwitchFallback(ctx, R300_FALLBACK_RADEON_COMMON, mode);
     }
     
     static void r300_emit_query_finish(radeonContextPtr radeon)
    diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
    index 11eafd3aeea..bb8f91491f5 100644
    --- a/src/mesa/drivers/dri/r300/r300_render.c
    +++ b/src/mesa/drivers/dri/r300/r300_render.c
    @@ -408,8 +408,9 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
     	COMMIT_BATCH();
     }
     
    -static const char *getFallbackString(uint32_t bit)
    +static const char *getFallbackString(r300ContextPtr rmesa, uint32_t bit)
     {
    +	static char common_fallback_str[32];
     	switch (bit) {
     		case R300_FALLBACK_VERTEX_PROGRAM :
     			return "vertex program";
    @@ -429,6 +430,9 @@ static const char *getFallbackString(uint32_t bit)
     			return "render mode != GL_RENDER";
     		case R300_FALLBACK_FRAGMENT_PROGRAM:
     			return "fragment program";
    +		case R300_FALLBACK_RADEON_COMMON:
    +			snprintf(common_fallback_str, 32, "radeon common 0x%08x", rmesa->radeon.Fallback);
    +			return common_fallback_str;
     		case R300_FALLBACK_AOS_LIMIT:
     			return "aos limit";
     		case R300_FALLBACK_INVALID_BUFFERS:
    @@ -448,7 +452,7 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
     	if (mode) {
     		if ((fallback_warn & bit) == 0) {
     			if (RADEON_DEBUG & RADEON_FALLBACKS)
    -				fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit));
    +				fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(rmesa, bit));
     			fallback_warn |= bit;
     		}
     		rmesa->fallback |= bit;
    diff --git a/src/mesa/drivers/dri/r300/r300_render.h b/src/mesa/drivers/dri/r300/r300_render.h
    index ec785474a67..581e9fa0ccd 100644
    --- a/src/mesa/drivers/dri/r300/r300_render.h
    +++ b/src/mesa/drivers/dri/r300/r300_render.h
    @@ -41,6 +41,7 @@
     #define R300_FALLBACK_STENCIL_TWOSIDE   (1 << 21)
     #define R300_FALLBACK_RENDER_MODE       (1 << 22)
     #define R300_FALLBACK_FRAGMENT_PROGRAM  (1 << 23)
    +#define R300_FALLBACK_RADEON_COMMON     (1 << 29)
     #define R300_FALLBACK_AOS_LIMIT         (1 << 30)
     #define R300_FALLBACK_INVALID_BUFFERS   (1 << 31)
     #define R300_RASTER_FALLBACK_MASK        0xffff0000
    -- 
    cgit v1.2.3
    
    
    From 484079d7245e089a908090c0944e2088a3a074f6 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Sun, 11 Apr 2010 13:31:54 -0700
    Subject: r300/compiler: Add NPOT compatibility fields to external state.
    
    Completely unused for now.
    ---
     src/mesa/drivers/dri/r300/compiler/radeon_code.h | 28 ++++++++++++++++++++++--
     1 file changed, 26 insertions(+), 2 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    index 6d979bbaecf..45cc7df1e31 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    @@ -107,6 +107,18 @@ typedef enum {
     	RC_COMPARE_FUNC_ALWAYS
     } rc_compare_func;
     
    +/**
    + * Coordinate wrapping modes.
    + *
    + * These are not quite the same as their GL counterparts yet.
    + */
    +typedef enum {
    +	RC_WRAP_NONE = 0,
    +	RC_WRAP_CLAMP,
    +	RC_WRAP_REPEAT,
    +	RC_WRAP_MIRROR
    +} rc_wrap_mode;
    +
     /**
      * Stores state that influences the compilation of a fragment program.
      */
    @@ -127,11 +139,23 @@ struct r300_fragment_program_external_state {
     		 * this field specifies the compare function.
     		 *
     		 * Otherwise, this field is \ref RC_COMPARE_FUNC_NEVER (aka 0).
    -		 *
    -		 * Otherwise, this field is 0.
     		 * \sa rc_compare_func
     		 */
     		unsigned texture_compare_func : 3;
    +
    +		/**
    +		 * If the sampler will be accessed with non-normalized coords,
    +		 * this field is set.
    +		 */
    +		unsigned non_normalized_coords : 1;
    +
    +		/**
    +		 * This field specifies wrapping modes for the sampler.
    +		 *
    +		 * If this field is \ref RC_WRAP_NONE (aka 0), no wrapping maths
    +		 * will be performed on the coordinates.
    +		 */
    +		unsigned wrap_mode : 2;
     	} unit[16];
     };
     
    -- 
    cgit v1.2.3
    
    
    From d5af1dce8fc23dc3763773e3c0b7e0be128d2aa0 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Sun, 11 Apr 2010 16:13:45 -0700
    Subject: r300/compiler: Implement texcoord repeat and mirror for NPOT.
    
    ---
     src/gallium/drivers/r300/r300_fs.c                 | 51 +++++++++---------
     src/mesa/drivers/dri/r300/compiler/r300_fragprog.c | 62 ++++++++++++++++++----
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 57 ++++++++++++++++++++
     src/mesa/drivers/dri/r300/compiler/radeon_code.h   |  7 ++-
     4 files changed, 140 insertions(+), 37 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
    index c0d26e5ebde..6af6028447f 100644
    --- a/src/gallium/drivers/r300/r300_fs.c
    +++ b/src/gallium/drivers/r300/r300_fs.c
    @@ -139,11 +139,14 @@ static void get_external_state(
     
         for (i = 0; i < texstate->sampler_state_count; i++) {
             struct r300_sampler_state* s = texstate->sampler_states[i];
    +        struct r300_texture *t;
     
    -        if (!s) {
    +        if (!s || !texstate->sampler_views[i]) {
                 continue;
             }
     
    +        t = (struct r300_texture*)texstate->sampler_views[i]->base.texture;
    +
             if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
                 /* XXX Gallium doesn't provide us with any information regarding
                  * this mode, so we are screwed. I'm setting 0 = LUMINANCE. */
    @@ -153,30 +156,28 @@ static void get_external_state(
                 state->unit[i].texture_compare_func = s->state.compare_func;
             }
     
    -        /* Should we ask the shader to handle wrapping modes for us? */
    -        if (!s->state.normalized_coords) {
    -            state->unit[i].non_normalized_coords = 1;
    -
    -            /* XXX this should probably take into account STR, not just S. */
    -            switch (s->state.wrap_s) {
    -                case PIPE_TEX_WRAP_REPEAT:
    -                    state->unit[i].wrap_mode = RC_WRAP_REPEAT;
    -                    break;
    -                case PIPE_TEX_WRAP_CLAMP:
    -                case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
    -                case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
    -                    state->unit[i].wrap_mode = RC_WRAP_CLAMP;
    -                    break;
    -                case PIPE_TEX_WRAP_MIRROR_REPEAT:
    -                case PIPE_TEX_WRAP_MIRROR_CLAMP:
    -                case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
    -                case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
    -                    state->unit[i].wrap_mode = RC_WRAP_MIRROR;
    -                    break;
    -                default:
    -                    state->unit[i].wrap_mode = RC_WRAP_NONE;
    -                    break;
    -            }
    +        state->unit[i].fake_npot = t->uses_pitch;
    +        state->unit[i].non_normalized_coords = !s->state.normalized_coords;
    +
    +        /* XXX this should probably take into account STR, not just S. */
    +        switch (s->state.wrap_s) {
    +            case PIPE_TEX_WRAP_REPEAT:
    +                state->unit[i].wrap_mode = RC_WRAP_REPEAT;
    +                break;
    +            case PIPE_TEX_WRAP_CLAMP:
    +            case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
    +            case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
    +                state->unit[i].wrap_mode = RC_WRAP_CLAMP;
    +                break;
    +            case PIPE_TEX_WRAP_MIRROR_REPEAT:
    +            case PIPE_TEX_WRAP_MIRROR_CLAMP:
    +            case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
    +            case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
    +                state->unit[i].wrap_mode = RC_WRAP_MIRROR;
    +                break;
    +            default:
    +                state->unit[i].wrap_mode = RC_WRAP_NONE;
    +                break;
             }
         }
     }
    diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    index 928c15e1e40..4a60d05cd76 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    @@ -143,19 +143,59 @@ int r300_transform_TEX(
     	 * instead of [0..Width]x[0..Height].
     	 * Add a scaling instruction.
     	 */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL && inst->U.I.TexSrcTarget == RC_TEXTURE_RECT) {
    -		struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst->Prev);
    +	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    +		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    +		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
    +		struct rc_instruction *inst_rect = NULL;
    +		unsigned temp = rc_find_free_temporary(c);
    +
    +		if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
    +			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +			inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_rect->U.I.DstReg.Index = temp;
    +			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +			inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    +			inst_rect->U.I.SrcReg[1].Index =
    +				rc_constants_add_state(&c->Program.Constants,
    +					RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    +
    +			reset_srcreg(&inst->U.I.SrcReg[0]);
    +			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +
    +			inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    +		}
     
    -		inst_mul->U.I.Opcode = RC_OPCODE_MUL;
    -		inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -		inst_mul->U.I.DstReg.Index = rc_find_free_temporary(c);
    -		inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -		inst_mul->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    -		inst_mul->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    +		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    +			wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) {
    +			/* Repeat, with optional mirror */
    +			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +			inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    +			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_rect->U.I.DstReg.Index = temp;
    +			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +			if (wrapmode == RC_WRAP_MIRROR) {
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_SUB;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    +				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[1].Index = temp;
    +			}
     
    -		reset_srcreg(&inst->U.I.SrcReg[0]);
    -		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -		inst->U.I.SrcReg[0].Index = inst_mul->U.I.DstReg.Index;
    +			reset_srcreg(&inst->U.I.SrcReg[0]);
    +			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +		}
     	}
     
     	/* Cannot write texture to output registers or with masks */
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    index b78d7d57157..c20ee90fcd6 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    @@ -138,6 +138,63 @@ int r500_transform_TEX(
     		}
     	}
     
    +	/* Texture wrap modes don't work on NPOT textures or texrects. */
    +	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    +		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    +		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
    +		struct rc_instruction *inst_rect = NULL;
    +		unsigned temp = rc_find_free_temporary(c);
    +
    +		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    +			wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) {
    +
    +			if ((inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +				compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    +				inst_rect->U.I.SrcReg[1].Index =
    +					rc_constants_add_state(&c->Program.Constants,
    +						RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    +
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +
    +				inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    +			}
    +
    +			/* Repeat, with optional mirror */
    +			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +			inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    +			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_rect->U.I.DstReg.Index = temp;
    +			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +			if (wrapmode == RC_WRAP_MIRROR) {
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_SUB;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    +				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[1].Index = temp;
    +			}
    +
    +			reset_srcreg(&inst->U.I.SrcReg[0]);
    +			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +		}
    +	}
    +
     	/* Cannot write texture to output registers */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL && inst->U.I.DstReg.File != RC_FILE_TEMPORARY) {
     		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    index 45cc7df1e31..0a20dfe2d1a 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    @@ -144,7 +144,12 @@ struct r300_fragment_program_external_state {
     		unsigned texture_compare_func : 3;
     
     		/**
    -		 * If the sampler will be accessed with non-normalized coords,
    +		 * If the sampler needs to fake NPOT, this field is set.
    +		 */
    +		unsigned fake_npot : 1;
    +
    +		/**
    +		 * If the sampler will recieve non-normalized coords,
     		 * this field is set.
     		 */
     		unsigned non_normalized_coords : 1;
    -- 
    cgit v1.2.3
    
    
    From f0b8677d57f32ea66c997dfc8c3bf06987c6ebcd Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Mon, 12 Apr 2010 02:40:40 -0700
    Subject: r300/compiler: Comment code, add much better mirror maths.
    
    ---
     src/mesa/drivers/dri/r300/compiler/r300_fragprog.c |  81 ++++++++++++---
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 109 ++++++++++++++++++---
     2 files changed, 161 insertions(+), 29 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    index 4a60d05cd76..50360de3a38 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    @@ -142,6 +142,8 @@ int r300_transform_TEX(
     	/* Hardware uses [0..1]x[0..1] range for rectangle textures
     	 * instead of [0..Width]x[0..Height].
     	 * Add a scaling instruction.
    +	 *
    +	 * See also comments in this same section in r500_fragprog.c
     	 */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
     		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    @@ -166,35 +168,86 @@ int r300_transform_TEX(
     
     			reset_srcreg(&inst->U.I.SrcReg[0]);
     			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +			inst->U.I.SrcReg[0].Index = temp;
     
     			inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
     		}
     
     		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
     			wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) {
    -			/* Repeat, with optional mirror */
    -			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +			if (wrapmode == RC_WRAP_REPEAT) {
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
     
    -			inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_rect->U.I.DstReg.Index = temp;
    -			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = temp;
    +			} else if (wrapmode == RC_WRAP_MIRROR) {
    +				unsigned temp1;
    +				/*
    +				 * MUL temp0, abs(temp0), 0.5
    +				 * FRC temp0, temp0
    +				 * SGE temp1, temp0, 0.5
    +				 * MAD temp0, neg(0.5), temp1, temp0
    +				 * ADD temp0, temp0, temp0
    +				 */
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +
    +				temp1 = rc_find_free_temporary(c);
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp1;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
     
    -			if (wrapmode == RC_WRAP_MIRROR) {
     				inst_rect = rc_insert_new_instruction(c, inst->Prev);
     
    -				inst_rect->U.I.Opcode = RC_OPCODE_SUB;
    +				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
     				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
     				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp1;
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +				inst_rect->U.I.SrcReg[1].Negate = 1;
    +				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[2].Index = temp;
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
     				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
     				inst_rect->U.I.SrcReg[1].Index = temp;
    -			}
     
    -			reset_srcreg(&inst->U.I.SrcReg[0]);
    -			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = temp;
    +			}
     		}
     	}
     
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    index c20ee90fcd6..647bc87d0b7 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    @@ -138,7 +138,36 @@ int r500_transform_TEX(
     		}
     	}
     
    -	/* Texture wrap modes don't work on NPOT textures or texrects. */
    +	/* Texture wrap modes don't work on NPOT textures or texrects.
    +	 *
    +	 * The game plan is simple. We have two flags, fake_npot and
    +	 * non_normalized_coords, as well as a tex target. The RECT tex target
    +	 * will make the emitted code use non-scaled texcoords.
    +	 *
    +	 * Non-wrapped/clamped texcoords with NPOT are free in HW. Repeat and
    +	 * mirroring are not. If we need to repeat, we do:
    +	 *
    +	 * MUL temp, texcoord, 
    +	 * FRC temp, temp ; Discard integer portion of coords
    +	 *
    +	 * This gives us coords in [0, 1].
    +	 *
    +	 * Mirroring is trickier. We're going to start out like repeat:
    +	 *
    +	 * MUL temp0, texcoord,  ; De-mirror across axes
    +	 * MUL temp0, abs(temp0), 0.5 ; Pattern repeats in [0, 2]
    +	 *                            ; so scale to [0, 1]
    +	 * FRC temp0, temp0 ; Make the pattern repeat
    +	 * SGE temp1, temp0, 0.5 ; Select components that need to be "reflected"
    +	 *                       ; across the mirror
    +	 * MAD temp0, neg(0.5), temp1, temp0 ; Add -0.5 to the
    +	 *                                   ; selected components
    +	 * ADD temp0, temp0, temp0 ; Poor man's 2x to undo earlier MUL
    +	 *
    +	 * This gives us coords in [0, 1].
    +	 *
    +	 * ~ C.
    +	 */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
     		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
     			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
    @@ -165,33 +194,83 @@ int r500_transform_TEX(
     
     				reset_srcreg(&inst->U.I.SrcReg[0]);
     				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +				inst->U.I.SrcReg[0].Index = temp;
     
     				inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
     			}
     
    -			/* Repeat, with optional mirror */
    -			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +			if (wrapmode == RC_WRAP_REPEAT) {
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = temp;
    +			} else if (wrapmode == RC_WRAP_MIRROR) {
    +				unsigned temp1;
    +				/*
    +				 * MUL temp0, abs(temp0), 0.5
    +				 * FRC temp0, temp0
    +				 * SGE temp1, temp0, 0.5
    +				 * MAD temp0, neg(0.5), temp1, temp0
    +				 * ADD temp0, temp0, temp0
    +				 */
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
     
    -			inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_rect->U.I.DstReg.Index = temp;
    -			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
     
    -			if (wrapmode == RC_WRAP_MIRROR) {
     				inst_rect = rc_insert_new_instruction(c, inst->Prev);
     
    -				inst_rect->U.I.Opcode = RC_OPCODE_SUB;
    +				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
     				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
     				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +
    +				temp1 = rc_find_free_temporary(c);
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp1;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp1;
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +				inst_rect->U.I.SrcReg[1].Negate = 1;
    +				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[2].Index = temp;
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
     				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
     				inst_rect->U.I.SrcReg[1].Index = temp;
    -			}
     
    -			reset_srcreg(&inst->U.I.SrcReg[0]);
    -			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = temp;
    +			}
     		}
     	}
     
    -- 
    cgit v1.2.3
    
    
    From c2e804a7e1de99a60ff293972772835772d49391 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Mon, 12 Apr 2010 18:23:17 -0700
    Subject: r300/compiler: Hax around instructions limits in mirroring code.
    
    Stuff's starting to show up in arbnpot.
    ---
     src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c | 10 ++++++++++
     1 file changed, 10 insertions(+)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    index d06429254d8..a5814875bdb 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    @@ -110,6 +110,16 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     		c->Base.SwizzleCaps = &r300_swizzle_caps;
     	}
     
    +	/* As a stopgap, run the ALU lowering sequence once again.
    +	 *
    +	 * The entire lowering sequence should be fixed so that these little
    +	 * inter-dependent instructions aren't an issue. I suppose we'd need a
    +	 * list of safe instructions first... */
    +	struct radeon_program_transformation maths_lowering[] = {
    +		{ &radeonTransformALU, 0 }
    +	};
    +	radeonLocalTransform(&c->Base, 1, maths_lowering);
    +
     	if (c->Base.Debug) {
     		fprintf(stderr, "Fragment Program: After native rewrite:\n");
     		rc_print_program(&c->Base.Program);
    -- 
    cgit v1.2.3
    
    
    From 17b41f80bd1e9306de625e4240e6d83c08eec7fd Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Thu, 15 Apr 2010 23:58:38 +0200
    Subject: r300/compiler: kill off RC_WRAP_CLAMP
    
    A variant thereof might be later reintroduced for the mirrored-clamp modes.
    ---
     src/gallium/drivers/r300/r300_fs.c                 | 6 ------
     src/mesa/drivers/dri/r300/compiler/r300_fragprog.c | 2 +-
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 2 +-
     src/mesa/drivers/dri/r300/compiler/radeon_code.h   | 1 -
     4 files changed, 2 insertions(+), 9 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
    index cf81771bb7b..01fd67e536b 100644
    --- a/src/gallium/drivers/r300/r300_fs.c
    +++ b/src/gallium/drivers/r300/r300_fs.c
    @@ -169,12 +169,6 @@ static void get_external_state(
                             state->unit[i].fake_npot = TRUE; */
                             break;
     
    -                    case PIPE_TEX_WRAP_CLAMP:
    -                    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
    -                    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
    -                        state->unit[i].wrap_mode = RC_WRAP_CLAMP;
    -                        break;
    -
                         case PIPE_TEX_WRAP_MIRROR_REPEAT:
                         case PIPE_TEX_WRAP_MIRROR_CLAMP:
                         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
    diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    index 50360de3a38..b2cb9168807 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    @@ -174,7 +174,7 @@ int r300_transform_TEX(
     		}
     
     		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    -			wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) {
    +			wrapmode != RC_WRAP_NONE) {
     			if (wrapmode == RC_WRAP_REPEAT) {
     				inst_rect = rc_insert_new_instruction(c, inst->Prev);
     
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    index 647bc87d0b7..295e455d900 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    @@ -177,7 +177,7 @@ int r500_transform_TEX(
     		unsigned temp = rc_find_free_temporary(c);
     
     		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    -			wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) {
    +			wrapmode != RC_WRAP_NONE) {
     
     			if ((inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
     				compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    index 0a20dfe2d1a..28bcd1029bb 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    @@ -114,7 +114,6 @@ typedef enum {
      */
     typedef enum {
     	RC_WRAP_NONE = 0,
    -	RC_WRAP_CLAMP,
     	RC_WRAP_REPEAT,
     	RC_WRAP_MIRROR
     } rc_wrap_mode;
    -- 
    cgit v1.2.3
    
    
    From 80d89aa0d28ca987d958c1033eeb7e4a3c10368b Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Fri, 16 Apr 2010 01:59:11 +0200
    Subject: r300/compiler: fix repeat wrap mode for TXP and NPOTs
    
    No idea why st/mesa unnecessarily inserts TXP where TEX is sufficient.
    Also re-enabling the NPOT fallback for repeat in r300g.
    ---
     src/gallium/drivers/r300/r300_fs.c                 |  3 +--
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 22 ++++++++++++++++------
     2 files changed, 17 insertions(+), 8 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
    index 01fd67e536b..a37f23aaef2 100644
    --- a/src/gallium/drivers/r300/r300_fs.c
    +++ b/src/gallium/drivers/r300/r300_fs.c
    @@ -165,8 +165,7 @@ static void get_external_state(
                     switch (s->state.wrap_s) {
                         case PIPE_TEX_WRAP_REPEAT:
                             state->unit[i].wrap_mode = RC_WRAP_REPEAT;
    -                        /* XXX Enable when REPEAT fallback works.
    -                        state->unit[i].fake_npot = TRUE; */
    +                        state->unit[i].fake_npot = TRUE;
                             break;
     
                         case PIPE_TEX_WRAP_MIRROR_REPEAT:
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    index 295e455d900..0caff487b0c 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    @@ -200,12 +200,22 @@ int r500_transform_TEX(
     			}
     
     			if (wrapmode == RC_WRAP_REPEAT) {
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				/* Both instructions will be paired up. */
    +				struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev);
    +				struct rc_instruction *inst_mov = rc_insert_new_instruction(c, inst_frc);
    +
    +				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_frc->U.I.DstReg.Index = temp;
    +				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +				/* Preserve W for TXP. */
    +				inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +				inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_mov->U.I.DstReg.Index = temp;
    +				inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
    +				inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
     
     				reset_srcreg(&inst->U.I.SrcReg[0]);
     				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -- 
    cgit v1.2.3
    
    
    From f8a14186809356871ae74159c774e9e3959a22e5 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Thu, 15 Apr 2010 22:48:18 -0700
    Subject: r300/compiler: Split off texture fixes to their own file.
    
    Yes, I'm fully aware this generates subpar code on r500.
    ---
     src/mesa/drivers/dri/r300/compiler/Makefile        |   1 +
     src/mesa/drivers/dri/r300/compiler/r300_fragprog.c | 253 ----------------
     src/mesa/drivers/dri/r300/compiler/r300_fragprog.h |   2 -
     src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c |  19 +-
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 284 ------------------
     src/mesa/drivers/dri/r300/compiler/r500_fragprog.h |   5 -
     .../drivers/dri/r300/compiler/radeon_program_tex.c | 321 +++++++++++++++++++++
     .../drivers/dri/r300/compiler/radeon_program_tex.h |  39 +++
     8 files changed, 369 insertions(+), 555 deletions(-)
     create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
     create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_program_tex.h
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
    index d83888d90a3..c8acd3a3339 100644
    --- a/src/mesa/drivers/dri/r300/compiler/Makefile
    +++ b/src/mesa/drivers/dri/r300/compiler/Makefile
    @@ -13,6 +13,7 @@ C_SOURCES = \
     		radeon_opcodes.c \
     		radeon_program_alu.c \
     		radeon_program_pair.c \
    +		radeon_program_tex.c \
     		radeon_pair_translate.c \
     		radeon_pair_schedule.c \
     		radeon_pair_regalloc.c \
    diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    index b2cb9168807..794db8335a2 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
    @@ -31,259 +31,6 @@
     
     #include "../r300_reg.h"
     
    -static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
    -{
    -	struct rc_src_register reg = { 0, };
    -
    -	reg.File = RC_FILE_CONSTANT;
    -	reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
    -	reg.Swizzle = RC_SWIZZLE_WWWW;
    -	return reg;
    -}
    -
    -/**
    - * Transform TEX, TXP, TXB, and KIL instructions in the following way:
    - *  - premultiply texture coordinates for RECT
    - *  - extract operand swizzles
    - *  - introduce a temporary register when write masks are needed
    - */
    -int r300_transform_TEX(
    -	struct radeon_compiler * c,
    -	struct rc_instruction* inst,
    -	void* data)
    -{
    -	struct r300_fragment_program_compiler *compiler =
    -		(struct r300_fragment_program_compiler*)data;
    -
    -	if (inst->U.I.Opcode != RC_OPCODE_TEX &&
    -	    inst->U.I.Opcode != RC_OPCODE_TXB &&
    -	    inst->U.I.Opcode != RC_OPCODE_TXP &&
    -	    inst->U.I.Opcode != RC_OPCODE_KIL)
    -		return 0;
    -
    -	/* ARB_shadow & EXT_shadow_funcs */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -	    c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) {
    -		rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
    -
    -		if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    -			inst->U.I.Opcode = RC_OPCODE_MOV;
    -
    -			if (comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    -				inst->U.I.SrcReg[0].File = RC_FILE_NONE;
    -				inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    -			} else {
    -				inst->U.I.SrcReg[0] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    -			}
    -
    -			return 1;
    -		} else {
    -			rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
    -			unsigned int depthmode = compiler->state.unit[inst->U.I.TexSrcUnit].depth_texture_mode;
    -			struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
    -			struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
    -			struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
    -			int pass, fail;
    -
    -			inst_rcp->U.I.Opcode = RC_OPCODE_RCP;
    -			inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_rcp->U.I.DstReg.Index = rc_find_free_temporary(c);
    -			inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;
    -			inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
    -
    -			inst_cmp->U.I.DstReg = inst->U.I.DstReg;
    -			inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst->U.I.DstReg.Index = rc_find_free_temporary(c);
    -			inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    -
    -			inst_mad->U.I.Opcode = RC_OPCODE_MAD;
    -			inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_mad->U.I.DstReg.Index = rc_find_free_temporary(c);
    -			inst_mad->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_ZZZZ;
    -			inst_mad->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    -			inst_mad->U.I.SrcReg[1].Index = inst_rcp->U.I.DstReg.Index;
    -			inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
    -			inst_mad->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    -			inst_mad->U.I.SrcReg[2].Index = inst->U.I.DstReg.Index;
    -			if (depthmode == 0) /* GL_LUMINANCE */
    -				inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z);
    -			else if (depthmode == 2) /* GL_ALPHA */
    -				inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_WWWW;
    -
    -			/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
    -			 *   r  < tex  <=>      -tex+r < 0
    -			 *   r >= tex  <=> not (-tex+r < 0 */
    -			if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL)
    -				inst_mad->U.I.SrcReg[2].Negate = inst_mad->U.I.SrcReg[2].Negate ^ RC_MASK_XYZW;
    -			else
    -				inst_mad->U.I.SrcReg[0].Negate = inst_mad->U.I.SrcReg[0].Negate ^ RC_MASK_XYZW;
    -
    -			inst_cmp->U.I.Opcode = RC_OPCODE_CMP;
    -			/* DstReg has been filled out above */
    -			inst_cmp->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst_cmp->U.I.SrcReg[0].Index = inst_mad->U.I.DstReg.Index;
    -
    -			if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER) {
    -				pass = 1;
    -				fail = 2;
    -			} else {
    -				pass = 2;
    -				fail = 1;
    -			}
    -
    -			inst_cmp->U.I.SrcReg[pass].File = RC_FILE_NONE;
    -			inst_cmp->U.I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
    -			inst_cmp->U.I.SrcReg[fail] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    -		}
    -	}
    -
    -	/* Hardware uses [0..1]x[0..1] range for rectangle textures
    -	 * instead of [0..Width]x[0..Height].
    -	 * Add a scaling instruction.
    -	 *
    -	 * See also comments in this same section in r500_fragprog.c
    -	 */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    -			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
    -			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    -		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
    -		struct rc_instruction *inst_rect = NULL;
    -		unsigned temp = rc_find_free_temporary(c);
    -
    -		if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    -			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
    -			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -			inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    -			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_rect->U.I.DstReg.Index = temp;
    -			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    -			inst_rect->U.I.SrcReg[1].Index =
    -				rc_constants_add_state(&c->Program.Constants,
    -					RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    -
    -			reset_srcreg(&inst->U.I.SrcReg[0]);
    -			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst->U.I.SrcReg[0].Index = temp;
    -
    -			inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    -		}
    -
    -		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    -			wrapmode != RC_WRAP_NONE) {
    -			if (wrapmode == RC_WRAP_REPEAT) {
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
    -			} else if (wrapmode == RC_WRAP_MIRROR) {
    -				unsigned temp1;
    -				/*
    -				 * MUL temp0, abs(temp0), 0.5
    -				 * FRC temp0, temp0
    -				 * SGE temp1, temp0, 0.5
    -				 * MAD temp0, neg(0.5), temp1, temp0
    -				 * ADD temp0, temp0, temp0
    -				 */
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -
    -				temp1 = rc_find_free_temporary(c);
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp1;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp1;
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -				inst_rect->U.I.SrcReg[1].Negate = 1;
    -				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[2].Index = temp;
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[1].Index = temp;
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
    -			}
    -		}
    -	}
    -
    -	/* Cannot write texture to output registers or with masks */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -	    (inst->U.I.DstReg.File != RC_FILE_TEMPORARY || inst->U.I.DstReg.WriteMask != RC_MASK_XYZW)) {
    -		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
    -
    -		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -		inst_mov->U.I.DstReg = inst->U.I.DstReg;
    -		inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -		inst_mov->U.I.SrcReg[0].Index = rc_find_free_temporary(c);
    -
    -		inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -		inst->U.I.DstReg.Index = inst_mov->U.I.SrcReg[0].Index;
    -		inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    -	}
    -
    -
    -	/* Cannot read texture coordinate from constants file */
    -	if (inst->U.I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->U.I.SrcReg[0].File != RC_FILE_INPUT) {
    -		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
    -
    -		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -		inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -		inst_mov->U.I.DstReg.Index = rc_find_free_temporary(c);
    -		inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -		reset_srcreg(&inst->U.I.SrcReg[0]);
    -		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -		inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index;
    -	}
    -
    -	return 1;
    -}
    -
     /* just some random things... */
     void r300FragmentProgramDump(struct rX00_fragment_program_code *c)
     {
    diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
    index 418df36c936..8b755703be4 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
    +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
    @@ -41,6 +41,4 @@ extern void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler
     
     extern void r300FragmentProgramDump(struct rX00_fragment_program_code *c);
     
    -extern int r300_transform_TEX(struct radeon_compiler * c, struct rc_instruction* inst, void* data);
    -
     #endif
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    index a5814875bdb..1e126d546d7 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    @@ -26,6 +26,7 @@
     
     #include "radeon_dataflow.h"
     #include "radeon_program_alu.h"
    +#include "radeon_program_tex.h"
     #include "r300_fragprog.h"
     #include "r300_fragprog_swizzle.h"
     #include "r500_fragprog.h"
    @@ -90,35 +91,31 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     
     	if (c->is_r500) {
     		struct radeon_program_transformation transformations[] = {
    -			{ &r500_transform_TEX, c },
     			{ &r500_transform_IF, 0 },
     			{ &radeonTransformALU, 0 },
     			{ &radeonTransformDeriv, 0 },
     			{ &radeonTransformTrigScale, 0 }
     		};
    -		radeonLocalTransform(&c->Base, 5, transformations);
    +		radeonLocalTransform(&c->Base, 4, transformations);
     
     		c->Base.SwizzleCaps = &r500_swizzle_caps;
     	} else {
     		struct radeon_program_transformation transformations[] = {
    -			{ &r300_transform_TEX, c },
     			{ &radeonTransformALU, 0 },
     			{ &radeonTransformTrigSimple, 0 }
     		};
    -		radeonLocalTransform(&c->Base, 3, transformations);
    +		radeonLocalTransform(&c->Base, 2, transformations);
     
     		c->Base.SwizzleCaps = &r300_swizzle_caps;
     	}
     
    -	/* As a stopgap, run the ALU lowering sequence once again.
    -	 *
    -	 * The entire lowering sequence should be fixed so that these little
    -	 * inter-dependent instructions aren't an issue. I suppose we'd need a
    -	 * list of safe instructions first... */
    -	struct radeon_program_transformation maths_lowering[] = {
    +	/* Run the common transformations too.
    +	 * Remember, lowering comes last! */
    +	struct radeon_program_transformation common_transformations[] = {
    +		{ &radeonTransformTEX, c },
     		{ &radeonTransformALU, 0 }
     	};
    -	radeonLocalTransform(&c->Base, 1, maths_lowering);
    +	radeonLocalTransform(&c->Base, 2, common_transformations);
     
     	if (c->Base.Debug) {
     		fprintf(stderr, "Fragment Program: After native rewrite:\n");
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    index 0caff487b0c..632f0bcf4f8 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
    @@ -31,290 +31,6 @@
     
     #include "../r300_reg.h"
     
    -static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
    -{
    -	struct rc_src_register reg = { 0, };
    -
    -	reg.File = RC_FILE_CONSTANT;
    -	reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
    -	reg.Swizzle = RC_SWIZZLE_WWWW;
    -	return reg;
    -}
    -
    -/**
    - * Transform TEX, TXP, TXB, and KIL instructions in the following way:
    - *  - implement texture compare (shadow extensions)
    - *  - extract non-native source / destination operands
    - */
    -int r500_transform_TEX(
    -	struct radeon_compiler * c,
    -	struct rc_instruction * inst,
    -	void* data)
    -{
    -	struct r300_fragment_program_compiler *compiler =
    -		(struct r300_fragment_program_compiler*)data;
    -
    -	if (inst->U.I.Opcode != RC_OPCODE_TEX &&
    -	    inst->U.I.Opcode != RC_OPCODE_TXB &&
    -	    inst->U.I.Opcode != RC_OPCODE_TXP &&
    -	    inst->U.I.Opcode != RC_OPCODE_KIL)
    -		return 0;
    -
    -	/* ARB_shadow & EXT_shadow_funcs */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -	    c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) {
    -		rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
    -
    -		if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    -			inst->U.I.Opcode = RC_OPCODE_MOV;
    -
    -			if (comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    -				inst->U.I.SrcReg[0].File = RC_FILE_NONE;
    -				inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    -			} else {
    -				inst->U.I.SrcReg[0] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    -			}
    -
    -			return 1;
    -		} else {
    -			rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
    -			unsigned int depthmode = compiler->state.unit[inst->U.I.TexSrcUnit].depth_texture_mode;
    -			struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
    -			struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
    -			struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
    -			int pass, fail;
    -
    -			inst_rcp->U.I.Opcode = RC_OPCODE_RCP;
    -			inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_rcp->U.I.DstReg.Index = rc_find_free_temporary(c);
    -			inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;
    -			inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
    -
    -			inst_cmp->U.I.DstReg = inst->U.I.DstReg;
    -			inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst->U.I.DstReg.Index = rc_find_free_temporary(c);
    -			inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    -
    -			inst_mad->U.I.Opcode = RC_OPCODE_MAD;
    -			inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_mad->U.I.DstReg.Index = rc_find_free_temporary(c);
    -			inst_mad->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_ZZZZ;
    -			inst_mad->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    -			inst_mad->U.I.SrcReg[1].Index = inst_rcp->U.I.DstReg.Index;
    -			inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
    -			inst_mad->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    -			inst_mad->U.I.SrcReg[2].Index = inst->U.I.DstReg.Index;
    -			if (depthmode == 0) /* GL_LUMINANCE */
    -				inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z);
    -			else if (depthmode == 2) /* GL_ALPHA */
    -				inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_WWWW;
    -
    -			/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
    -			 *   r  < tex  <=>      -tex+r < 0
    -			 *   r >= tex  <=> not (-tex+r < 0 */
    -			if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL)
    -				inst_mad->U.I.SrcReg[2].Negate = inst_mad->U.I.SrcReg[2].Negate ^ RC_MASK_XYZW;
    -			else
    -				inst_mad->U.I.SrcReg[0].Negate = inst_mad->U.I.SrcReg[0].Negate ^ RC_MASK_XYZW;
    -
    -			inst_cmp->U.I.Opcode = RC_OPCODE_CMP;
    -			/* DstReg has been filled out above */
    -			inst_cmp->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst_cmp->U.I.SrcReg[0].Index = inst_mad->U.I.DstReg.Index;
    -
    -			if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER) {
    -				pass = 1;
    -				fail = 2;
    -			} else {
    -				pass = 2;
    -				fail = 1;
    -			}
    -
    -			inst_cmp->U.I.SrcReg[pass].File = RC_FILE_NONE;
    -			inst_cmp->U.I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
    -			inst_cmp->U.I.SrcReg[fail] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    -		}
    -	}
    -
    -	/* Texture wrap modes don't work on NPOT textures or texrects.
    -	 *
    -	 * The game plan is simple. We have two flags, fake_npot and
    -	 * non_normalized_coords, as well as a tex target. The RECT tex target
    -	 * will make the emitted code use non-scaled texcoords.
    -	 *
    -	 * Non-wrapped/clamped texcoords with NPOT are free in HW. Repeat and
    -	 * mirroring are not. If we need to repeat, we do:
    -	 *
    -	 * MUL temp, texcoord, 
    -	 * FRC temp, temp ; Discard integer portion of coords
    -	 *
    -	 * This gives us coords in [0, 1].
    -	 *
    -	 * Mirroring is trickier. We're going to start out like repeat:
    -	 *
    -	 * MUL temp0, texcoord,  ; De-mirror across axes
    -	 * MUL temp0, abs(temp0), 0.5 ; Pattern repeats in [0, 2]
    -	 *                            ; so scale to [0, 1]
    -	 * FRC temp0, temp0 ; Make the pattern repeat
    -	 * SGE temp1, temp0, 0.5 ; Select components that need to be "reflected"
    -	 *                       ; across the mirror
    -	 * MAD temp0, neg(0.5), temp1, temp0 ; Add -0.5 to the
    -	 *                                   ; selected components
    -	 * ADD temp0, temp0, temp0 ; Poor man's 2x to undo earlier MUL
    -	 *
    -	 * This gives us coords in [0, 1].
    -	 *
    -	 * ~ C.
    -	 */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    -			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
    -			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    -		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
    -		struct rc_instruction *inst_rect = NULL;
    -		unsigned temp = rc_find_free_temporary(c);
    -
    -		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    -			wrapmode != RC_WRAP_NONE) {
    -
    -			if ((inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    -				compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -				inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    -				inst_rect->U.I.SrcReg[1].Index =
    -					rc_constants_add_state(&c->Program.Constants,
    -						RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
    -
    -				inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    -			}
    -
    -			if (wrapmode == RC_WRAP_REPEAT) {
    -				/* Both instructions will be paired up. */
    -				struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev);
    -				struct rc_instruction *inst_mov = rc_insert_new_instruction(c, inst_frc);
    -
    -				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
    -				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_frc->U.I.DstReg.Index = temp;
    -				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    -				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -				/* Preserve W for TXP. */
    -				inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -				inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_mov->U.I.DstReg.Index = temp;
    -				inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
    -				inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
    -			} else if (wrapmode == RC_WRAP_MIRROR) {
    -				unsigned temp1;
    -				/*
    -				 * MUL temp0, abs(temp0), 0.5
    -				 * FRC temp0, temp0
    -				 * SGE temp1, temp0, 0.5
    -				 * MAD temp0, neg(0.5), temp1, temp0
    -				 * ADD temp0, temp0, temp0
    -				 */
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -
    -				temp1 = rc_find_free_temporary(c);
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp1;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp1;
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -				inst_rect->U.I.SrcReg[1].Negate = 1;
    -				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[2].Index = temp;
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[1].Index = temp;
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
    -			}
    -		}
    -	}
    -
    -	/* Cannot write texture to output registers */
    -	if (inst->U.I.Opcode != RC_OPCODE_KIL && inst->U.I.DstReg.File != RC_FILE_TEMPORARY) {
    -		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
    -
    -		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -		inst_mov->U.I.DstReg = inst->U.I.DstReg;
    -		inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -		inst_mov->U.I.SrcReg[0].Index = rc_find_free_temporary(c);
    -
    -		inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -		inst->U.I.DstReg.Index = inst_mov->U.I.SrcReg[0].Index;
    -		inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    -	}
    -
    -	/* Cannot read texture coordinate from constants file */
    -	if (inst->U.I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->U.I.SrcReg[0].File != RC_FILE_INPUT) {
    -		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
    -
    -		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -		inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -		inst_mov->U.I.DstReg.Index = rc_find_free_temporary(c);
    -		inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -		reset_srcreg(&inst->U.I.SrcReg[0]);
    -		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -		inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index;
    -	}
    -
    -	return 1;
    -}
    -
     /**
      * Rewrite IF instructions to use the ALU result special register.
      */
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
    index 0918cdf518b..4efbae7ba67 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
    @@ -42,11 +42,6 @@ extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c);
     
     extern struct rc_swizzle_caps r500_swizzle_caps;
     
    -extern int r500_transform_TEX(
    -	struct radeon_compiler * c,
    -	struct rc_instruction * inst,
    -	void* data);
    -
     extern int r500_transform_IF(
     	struct radeon_compiler * c,
     	struct rc_instruction * inst,
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    new file mode 100644
    index 00000000000..b95cea26cf3
    --- /dev/null
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -0,0 +1,321 @@
    +/*
    + * Copyright (C) 2010 Corbin Simpson
    + *
    + * 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_program_tex.h"
    +
    +#include "../r300_reg.h"
    +
    +/* Series of transformations to be done on textures. */
    +
    +static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
    +{
    +	struct rc_src_register reg = { 0, };
    +
    +	reg.File = RC_FILE_CONSTANT;
    +	reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
    +	reg.Swizzle = RC_SWIZZLE_WWWW;
    +	return reg;
    +}
    +
    +/**
    + * Transform TEX, TXP, TXB, and KIL instructions in the following ways:
    + *  - implement texture compare (shadow extensions)
    + *  - extract non-native source / destination operands
    + *  - premultiply texture coordinates for RECT
    + *  - extract operand swizzles
    + *  - introduce a temporary register when write masks are needed
    + */
    +int radeonTransformTEX(
    +	struct radeon_compiler * c,
    +	struct rc_instruction * inst,
    +	void* data)
    +{
    +	struct r300_fragment_program_compiler *compiler =
    +		(struct r300_fragment_program_compiler*)data;
    +
    +	if (inst->U.I.Opcode != RC_OPCODE_TEX &&
    +	    inst->U.I.Opcode != RC_OPCODE_TXB &&
    +	    inst->U.I.Opcode != RC_OPCODE_TXP &&
    +	    inst->U.I.Opcode != RC_OPCODE_KIL)
    +		return 0;
    +
    +	/* ARB_shadow & EXT_shadow_funcs */
    +	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    +	    c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) {
    +		rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
    +
    +		if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    +			inst->U.I.Opcode = RC_OPCODE_MOV;
    +
    +			if (comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    +				inst->U.I.SrcReg[0].File = RC_FILE_NONE;
    +				inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    +			} else {
    +				inst->U.I.SrcReg[0] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    +			}
    +
    +			return 1;
    +		} else {
    +			rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
    +			unsigned int depthmode = compiler->state.unit[inst->U.I.TexSrcUnit].depth_texture_mode;
    +			struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
    +			struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
    +			struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
    +			int pass, fail;
    +
    +			inst_rcp->U.I.Opcode = RC_OPCODE_RCP;
    +			inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_rcp->U.I.DstReg.Index = rc_find_free_temporary(c);
    +			inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;
    +			inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +			inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
    +
    +			inst_cmp->U.I.DstReg = inst->U.I.DstReg;
    +			inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst->U.I.DstReg.Index = rc_find_free_temporary(c);
    +			inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    +
    +			inst_mad->U.I.Opcode = RC_OPCODE_MAD;
    +			inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_mad->U.I.DstReg.Index = rc_find_free_temporary(c);
    +			inst_mad->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +			inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_ZZZZ;
    +			inst_mad->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    +			inst_mad->U.I.SrcReg[1].Index = inst_rcp->U.I.DstReg.Index;
    +			inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
    +			inst_mad->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    +			inst_mad->U.I.SrcReg[2].Index = inst->U.I.DstReg.Index;
    +			if (depthmode == 0) /* GL_LUMINANCE */
    +				inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z);
    +			else if (depthmode == 2) /* GL_ALPHA */
    +				inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_WWWW;
    +
    +			/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
    +			 *   r  < tex  <=>      -tex+r < 0
    +			 *   r >= tex  <=> not (-tex+r < 0 */
    +			if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL)
    +				inst_mad->U.I.SrcReg[2].Negate = inst_mad->U.I.SrcReg[2].Negate ^ RC_MASK_XYZW;
    +			else
    +				inst_mad->U.I.SrcReg[0].Negate = inst_mad->U.I.SrcReg[0].Negate ^ RC_MASK_XYZW;
    +
    +			inst_cmp->U.I.Opcode = RC_OPCODE_CMP;
    +			/* DstReg has been filled out above */
    +			inst_cmp->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst_cmp->U.I.SrcReg[0].Index = inst_mad->U.I.DstReg.Index;
    +
    +			if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER) {
    +				pass = 1;
    +				fail = 2;
    +			} else {
    +				pass = 2;
    +				fail = 1;
    +			}
    +
    +			inst_cmp->U.I.SrcReg[pass].File = RC_FILE_NONE;
    +			inst_cmp->U.I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
    +			inst_cmp->U.I.SrcReg[fail] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    +		}
    +	}
    +
    +	/* Texture wrap modes don't work on NPOT textures or texrects.
    +	 *
    +	 * The game plan is simple. We have two flags, fake_npot and
    +	 * non_normalized_coords, as well as a tex target. The RECT tex target
    +	 * will make the emitted code use non-scaled texcoords.
    +	 *
    +	 * Non-wrapped/clamped texcoords with NPOT are free in HW. Repeat and
    +	 * mirroring are not. If we need to repeat, we do:
    +	 *
    +	 * MUL temp, texcoord, 
    +	 * FRC temp, temp ; Discard integer portion of coords
    +	 *
    +	 * This gives us coords in [0, 1].
    +	 *
    +	 * Mirroring is trickier. We're going to start out like repeat:
    +	 *
    +	 * MUL temp0, texcoord,  ; De-mirror across axes
    +	 * MUL temp0, abs(temp0), 0.5 ; Pattern repeats in [0, 2]
    +	 *                            ; so scale to [0, 1]
    +	 * FRC temp0, temp0 ; Make the pattern repeat
    +	 * SGE temp1, temp0, 0.5 ; Select components that need to be "reflected"
    +	 *                       ; across the mirror
    +	 * MAD temp0, neg(0.5), temp1, temp0 ; Add -0.5 to the
    +	 *                                   ; selected components
    +	 * ADD temp0, temp0, temp0 ; Poor man's 2x to undo earlier MUL
    +	 *
    +	 * This gives us coords in [0, 1].
    +	 *
    +	 * ~ C.
    +	 */
    +	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    +		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
    +		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
    +		struct rc_instruction *inst_rect = NULL;
    +		unsigned temp = rc_find_free_temporary(c);
    +
    +		if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
    +			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +			inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_rect->U.I.DstReg.Index = temp;
    +			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +			inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    +			inst_rect->U.I.SrcReg[1].Index =
    +				rc_constants_add_state(&c->Program.Constants,
    +					RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    +
    +			reset_srcreg(&inst->U.I.SrcReg[0]);
    +			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst->U.I.SrcReg[0].Index = temp;
    +
    +			inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    +		}
    +
    +		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
    +			wrapmode != RC_WRAP_NONE) {
    +			if (wrapmode == RC_WRAP_REPEAT) {
    +				/* Both instructions will be paired up. */
    +				struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev);
    +				struct rc_instruction *inst_mov = rc_insert_new_instruction(c, inst_frc);
    +
    +				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_frc->U.I.DstReg.Index = temp;
    +				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +				/* Preserve W for TXP. */
    +				inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +				inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_mov->U.I.DstReg.Index = temp;
    +				inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
    +				inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = temp;
    +			} else if (wrapmode == RC_WRAP_MIRROR) {
    +				unsigned temp1;
    +				/*
    +				 * MUL temp0, abs(temp0), 0.5
    +				 * FRC temp0, temp0
    +				 * SGE temp1, temp0, 0.5
    +				 * MAD temp0, neg(0.5), temp1, temp0
    +				 * ADD temp0, temp0, temp0
    +				 */
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +
    +				temp1 = rc_find_free_temporary(c);
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp1;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp1;
    +				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    +				inst_rect->U.I.SrcReg[1].Negate = 1;
    +				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[2].Index = temp;
    +
    +				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
    +				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.DstReg.Index = temp;
    +				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[0].Index = temp;
    +				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    +				inst_rect->U.I.SrcReg[1].Index = temp;
    +
    +				reset_srcreg(&inst->U.I.SrcReg[0]);
    +				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst->U.I.SrcReg[0].Index = temp;
    +			}
    +		}
    +	}
    +
    +	/* Cannot write texture to output registers or with masks */
    +	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    +	    (inst->U.I.DstReg.File != RC_FILE_TEMPORARY || inst->U.I.DstReg.WriteMask != RC_MASK_XYZW)) {
    +		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
    +
    +		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +		inst_mov->U.I.DstReg = inst->U.I.DstReg;
    +		inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +		inst_mov->U.I.SrcReg[0].Index = rc_find_free_temporary(c);
    +
    +		inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +		inst->U.I.DstReg.Index = inst_mov->U.I.SrcReg[0].Index;
    +		inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    +	}
    +
    +
    +	/* Cannot read texture coordinate from constants file */
    +	if (inst->U.I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->U.I.SrcReg[0].File != RC_FILE_INPUT) {
    +		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
    +
    +		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +		inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +		inst_mov->U.I.DstReg.Index = rc_find_free_temporary(c);
    +		inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +		reset_srcreg(&inst->U.I.SrcReg[0]);
    +		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +		inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index;
    +	}
    +
    +	return 1;
    +}
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.h
    new file mode 100644
    index 00000000000..a0105051ac4
    --- /dev/null
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.h
    @@ -0,0 +1,39 @@
    +/*
    + * Copyright (C) 2010 Corbin Simpson
    + *
    + * 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_PROGRAM_TEX_H_
    +#define __RADEON_PROGRAM_TEX_H_
    +
    +#include "radeon_compiler.h"
    +#include "radeon_program.h"
    +
    +int radeonTransformTEX(
    +	struct radeon_compiler * c,
    +	struct rc_instruction * inst,
    +	void* data);
    +
    +#endif /* __RADEON_PROGRAM_TEX_H_ */
    -- 
    cgit v1.2.3
    
    
    From 2e74bc440eb110f1256af26f777e1b283df08df2 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Thu, 15 Apr 2010 23:23:52 -0700
    Subject: r300/compiler: Save Q for mirror and repeat.
    
    ---
     .../drivers/dri/r300/compiler/radeon_program_tex.c | 42 +++++++++++-----------
     1 file changed, 20 insertions(+), 22 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    index b95cea26cf3..655e84b4cb8 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -58,14 +58,14 @@ int radeonTransformTEX(
     		(struct r300_fragment_program_compiler*)data;
     
     	if (inst->U.I.Opcode != RC_OPCODE_TEX &&
    -	    inst->U.I.Opcode != RC_OPCODE_TXB &&
    -	    inst->U.I.Opcode != RC_OPCODE_TXP &&
    -	    inst->U.I.Opcode != RC_OPCODE_KIL)
    +		inst->U.I.Opcode != RC_OPCODE_TXB &&
    +		inst->U.I.Opcode != RC_OPCODE_TXP &&
    +		inst->U.I.Opcode != RC_OPCODE_KIL)
     		return 0;
     
     	/* ARB_shadow & EXT_shadow_funcs */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -	    c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) {
    +		c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) {
     		rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
     
     		if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
    @@ -201,27 +201,17 @@ int radeonTransformTEX(
     
     		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
     			wrapmode != RC_WRAP_NONE) {
    +			struct rc_instruction *inst_mov;
    +
     			if (wrapmode == RC_WRAP_REPEAT) {
     				/* Both instructions will be paired up. */
     				struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev);
    -				struct rc_instruction *inst_mov = rc_insert_new_instruction(c, inst_frc);
     
     				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
     				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
     				inst_frc->U.I.DstReg.Index = temp;
     				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
     				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -				/* Preserve W for TXP. */
    -				inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -				inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_mov->U.I.DstReg.Index = temp;
    -				inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
    -				inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
     			} else if (wrapmode == RC_WRAP_MIRROR) {
     				unsigned temp1;
     				/*
    @@ -279,17 +269,26 @@ int radeonTransformTEX(
     				inst_rect->U.I.SrcReg[0].Index = temp;
     				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
     				inst_rect->U.I.SrcReg[1].Index = temp;
    -
    -				reset_srcreg(&inst->U.I.SrcReg[0]);
    -				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst->U.I.SrcReg[0].Index = temp;
     			}
    +
    +			/* Preserve W for TXP/TXB. */
    +			inst_mov = rc_insert_new_instruction(c, inst->Prev);
    +
    +			inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +			inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_mov->U.I.DstReg.Index = temp;
    +			inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
    +			inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +			reset_srcreg(&inst->U.I.SrcReg[0]);
    +			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst->U.I.SrcReg[0].Index = temp;
     		}
     	}
     
     	/* Cannot write texture to output registers or with masks */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -	    (inst->U.I.DstReg.File != RC_FILE_TEMPORARY || inst->U.I.DstReg.WriteMask != RC_MASK_XYZW)) {
    +		(inst->U.I.DstReg.File != RC_FILE_TEMPORARY || inst->U.I.DstReg.WriteMask != RC_MASK_XYZW)) {
     		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
     
     		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    @@ -302,7 +301,6 @@ int radeonTransformTEX(
     		inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
     	}
     
    -
     	/* Cannot read texture coordinate from constants file */
     	if (inst->U.I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->U.I.SrcReg[0].File != RC_FILE_INPUT) {
     		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
    -- 
    cgit v1.2.3
    
    
    From a089fe281645395d68cfae6d66151a8a88fe5f8e Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Thu, 15 Apr 2010 23:35:48 -0700
    Subject: r300/compiler: Oops, this slipped through.
    
    ---
     src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c | 6 ++++--
     1 file changed, 4 insertions(+), 2 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    index 1e126d546d7..5fe10dbfe8b 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    @@ -113,9 +113,11 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     	 * Remember, lowering comes last! */
     	struct radeon_program_transformation common_transformations[] = {
     		{ &radeonTransformTEX, c },
    -		{ &radeonTransformALU, 0 }
     	};
    -	radeonLocalTransform(&c->Base, 2, common_transformations);
    +	radeonLocalTransform(&c->Base, 1, common_transformations);
    +
    +	common_transformations[0].function = &radeonTransformALU;
    +	radeonLocalTransform(&c->Base, 1, common_transformations);
     
     	if (c->Base.Debug) {
     		fprintf(stderr, "Fragment Program: After native rewrite:\n");
    -- 
    cgit v1.2.3
    
    
    From 2c5b35807eb506a1f7a4fc675f5644ae2f675d84 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Fri, 16 Apr 2010 00:35:10 -0700
    Subject: r300/compiler: Fix magic numbers in readmasks.
    
    ---
     src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    index 9d289fce342..cf8602e3290 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    @@ -412,15 +412,15 @@ void rc_compute_sources_for_writemask(
     			srcmasks[0] |= RC_MASK_XYZW;
     			break;
     		case RC_OPCODE_DST:
    -			srcmasks[0] |= 0x6;
    -			srcmasks[1] |= 0xa;
    +			srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
    +			srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
     			break;
     		case RC_OPCODE_EXP:
     		case RC_OPCODE_LOG:
     			srcmasks[0] |= RC_MASK_XY;
     			break;
     		case RC_OPCODE_LIT:
    -			srcmasks[0] |= 0xb;
    +			srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
     			break;
     		default:
     			break;
    -- 
    cgit v1.2.3
    
    
    From b1a89ea1abe1c69e3e0abcdfc2b525fe7f727864 Mon Sep 17 00:00:00 2001
    From: Corbin Simpson 
    Date: Fri, 16 Apr 2010 00:39:42 -0700
    Subject: r300/compiler: Fix texture instruction readmasks.
    
    No immediate benefit, it was just bugging me.
    ---
     .../dri/r300/compiler/radeon_dataflow_deadcode.c   |  6 +++---
     .../drivers/dri/r300/compiler/radeon_opcodes.c     | 24 +++++++++++++++++++---
     .../drivers/dri/r300/compiler/radeon_opcodes.h     |  4 +++-
     3 files changed, 27 insertions(+), 7 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
    index e0c66c4aeb0..f3734852cc6 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
    @@ -162,7 +162,7 @@ static void update_instruction(struct deadcode_state * s, struct rc_instruction
     	}
     
     	unsigned int srcmasks[3];
    -	rc_compute_sources_for_writemask(opcode, usedmask, srcmasks);
    +	rc_compute_sources_for_writemask(inst, usedmask, srcmasks);
     
     	for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
     		unsigned int refmask = 0;
    @@ -250,7 +250,7 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
     	for(struct rc_instruction * inst = c->Program.Instructions.Next;
     	    inst != &c->Program.Instructions;
     	    inst = inst->Next, ++ip) {
    -		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);\
    +		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
     		int dead = 1;
     
     		if (!opcode->HasDstReg) {
    @@ -281,7 +281,7 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
     		else if (inst->U.I.WriteALUResult == RC_ALURESULT_W)
     			usemask |= RC_MASK_W;
     
    -		rc_compute_sources_for_writemask(opcode, usemask, srcmasks);
    +		rc_compute_sources_for_writemask(inst, usemask, srcmasks);
     
     		for(unsigned int src = 0; src < 3; ++src) {
     			for(unsigned int chan = 0; chan < 4; ++chan) {
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    index cf8602e3290..ffc91241ab8 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    @@ -26,6 +26,7 @@
      */
     
     #include "radeon_opcodes.h"
    +#include "radeon_program.h"
     
     #include "radeon_program_constants.h"
     
    @@ -371,10 +372,11 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
     };
     
     void rc_compute_sources_for_writemask(
    -		const struct rc_opcode_info * opcode,
    +		const struct rc_instruction *inst,
     		unsigned int writemask,
     		unsigned int *srcmasks)
     {
    +	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
     	srcmasks[0] = 0;
     	srcmasks[1] = 0;
     	srcmasks[2] = 0;
    @@ -406,10 +408,26 @@ void rc_compute_sources_for_writemask(
     			srcmasks[0] |= RC_MASK_XYZW;
     			srcmasks[1] |= RC_MASK_XYZW;
     			break;
    -		case RC_OPCODE_TEX:
     		case RC_OPCODE_TXB:
     		case RC_OPCODE_TXP:
    -			srcmasks[0] |= RC_MASK_XYZW;
    +			srcmasks[0] |= RC_MASK_W;
    +			/* Fall through */
    +		case RC_OPCODE_TEX:
    +			switch (inst->U.I.TexSrcTarget) {
    +				case RC_TEXTURE_1D:
    +					srcmasks[0] |= RC_MASK_X;
    +					break;
    +				case RC_TEXTURE_2D:
    +				case RC_TEXTURE_RECT:
    +				case RC_TEXTURE_1D_ARRAY:
    +					srcmasks[0] |= RC_MASK_XY;
    +					break;
    +				case RC_TEXTURE_3D:
    +				case RC_TEXTURE_CUBE:
    +				case RC_TEXTURE_2D_ARRAY:
    +					srcmasks[0] |= RC_MASK_XYZ;
    +					break;
    +			}
     			break;
     		case RC_OPCODE_DST:
     			srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
    index a3c5b869546..1c9b34df78e 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
    @@ -227,8 +227,10 @@ static inline const struct rc_opcode_info * rc_get_opcode_info(rc_opcode opcode)
     	return &rc_opcodes[opcode];
     }
     
    +struct rc_instruction;
    +
     void rc_compute_sources_for_writemask(
    -		const struct rc_opcode_info * opcode,
    +		const struct rc_instruction *inst,
     		unsigned int writemask,
     		unsigned int *srcmasks);
     
    -- 
    cgit v1.2.3
    
    
    From b2c1b944c9bf7ea08ef3ff6bb0820091903c895c Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Fri, 16 Apr 2010 20:59:35 +0200
    Subject: r300/compiler: restore r500-specific bits of TEX transformations
    
    ---
     .../drivers/dri/r300/compiler/radeon_program_tex.c | 63 ++++++++++++++--------
     1 file changed, 40 insertions(+), 23 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    index 655e84b4cb8..967fd74b003 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -41,6 +41,33 @@ static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu
     	return reg;
     }
     
    +static void lower_texture_rect(struct r300_fragment_program_compiler *compiler,
    +							   struct rc_instruction *inst)
    +{
    +	struct rc_instruction *inst_rect;
    +	unsigned temp = rc_find_free_temporary(&compiler->Base);
    +
    +	if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    +		compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
    +		inst_rect = rc_insert_new_instruction(&compiler->Base, inst->Prev);
    +
    +		inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    +		inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +		inst_rect->U.I.DstReg.Index = temp;
    +		inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +		inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    +		inst_rect->U.I.SrcReg[1].Index =
    +				rc_constants_add_state(&compiler->Base.Program.Constants,
    +									   RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
    +
    +		reset_srcreg(&inst->U.I.SrcReg[0]);
    +		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +		inst->U.I.SrcReg[0].Index = temp;
    +
    +		inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    +	}
    +}
    +
     /**
      * Transform TEX, TXP, TXB, and KIL instructions in the following ways:
      *  - implement texture compare (shadow extensions)
    @@ -176,32 +203,21 @@ int radeonTransformTEX(
     			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
     			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
     		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
    -		struct rc_instruction *inst_rect = NULL;
    -		unsigned temp = rc_find_free_temporary(c);
    -
    -		if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    -			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
    -			inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -			inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    -			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -			inst_rect->U.I.DstReg.Index = temp;
    -			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    -			inst_rect->U.I.SrcReg[1].Index =
    -				rc_constants_add_state(&c->Program.Constants,
    -					RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
     
    -			reset_srcreg(&inst->U.I.SrcReg[0]);
    -			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -			inst->U.I.SrcReg[0].Index = temp;
    -
    -			inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
    +		/* R300 cannot sample from rectangles. */
    +		if (!compiler->is_r500) {
    +			lower_texture_rect(compiler, inst);
     		}
     
     		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
     			wrapmode != RC_WRAP_NONE) {
     			struct rc_instruction *inst_mov;
    +			unsigned temp = rc_find_free_temporary(c);
    +
    +			/* For NPOT fallback, we need normalized coordinates anyway. */
    +			if (compiler->is_r500) {
    +				lower_texture_rect(compiler, inst);
    +			}
     
     			if (wrapmode == RC_WRAP_REPEAT) {
     				/* Both instructions will be paired up. */
    @@ -222,7 +238,7 @@ int radeonTransformTEX(
     				 * ADD temp0, temp0, temp0
     				 */
     
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    +				struct rc_instruction *inst_rect = rc_insert_new_instruction(c, inst->Prev);
     
     				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
     				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    @@ -286,9 +302,10 @@ int radeonTransformTEX(
     		}
     	}
     
    -	/* Cannot write texture to output registers or with masks */
    +	/* Cannot write texture to output registers (all chips) or with masks (non-r500) */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
    -		(inst->U.I.DstReg.File != RC_FILE_TEMPORARY || inst->U.I.DstReg.WriteMask != RC_MASK_XYZW)) {
    +		(inst->U.I.DstReg.File != RC_FILE_TEMPORARY ||
    +		 (!compiler->is_r500 && inst->U.I.DstReg.WriteMask != RC_MASK_XYZW))) {
     		struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
     
     		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    -- 
    cgit v1.2.3
    
    
    From 47265e69c84c78a68102fa727aa80d63f25c0d46 Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Fri, 16 Apr 2010 22:29:19 +0200
    Subject: r300/compiler: make ARB_shadow_ambient optional
    
    This saves constant register space for r300g, which doesn't need
    this feature.
    ---
     src/gallium/drivers/r300/r300_emit.c                  |  6 ------
     src/mesa/drivers/dri/r300/compiler/radeon_compiler.h  |  3 +++
     .../drivers/dri/r300/compiler/radeon_program_tex.c    | 19 +++++++++++++------
     src/mesa/drivers/dri/r300/r300_blit.c                 |  1 +
     src/mesa/drivers/dri/r300/r300_fragprog_common.c      |  1 +
     5 files changed, 18 insertions(+), 12 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
    index 9c4bcfc49b1..19acdaba621 100644
    --- a/src/gallium/drivers/r300/r300_emit.c
    +++ b/src/gallium/drivers/r300/r300_emit.c
    @@ -157,12 +157,6 @@ static const float * get_rc_constant_state(
                 vec[1] = 1.0 / tex->height0;
                 break;
     
    -        /* Texture compare-fail value. Shouldn't ever show up, but if
    -         * it does, we'll be ready. */
    -        case RC_STATE_SHADOW_AMBIENT:
    -            vec[3] = 0;
    -            break;
    -
             case RC_STATE_R300_VIEWPORT_SCALE:
                 vec[0] = viewport->xscale;
                 vec[1] = viewport->yscale;
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
    index 934ae28da56..09794a52ad8 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
    @@ -81,7 +81,10 @@ void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsig
     struct r300_fragment_program_compiler {
     	struct radeon_compiler Base;
     	struct rX00_fragment_program_code *code;
    +	/* Optional transformations and features. */
     	struct r300_fragment_program_external_state state;
    +	unsigned enable_shadow_ambient;
    +	/* Hardware specification. */
     	unsigned is_r500;
     	unsigned max_temp_regs;
         /* Register corresponding to the depthbuffer. */
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    index 967fd74b003..200c1f710ba 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -31,13 +31,20 @@
     
     /* Series of transformations to be done on textures. */
     
    -static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
    +static struct rc_src_register shadow_ambient(struct r300_fragment_program_compiler *compiler,
    +											 int tmu)
     {
     	struct rc_src_register reg = { 0, };
     
    -	reg.File = RC_FILE_CONSTANT;
    -	reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
    -	reg.Swizzle = RC_SWIZZLE_WWWW;
    +	if (compiler->enable_shadow_ambient) {
    +		reg.File = RC_FILE_CONSTANT;
    +		reg.Index = rc_constants_add_state(&compiler->Base.Program.Constants,
    +										   RC_STATE_SHADOW_AMBIENT, tmu);
    +		reg.Swizzle = RC_SWIZZLE_WWWW;
    +	} else {
    +		reg.File = RC_FILE_NONE;
    +		reg.Swizzle = RC_SWIZZLE_0000;
    +	}
     	return reg;
     }
     
    @@ -102,7 +109,7 @@ int radeonTransformTEX(
     				inst->U.I.SrcReg[0].File = RC_FILE_NONE;
     				inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
     			} else {
    -				inst->U.I.SrcReg[0] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    +				inst->U.I.SrcReg[0] = shadow_ambient(compiler, inst->U.I.TexSrcUnit);
     			}
     
     			return 1;
    @@ -164,7 +171,7 @@ int radeonTransformTEX(
     
     			inst_cmp->U.I.SrcReg[pass].File = RC_FILE_NONE;
     			inst_cmp->U.I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
    -			inst_cmp->U.I.SrcReg[fail] = shadow_ambient(c, inst->U.I.TexSrcUnit);
    +			inst_cmp->U.I.SrcReg[fail] = shadow_ambient(compiler, inst->U.I.TexSrcUnit);
     		}
     	}
     
    diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c
    index f6c3a85e51b..0865a456443 100644
    --- a/src/mesa/drivers/dri/r300/r300_blit.c
    +++ b/src/mesa/drivers/dri/r300/r300_blit.c
    @@ -117,6 +117,7 @@ static void create_fragment_program(struct r300_context *r300)
         compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
         compiler.OutputColor[0] = FRAG_RESULT_COLOR;
         compiler.OutputDepth = FRAG_RESULT_DEPTH;
    +    compiler.enable_shadow_ambient = GL_TRUE;
         compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
         compiler.max_temp_regs = (compiler.is_r500) ? 128 : 32;
         compiler.code = &r300->blit.fp_code;
    diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    index ba841229565..2b7c93a9575 100644
    --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
    @@ -219,6 +219,7 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
     
     	compiler.code = &fp->code;
     	compiler.state = fp->state;
    +	compiler.enable_shadow_ambient = GL_TRUE;
     	compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
     	compiler.max_temp_regs = (compiler.is_r500) ? 128 : 32;
     	compiler.OutputDepth = FRAG_RESULT_DEPTH;
    -- 
    cgit v1.2.3
    
    
    From a94942e3796be135d3a6b6f9bfacb954088228d1 Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sat, 17 Apr 2010 01:31:25 +0200
    Subject: r300/compiler: add handy definitions for XYZ0 and smeared half
     swizzling
    
    ---
     src/mesa/drivers/dri/r300/compiler/radeon_compiler.c          | 6 +++---
     src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h | 2 ++
     2 files changed, 5 insertions(+), 3 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
    index 272f9072d4a..1c8ba864a41 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
    @@ -277,13 +277,13 @@ void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsig
     
     	inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
     	inst_mad->U.I.SrcReg[0].Index = tempregi;
    -	inst_mad->U.I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
    +	inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
     
     	inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    -	inst_mad->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
    +	inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;
     
     	inst_mad->U.I.SrcReg[2].File = RC_FILE_CONSTANT;
    -	inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
    +	inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZ0;
     
     	if (full_vtransform) {
     		inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_SCALE, 0);
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h
    index 7c0d6720b11..842012def02 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h
    @@ -114,12 +114,14 @@ typedef enum {
     	} while(0)
     
     #define RC_SWIZZLE_XYZW RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_W)
    +#define RC_SWIZZLE_XYZ0 RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO)
     #define RC_SWIZZLE_XXXX RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_X)
     #define RC_SWIZZLE_YYYY RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_Y)
     #define RC_SWIZZLE_ZZZZ RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_Z)
     #define RC_SWIZZLE_WWWW RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_W)
     #define RC_SWIZZLE_0000 RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_ZERO)
     #define RC_SWIZZLE_1111 RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_ONE)
    +#define RC_SWIZZLE_HHHH RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF)
     
     /**
      * \name Bitmasks for components of vectors.
    -- 
    cgit v1.2.3
    
    
    From f91a06eed27516b06d51cf437b9b165e8bcef35d Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sat, 17 Apr 2010 02:05:26 +0200
    Subject: r300/compiler: replace mirrored-repeat emulation with a faster
     version
    
    Also, the Negate bitfield was 1 instead of RC_MASK_XYZ in the previous
    version, causing incorrect rendering.
    ---
     .../drivers/dri/r300/compiler/radeon_program_tex.c | 127 +++++++++++----------
     1 file changed, 65 insertions(+), 62 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    index 200c1f710ba..a8927acdffa 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -191,19 +191,17 @@ int radeonTransformTEX(
     	 *
     	 * Mirroring is trickier. We're going to start out like repeat:
     	 *
    -	 * MUL temp0, texcoord,  ; De-mirror across axes
    -	 * MUL temp0, abs(temp0), 0.5 ; Pattern repeats in [0, 2]
    +	 * MUL temp, texcoord,  ; De-mirror across axes
    +	 * MUL temp, temp, 0.5 ; Pattern repeats in [0, 2]
     	 *                            ; so scale to [0, 1]
    -	 * FRC temp0, temp0 ; Make the pattern repeat
    -	 * SGE temp1, temp0, 0.5 ; Select components that need to be "reflected"
    -	 *                       ; across the mirror
    -	 * MAD temp0, neg(0.5), temp1, temp0 ; Add -0.5 to the
    -	 *                                   ; selected components
    -	 * ADD temp0, temp0, temp0 ; Poor man's 2x to undo earlier MUL
    +	 * FRC temp, temp ; Make the pattern repeat
    +	 * MAD temp, temp, 2, -1 ; Move the pattern to [-1, 1]
    +	 * ADD temp, 1, -abs(temp) ; Now comes a neat trick: use abs to mirror the pattern.
    +	 *				; The pattern is backwards, so reverse it (1-x).
     	 *
     	 * This gives us coords in [0, 1].
     	 *
    -	 * ~ C.
    +	 * ~ C & M. ;)
     	 */
     	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
     		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
    @@ -236,62 +234,67 @@ int radeonTransformTEX(
     				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
     				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
     			} else if (wrapmode == RC_WRAP_MIRROR) {
    -				unsigned temp1;
     				/*
    -				 * MUL temp0, abs(temp0), 0.5
    -				 * FRC temp0, temp0
    -				 * SGE temp1, temp0, 0.5
    -				 * MAD temp0, neg(0.5), temp1, temp0
    -				 * ADD temp0, temp0, temp0
    +				 * Function:
    +				 *   f(v) = 1 - abs(frac(v * 0.5) * 2 - 1)
    +				 *
    +				 * Code:
    +				 *   MUL temp, src0, 0.5
    +				 *   FRC temp, temp
    +				 *   MAD temp, temp, 2, -1
    +				 *   ADD temp, 1, -abs(temp)
     				 */
     
    -				struct rc_instruction *inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -
    -				temp1 = rc_find_free_temporary(c);
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp1;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp1;
    -				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
    -				inst_rect->U.I.SrcReg[1].Negate = 1;
    -				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[2].Index = temp;
    -
    -				inst_rect = rc_insert_new_instruction(c, inst->Prev);
    -
    -				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
    -				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.DstReg.Index = temp;
    -				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[0].Index = temp;
    -				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    -				inst_rect->U.I.SrcReg[1].Index = temp;
    +				struct rc_instruction *inst_mul, *inst_frc, *inst_mad, *inst_add;
    +				unsigned two, two_swizzle;
    +
    +				inst_mul = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_mul->U.I.Opcode = RC_OPCODE_MUL;
    +				inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_mul->U.I.DstReg.Index = temp;
    +				inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_HHHH;
    +
    +				inst_frc = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
    +				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_frc->U.I.DstReg.Index = temp;
    +				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_frc->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_frc->U.I.SrcReg[0].Index = temp;
    +				inst_frc->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
    +
    +				two = rc_constants_add_immediate_scalar(&c->Program.Constants, 2, &two_swizzle);
    +				inst_mad = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_mad->U.I.Opcode = RC_OPCODE_MAD;
    +				inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_mad->U.I.DstReg.Index = temp;
    +				inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +				inst_mad->U.I.SrcReg[0].Index = temp;
    +				inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
    +				inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
    +				inst_mad->U.I.SrcReg[1].Index = two;
    +				inst_mad->U.I.SrcReg[1].Swizzle = two_swizzle;
    +				inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_1111;
    +				inst_mad->U.I.SrcReg[2].Negate = RC_MASK_XYZ;
    +
    +				inst_add = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_add->U.I.Opcode = RC_OPCODE_ADD;
    +				inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_add->U.I.DstReg.Index = temp;
    +				inst_add->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
    +				inst_add->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    +				inst_add->U.I.SrcReg[1].Index = temp;
    +				inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;
    +				inst_add->U.I.SrcReg[1].Abs = 1;
    +				inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZ;
     			}
     
     			/* Preserve W for TXP/TXB. */
    -- 
    cgit v1.2.3
    
    
    From 411d5063323ccdb85ec090f1c852fcc8e9cd0e64 Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sat, 17 Apr 2010 02:43:47 +0200
    Subject: r300/compiler: add emulation of all mirrored-clamp wrap modes for
     NPOT textures
    
    ---
     src/gallium/drivers/r300/r300_fs.c                     |  6 +++++-
     src/mesa/drivers/dri/r300/compiler/radeon_code.h       |  3 ++-
     .../drivers/dri/r300/compiler/radeon_program_tex.c     | 18 +++++++++++++++++-
     3 files changed, 24 insertions(+), 3 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
    index a37f23aaef2..4d61f638530 100644
    --- a/src/gallium/drivers/r300/r300_fs.c
    +++ b/src/gallium/drivers/r300/r300_fs.c
    @@ -169,10 +169,14 @@ static void get_external_state(
                             break;
     
                         case PIPE_TEX_WRAP_MIRROR_REPEAT:
    +                        state->unit[i].wrap_mode = RC_WRAP_MIRRORED_REPEAT;
    +                        state->unit[i].fake_npot = TRUE;
    +                        break;
    +
                         case PIPE_TEX_WRAP_MIRROR_CLAMP:
                         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
                         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
    -                        state->unit[i].wrap_mode = RC_WRAP_MIRROR;
    +                        state->unit[i].wrap_mode = RC_WRAP_MIRRORED_CLAMP;
                             state->unit[i].fake_npot = TRUE;
                             break;
     
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    index 28bcd1029bb..27274f07122 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
    @@ -115,7 +115,8 @@ typedef enum {
     typedef enum {
     	RC_WRAP_NONE = 0,
     	RC_WRAP_REPEAT,
    -	RC_WRAP_MIRROR
    +	RC_WRAP_MIRRORED_REPEAT,
    +	RC_WRAP_MIRRORED_CLAMP
     } rc_wrap_mode;
     
     /**
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    index a8927acdffa..0ca95d454b6 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -233,7 +233,7 @@ int radeonTransformTEX(
     				inst_frc->U.I.DstReg.Index = temp;
     				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
     				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    -			} else if (wrapmode == RC_WRAP_MIRROR) {
    +			} else if (wrapmode == RC_WRAP_MIRRORED_REPEAT) {
     				/*
     				 * Function:
     				 *   f(v) = 1 - abs(frac(v * 0.5) * 2 - 1)
    @@ -295,6 +295,22 @@ int radeonTransformTEX(
     				inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;
     				inst_add->U.I.SrcReg[1].Abs = 1;
     				inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZ;
    +			} else if (wrapmode == RC_WRAP_MIRRORED_CLAMP) {
    +				/*
    +				 * Mirrored clamp modes are bloody simple, we just use abs
    +				 * to mirror [0, 1] into [-1, 0]. This works for
    +				 * all modes i.e. CLAMP, CLAMP_TO_EDGE, and CLAMP_TO_BORDER.
    +				 */
    +				struct rc_instruction *inst_mov;
    +
    +				inst_mov = rc_insert_new_instruction(c, inst->Prev);
    +
    +				inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +				inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +				inst_mov->U.I.DstReg.Index = temp;
    +				inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZ;
    +				inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +				inst_mov->U.I.SrcReg[0].Abs = 1;
     			}
     
     			/* Preserve W for TXP/TXB. */
    -- 
    cgit v1.2.3
    
    
    From 6be186a6faff1414d8b92d84ff6d275e1bf7ce98 Mon Sep 17 00:00:00 2001
    From: Vinson Lee 
    Date: Fri, 16 Apr 2010 22:58:49 -0700
    Subject: r300/compiler: Add radeon_program_tex.c to SCons build.
    
    This was missed in commit f8a14186809356871ae74159c774e9e3959a22e5.
    ---
     src/mesa/drivers/dri/r300/compiler/SConscript | 1 +
     1 file changed, 1 insertion(+)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/SConscript b/src/mesa/drivers/dri/r300/compiler/SConscript
    index 46075a8aee9..28a3d39d961 100755
    --- a/src/mesa/drivers/dri/r300/compiler/SConscript
    +++ b/src/mesa/drivers/dri/r300/compiler/SConscript
    @@ -17,6 +17,7 @@ r300compiler = env.ConvenienceLibrary(
             'radeon_opcodes.c',
             'radeon_program_alu.c',
             'radeon_program_pair.c',
    +        'radeon_program_tex.c',
             'radeon_pair_translate.c',
             'radeon_pair_schedule.c',
             'radeon_pair_regalloc.c',
    -- 
    cgit v1.2.3
    
    
    From 0a2ae64b77d4d0c1571cd457d5e01c599307122e Mon Sep 17 00:00:00 2001
    From: Vinson Lee 
    Date: Sat, 17 Apr 2010 12:13:19 -0700
    Subject: r300/compiler: Remove unnecessary header.
    
    ---
     src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c | 2 --
     1 file changed, 2 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    index 0ca95d454b6..b4ba0b3f870 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
    @@ -27,8 +27,6 @@
     
     #include "radeon_program_tex.h"
     
    -#include "../r300_reg.h"
    -
     /* Series of transformations to be done on textures. */
     
     static struct rc_src_register shadow_ambient(struct r300_fragment_program_compiler *compiler,
    -- 
    cgit v1.2.3
    
    
    From 4d7ed844313a4be64e9162369c935ce750cd9b06 Mon Sep 17 00:00:00 2001
    From: Nicolai Hähnle 
    Date: Sun, 11 Oct 2009 14:18:11 +0200
    Subject: r300/compiler: Implement branch emulation for R300 fragment programs
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    Signed-off-by: Nicolai Hähnle 
    ---
     src/mesa/drivers/dri/r300/compiler/Makefile        |   1 +
     src/mesa/drivers/dri/r300/compiler/memory_pool.h   |  31 ++
     src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c |  52 ++--
     .../drivers/dri/r300/compiler/radeon_dataflow.c    |  89 ++++++
     .../drivers/dri/r300/compiler/radeon_dataflow.h    |   6 +-
     .../dri/r300/compiler/radeon_emulate_branches.c    | 331 +++++++++++++++++++++
     .../dri/r300/compiler/radeon_emulate_branches.h    |  30 ++
     .../dri/r300/compiler/radeon_pair_regalloc.c       |  76 +----
     8 files changed, 512 insertions(+), 104 deletions(-)
     create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
     create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
    index c8acd3a3339..e432afc3d41 100644
    --- a/src/mesa/drivers/dri/r300/compiler/Makefile
    +++ b/src/mesa/drivers/dri/r300/compiler/Makefile
    @@ -8,6 +8,7 @@ LIBNAME = r300compiler
     C_SOURCES = \
     		radeon_code.c \
     		radeon_compiler.c \
    +		radeon_emulate_branches.c \
     		radeon_program.c \
     		radeon_program_print.c \
     		radeon_opcodes.c \
    diff --git a/src/mesa/drivers/dri/r300/compiler/memory_pool.h b/src/mesa/drivers/dri/r300/compiler/memory_pool.h
    index ce23c319ad3..42344d0e3ba 100644
    --- a/src/mesa/drivers/dri/r300/compiler/memory_pool.h
    +++ b/src/mesa/drivers/dri/r300/compiler/memory_pool.h
    @@ -46,4 +46,35 @@ void memory_pool_init(struct memory_pool * pool);
     void memory_pool_destroy(struct memory_pool * pool);
     void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes);
     
    +
    +/**
    + * Generic helper for growing an array that has separate size/count
    + * and reserved counters to accomodate up to num new element.
    + *
    + *  type * Array;
    + *  unsigned int Size;
    + *  unsigned int Reserved;
    + *
    + * memory_pool_array_reserve(pool, type, Array, Size, Reserved, k);
    + * assert(Size + k < Reserved);
    + *
    + * \note Size is not changed by this macro.
    + *
    + * \warning Array, Size, Reserved have to be lvalues and may be evaluated
    + * several times.
    + */
    +#define memory_pool_array_reserve(pool, type, array, size, reserved, num) do { \
    +	unsigned int _num = (num); \
    +	if ((size) + _num > (reserved)) { \
    +		unsigned int newreserve = (reserved) * 2; \
    +		type * newarray; \
    +		if (newreserve < _num) \
    +			newreserve = 4 * _num; /* arbitrary heuristic */ \
    +		newarray = memory_pool_malloc((pool), newreserve * sizeof(type)); \
    +		memcpy(newarray, (array), (size) * sizeof(type)); \
    +		(array) = newarray; \
    +		(reserved) = newreserve; \
    +	} \
    +} while(0)
    +
     #endif /* MEMORY_POOL_H */
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    index 5fe10dbfe8b..1e1053483de 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    @@ -25,6 +25,7 @@
     #include 
     
     #include "radeon_dataflow.h"
    +#include "radeon_emulate_branches.h"
     #include "radeon_program_alu.h"
     #include "radeon_program_tex.h"
     #include "r300_fragprog.h"
    @@ -85,6 +86,14 @@ static void rewrite_depth_out(struct r300_fragment_program_compiler * c)
     	}
     }
     
    +static void debug_program_log(struct r300_fragment_program_compiler* c, const char * where)
    +{
    +	if (c->Base.Debug) {
    +		fprintf(stderr, "Fragment Program: %s\n", where);
    +		rc_print_program(&c->Base.Program);
    +	}
    +}
    +
     void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     {
     	rewrite_depth_out(c);
    @@ -106,6 +115,10 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     		};
     		radeonLocalTransform(&c->Base, 2, transformations);
     
    +		debug_program_log(c, "before emulate branches");
    +
    +		rc_emulate_branches(&c->Base);
    +
     		c->Base.SwizzleCaps = &r300_swizzle_caps;
     	}
     
    @@ -119,62 +132,41 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     	common_transformations[0].function = &radeonTransformALU;
     	radeonLocalTransform(&c->Base, 1, common_transformations);
     
    -	if (c->Base.Debug) {
    -		fprintf(stderr, "Fragment Program: After native rewrite:\n");
    -		rc_print_program(&c->Base.Program);
    -		fflush(stderr);
    -	}
    +	if (c->Base.Error)
    +		return;
    +
    +	debug_program_log(c, "after native rewrite");
     
     	rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_use, c);
     	if (c->Base.Error)
     		return;
     
    -	if (c->Base.Debug) {
    -		fprintf(stderr, "Fragment Program: After deadcode:\n");
    -		rc_print_program(&c->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(c, "after deadcode");
     
     	rc_dataflow_swizzles(&c->Base);
     	if (c->Base.Error)
     		return;
     
    -	if (c->Base.Debug) {
    -		fprintf(stderr, "Compiler: after dataflow passes:\n");
    -		rc_print_program(&c->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(c, "after dataflow passes");
     
     	rc_pair_translate(c);
     	if (c->Base.Error)
     		return;
     
    -	if (c->Base.Debug) {
    -		fprintf(stderr, "Compiler: after pair translate:\n");
    -		rc_print_program(&c->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(c, "after pair translate");
     
     	rc_pair_schedule(c);
     	if (c->Base.Error)
     		return;
     
    -	if (c->Base.Debug) {
    -		fprintf(stderr, "Compiler: after pair scheduling:\n");
    -		rc_print_program(&c->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(c, "after pair scheduling");
     
     	rc_pair_regalloc(c, c->max_temp_regs);
     
     	if (c->Base.Error)
     		return;
     
    -	if (c->Base.Debug) {
    -		fprintf(stderr, "Compiler: after pair register allocation:\n");
    -		rc_print_program(&c->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(c, "after register allocation");
     
     	if (c->is_r500) {
     		r500BuildFragmentProgramHwCode(c);
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
    index cce9166e644..16e2f3a2181 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
    @@ -160,3 +160,92 @@ void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void *
     		writes_pair(inst, cb, userdata);
     	}
     }
    +
    +
    +static void remap_normal_instruction(struct rc_instruction * fullinst,
    +		rc_remap_register_fn cb, void * userdata)
    +{
    +	struct rc_sub_instruction * inst = &fullinst->U.I;
    +	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
    +
    +	if (opcode->HasDstReg) {
    +		rc_register_file file = inst->DstReg.File;
    +		unsigned int index = inst->DstReg.Index;
    +
    +		cb(userdata, fullinst, &file, &index);
    +
    +		inst->DstReg.File = file;
    +		inst->DstReg.Index = index;
    +	}
    +
    +	for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
    +		rc_register_file file = inst->SrcReg[src].File;
    +		unsigned int index = inst->SrcReg[src].Index;
    +
    +		cb(userdata, fullinst, &file, &index);
    +
    +		inst->SrcReg[src].File = file;
    +		inst->SrcReg[src].Index = index;
    +	}
    +}
    +
    +static void remap_pair_instruction(struct rc_instruction * fullinst,
    +		rc_remap_register_fn cb, void * userdata)
    +{
    +	struct rc_pair_instruction * inst = &fullinst->U.P;
    +
    +	if (inst->RGB.WriteMask) {
    +		rc_register_file file = RC_FILE_TEMPORARY;
    +		unsigned int index = inst->RGB.DestIndex;
    +
    +		cb(userdata, fullinst, &file, &index);
    +
    +		inst->RGB.DestIndex = index;
    +	}
    +
    +	if (inst->Alpha.WriteMask) {
    +		rc_register_file file = RC_FILE_TEMPORARY;
    +		unsigned int index = inst->Alpha.DestIndex;
    +
    +		cb(userdata, fullinst, &file, &index);
    +
    +		inst->Alpha.DestIndex = index;
    +	}
    +
    +	for(unsigned int src = 0; src < 3; ++src) {
    +		if (inst->RGB.Src[src].Used) {
    +			rc_register_file file = inst->RGB.Src[src].File;
    +			unsigned int index = inst->RGB.Src[src].Index;
    +
    +			cb(userdata, fullinst, &file, &index);
    +
    +			inst->RGB.Src[src].File = file;
    +			inst->RGB.Src[src].Index = index;
    +		}
    +
    +		if (inst->Alpha.Src[src].Used) {
    +			rc_register_file file = inst->Alpha.Src[src].File;
    +			unsigned int index = inst->Alpha.Src[src].Index;
    +
    +			cb(userdata, fullinst, &file, &index);
    +
    +			inst->Alpha.Src[src].File = file;
    +			inst->Alpha.Src[src].Index = index;
    +		}
    +	}
    +}
    +
    +
    +/**
    + * Remap all register accesses according to the given function.
    + * That is, call the function \p cb for each referenced register (both read and written)
    + * and update the given instruction \p inst accordingly
    + * if it modifies its \ref pfile and \ref pindex contents.
    + */
    +void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata)
    +{
    +	if (inst->Type == RC_INSTRUCTION_NORMAL)
    +		remap_normal_instruction(inst, cb, userdata);
    +	else
    +		remap_pair_instruction(inst, cb, userdata);
    +}
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
    index 5aa4cb64f3d..62cda20eea6 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
    @@ -36,13 +36,17 @@ struct rc_swizzle_caps;
     
     
     /**
    - * Help analyze the register accesses of instructions.
    + * Help analyze and modify the register accesses of instructions.
      */
     /*@{*/
     typedef void (*rc_read_write_fn)(void * userdata, struct rc_instruction * inst,
     			rc_register_file file, unsigned int index, unsigned int chan);
     void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata);
     void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata);
    +
    +typedef void (*rc_remap_register_fn)(void * userdata, struct rc_instruction * inst,
    +			rc_register_file * pfile, unsigned int * pindex);
    +void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata);
     /*@}*/
     
     
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
    new file mode 100644
    index 00000000000..d889612f4f4
    --- /dev/null
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
    @@ -0,0 +1,331 @@
    +/*
    + * Copyright 2009 Nicolai Hähnle 
    + *
    + * 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
    + * THE AUTHOR(S) 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 "radeon_emulate_branches.h"
    +
    +#include 
    +
    +#include "radeon_compiler.h"
    +#include "radeon_dataflow.h"
    +
    +#define VERBOSE 0
    +
    +#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
    +
    +
    +struct proxy_info {
    +	unsigned int Proxied:1;
    +	unsigned int Index:RC_REGISTER_INDEX_BITS;
    +};
    +
    +struct register_proxies {
    +	struct proxy_info Temporary[RC_REGISTER_MAX_INDEX];
    +};
    +
    +struct branch_info {
    +	struct rc_instruction * If;
    +	struct rc_instruction * Else;
    +};
    +
    +struct emulate_branch_state {
    +	struct radeon_compiler * C;
    +
    +	struct branch_info * Branches;
    +	unsigned int BranchCount;
    +	unsigned int BranchReserved;
    +};
    +
    +
    +static void handle_if(struct emulate_branch_state * s, struct rc_instruction * inst)
    +{
    +	memory_pool_array_reserve(&s->C->Pool, struct branch_info,
    +			s->Branches, s->BranchCount, s->BranchReserved, 1);
    +
    +	DBG("%s\n", __FUNCTION__);
    +
    +	struct branch_info * branch = &s->Branches[s->BranchCount++];
    +	memset(branch, 0, sizeof(struct branch_info));
    +	branch->If = inst;
    +
    +	/* Make a safety copy of the decision register, because we will need
    +	 * it at ENDIF time and it might be overwritten in both branches. */
    +	struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, inst->Prev);
    +	inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +	inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +	inst_mov->U.I.DstReg.Index = rc_find_free_temporary(s->C);
    +	inst_mov->U.I.DstReg.WriteMask = RC_MASK_X;
    +	inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
    +
    +	inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +	inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index;
    +	inst->U.I.SrcReg[0].Swizzle = 0;
    +	inst->U.I.SrcReg[0].Abs = 0;
    +	inst->U.I.SrcReg[0].Negate = 0;
    +}
    +
    +static void handle_else(struct emulate_branch_state * s, struct rc_instruction * inst)
    +{
    +	if (!s->BranchCount) {
    +		rc_error(s->C, "Encountered ELSE outside of branches");
    +		return;
    +	}
    +
    +	DBG("%s\n", __FUNCTION__);
    +
    +	struct branch_info * branch = &s->Branches[s->BranchCount - 1];
    +	branch->Else = inst;
    +}
    +
    +
    +struct state_and_proxies {
    +	struct emulate_branch_state * S;
    +	struct register_proxies * Proxies;
    +};
    +
    +static struct proxy_info * get_proxy_info(struct state_and_proxies * sap,
    +			rc_register_file file, unsigned int index)
    +{
    +	if (file == RC_FILE_TEMPORARY) {
    +		return &sap->Proxies->Temporary[index];
    +	} else {
    +		return 0;
    +	}
    +}
    +
    +static void scan_write(void * userdata, struct rc_instruction * inst,
    +		rc_register_file file, unsigned int index, unsigned int comp)
    +{
    +	struct state_and_proxies * sap = userdata;
    +	struct proxy_info * proxy = get_proxy_info(sap, file, index);
    +
    +	if (proxy && !proxy->Proxied) {
    +		proxy->Proxied = 1;
    +		proxy->Index = rc_find_free_temporary(sap->S->C);
    +	}
    +}
    +
    +static void remap_proxy_function(void * userdata, struct rc_instruction * inst,
    +		rc_register_file * pfile, unsigned int * pindex)
    +{
    +	struct state_and_proxies * sap = userdata;
    +	struct proxy_info * proxy = get_proxy_info(sap, *pfile, *pindex);
    +
    +	if (proxy && proxy->Proxied) {
    +		*pfile = RC_FILE_TEMPORARY;
    +		*pindex = proxy->Index;
    +	}
    +}
    +
    +/**
    + * Redirect all writes in the instruction range [begin, end) to proxy
    + * temporary registers.
    + */
    +static void allocate_and_insert_proxies(struct emulate_branch_state * s,
    +		struct register_proxies * proxies,
    +		struct rc_instruction * begin,
    +		struct rc_instruction * end)
    +{
    +	struct state_and_proxies sap;
    +
    +	sap.S = s;
    +	sap.Proxies = proxies;
    +
    +	for(struct rc_instruction * inst = begin; inst != end; inst = inst->Next) {
    +		rc_for_all_writes(inst, scan_write, &sap);
    +		rc_remap_registers(inst, remap_proxy_function, &sap);
    +	}
    +
    +	for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) {
    +		if (proxies->Temporary[index].Proxied) {
    +			struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, begin->Prev);
    +			inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +			inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
    +			inst_mov->U.I.DstReg.Index = proxies->Temporary[index].Index;
    +			inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    +			inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +			inst_mov->U.I.SrcReg[0].Index = index;
    +		}
    +	}
    +}
    +
    +
    +static void inject_cmp(struct emulate_branch_state * s,
    +		struct rc_instruction * inst_if,
    +		struct rc_instruction * inst_endif,
    +		rc_register_file file, unsigned int index,
    +		struct proxy_info ifproxy,
    +		struct proxy_info elseproxy)
    +{
    +	struct rc_instruction * inst_cmp = rc_insert_new_instruction(s->C, inst_endif);
    +	inst_cmp->U.I.Opcode = RC_OPCODE_CMP;
    +	inst_cmp->U.I.DstReg.File = file;
    +	inst_cmp->U.I.DstReg.Index = index;
    +	inst_cmp->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    +	inst_cmp->U.I.SrcReg[0] = inst_if->U.I.SrcReg[0];
    +	inst_cmp->U.I.SrcReg[0].Abs = 1;
    +	inst_cmp->U.I.SrcReg[0].Negate = RC_MASK_XYZW;
    +	inst_cmp->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
    +	inst_cmp->U.I.SrcReg[1].Index = ifproxy.Proxied ? ifproxy.Index : index;
    +	inst_cmp->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
    +	inst_cmp->U.I.SrcReg[2].Index = elseproxy.Proxied ? elseproxy.Index : index;
    +}
    +
    +static void handle_endif(struct emulate_branch_state * s, struct rc_instruction * inst)
    +{
    +	if (!s->BranchCount) {
    +		rc_error(s->C, "Encountered ENDIF outside of branches");
    +		return;
    +	}
    +
    +	DBG("%s\n", __FUNCTION__);
    +
    +	struct branch_info * branch = &s->Branches[s->BranchCount - 1];
    +	struct register_proxies IfProxies;
    +	struct register_proxies ElseProxies;
    +
    +	memset(&IfProxies, 0, sizeof(IfProxies));
    +	memset(&ElseProxies, 0, sizeof(ElseProxies));
    +
    +	allocate_and_insert_proxies(s, &IfProxies, branch->If->Next, branch->Else ? branch->Else : inst);
    +
    +	if (branch->Else)
    +		allocate_and_insert_proxies(s, &ElseProxies, branch->Else->Next, inst);
    +
    +	/* Insert the CMP instructions at the end. */
    +	for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) {
    +		if (IfProxies.Temporary[index].Proxied || ElseProxies.Temporary[index].Proxied) {
    +			inject_cmp(s, branch->If, inst, RC_FILE_TEMPORARY, index,
    +					IfProxies.Temporary[index], ElseProxies.Temporary[index]);
    +		}
    +	}
    +
    +	/* Remove all traces of the branch instructions */
    +	rc_remove_instruction(branch->If);
    +	if (branch->Else)
    +		rc_remove_instruction(branch->Else);
    +	rc_remove_instruction(inst);
    +
    +	s->BranchCount--;
    +
    +	if (VERBOSE) {
    +		DBG("Program after ENDIF handling:\n");
    +		rc_print_program(&s->C->Program);
    +	}
    +}
    +
    +
    +struct remap_output_data {
    +	unsigned int Output:RC_REGISTER_INDEX_BITS;
    +	unsigned int Temporary:RC_REGISTER_INDEX_BITS;
    +};
    +
    +static void remap_output_function(void * userdata, struct rc_instruction * inst,
    +		rc_register_file * pfile, unsigned int * pindex)
    +{
    +	struct remap_output_data * data = userdata;
    +
    +	if (*pfile == RC_FILE_OUTPUT && *pindex == data->Output) {
    +		*pfile = RC_FILE_TEMPORARY;
    +		*pindex = data->Temporary;
    +	}
    +}
    +
    +
    +/**
    + * Output registers cannot be read from and so cannot be dealt with like
    + * temporary registers.
    + *
    + * We do the simplest thing: If an output registers is written within
    + * a branch, then *all* writes to this register are proxied to a
    + * temporary register, and a final MOV is appended to the end of
    + * the program.
    + */
    +static void fix_output_writes(struct emulate_branch_state * s, struct rc_instruction * inst)
    +{
    +	if (!s->BranchCount)
    +		return;
    +
    +	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
    +
    +	if (!opcode->HasDstReg)
    +		return;
    +
    +	if (inst->U.I.DstReg.File == RC_FILE_OUTPUT) {
    +		struct remap_output_data remap;
    +
    +		remap.Output = inst->U.I.DstReg.Index;
    +		remap.Temporary = rc_find_free_temporary(s->C);
    +
    +		for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
    +		    inst != &s->C->Program.Instructions;
    +		    inst = inst->Next) {
    +			rc_remap_registers(inst, &remap_output_function, &remap);
    +		}
    +
    +		struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, s->C->Program.Instructions.Prev);
    +		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
    +		inst_mov->U.I.DstReg.File = RC_FILE_OUTPUT;
    +		inst_mov->U.I.DstReg.Index = remap.Output;
    +		inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZW;
    +		inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
    +		inst_mov->U.I.SrcReg[0].Index = remap.Temporary;
    +	}
    +}
    +
    +/**
    + * Remove branch instructions; instead, execute both branches
    + * on different register sets and choose between their results
    + * using CMP instructions in place of the original ENDIF.
    + */
    +void rc_emulate_branches(struct radeon_compiler * c)
    +{
    +	struct emulate_branch_state s;
    +
    +	memset(&s, 0, sizeof(s));
    +	s.C = c;
    +
    +	/* Untypical loop because we may remove the current instruction */
    +	struct rc_instruction * ptr = c->Program.Instructions.Next;
    +	while(ptr != &c->Program.Instructions) {
    +		struct rc_instruction * inst = ptr;
    +		ptr = ptr->Next;
    +
    +		if (inst->Type == RC_INSTRUCTION_NORMAL) {
    +			switch(inst->U.I.Opcode) {
    +			case RC_OPCODE_IF:
    +				handle_if(&s, inst);
    +				break;
    +			case RC_OPCODE_ELSE:
    +				handle_else(&s, inst);
    +				break;
    +			case RC_OPCODE_ENDIF:
    +				handle_endif(&s, inst);
    +				break;
    +			default:
    +				fix_output_writes(&s, inst);
    +				break;
    +			}
    +		} else {
    +			rc_error(c, "%s: unhandled instruction type\n", __FUNCTION__);
    +		}
    +	}
    +}
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h
    new file mode 100644
    index 00000000000..e07279f0933
    --- /dev/null
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h
    @@ -0,0 +1,30 @@
    +/*
    + * Copyright 2009 Nicolai Hähnle 
    + *
    + * 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
    + * THE AUTHOR(S) 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_EMULATE_BRANCHES_H
    +#define RADEON_EMULATE_BRANCHES_H
    +
    +struct radeon_compiler;
    +
    +void rc_emulate_branches(struct radeon_compiler * c);
    +
    +#endif /* RADEON_EMULATE_BRANCHES_H */
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
    index b2fe7f76b2f..fdfee867014 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
    @@ -196,9 +196,10 @@ static void compute_live_intervals(struct regalloc_state * s)
     	}
     }
     
    -static void rewrite_register(struct regalloc_state * s,
    +static void remap_register(void * data, struct rc_instruction * inst,
     		rc_register_file * file, unsigned int * index)
     {
    +	struct regalloc_state * s = data;
     	const struct register_info * reg;
     
     	if (*file == RC_FILE_TEMPORARY)
    @@ -214,74 +215,6 @@ static void rewrite_register(struct regalloc_state * s,
     	}
     }
     
    -static void rewrite_normal_instruction(struct regalloc_state * s, struct rc_sub_instruction * inst)
    -{
    -	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
    -
    -	if (opcode->HasDstReg) {
    -		rc_register_file file = inst->DstReg.File;
    -		unsigned int index = inst->DstReg.Index;
    -
    -		rewrite_register(s, &file, &index);
    -
    -		inst->DstReg.File = file;
    -		inst->DstReg.Index = index;
    -	}
    -
    -	for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
    -		rc_register_file file = inst->SrcReg[src].File;
    -		unsigned int index = inst->SrcReg[src].Index;
    -
    -		rewrite_register(s, &file, &index);
    -
    -		inst->SrcReg[src].File = file;
    -		inst->SrcReg[src].Index = index;
    -	}
    -}
    -
    -static void rewrite_pair_instruction(struct regalloc_state * s, struct rc_pair_instruction * inst)
    -{
    -	if (inst->RGB.WriteMask) {
    -		rc_register_file file = RC_FILE_TEMPORARY;
    -		unsigned int index = inst->RGB.DestIndex;
    -
    -		rewrite_register(s, &file, &index);
    -
    -		inst->RGB.DestIndex = index;
    -	}
    -
    -	if (inst->Alpha.WriteMask) {
    -		rc_register_file file = RC_FILE_TEMPORARY;
    -		unsigned int index = inst->Alpha.DestIndex;
    -
    -		rewrite_register(s, &file, &index);
    -
    -		inst->Alpha.DestIndex = index;
    -	}
    -
    -	for(unsigned int src = 0; src < 3; ++src) {
    -		if (inst->RGB.Src[src].Used) {
    -			rc_register_file file = inst->RGB.Src[src].File;
    -			unsigned int index = inst->RGB.Src[src].Index;
    -
    -			rewrite_register(s, &file, &index);
    -
    -			inst->RGB.Src[src].File = file;
    -			inst->RGB.Src[src].Index = index;
    -		}
    -
    -		if (inst->Alpha.Src[src].Used) {
    -			rc_register_file file = inst->Alpha.Src[src].File;
    -			unsigned int index = inst->Alpha.Src[src].Index;
    -
    -			rewrite_register(s, &file, &index);
    -
    -			inst->Alpha.Src[src].File = file;
    -			inst->Alpha.Src[src].Index = index;
    -		}
    -	}
    -}
    -
     static void do_regalloc(struct regalloc_state * s)
     {
     	/* Simple and stupid greedy register allocation */
    @@ -310,10 +243,7 @@ static void do_regalloc(struct regalloc_state * s)
     	for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
     	    inst != &s->C->Program.Instructions;
     	    inst = inst->Next) {
    -		if (inst->Type == RC_INSTRUCTION_NORMAL)
    -			rewrite_normal_instruction(s, &inst->U.I);
    -		else
    -			rewrite_pair_instruction(s, &inst->U.P);
    +		rc_remap_registers(inst, &remap_register, s);
     	}
     }
     
    -- 
    cgit v1.2.3
    
    
    From 340e5e65dc1a7b82c8f910971c185bb4627204ea Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sun, 11 Oct 2009 14:18:11 +0200
    Subject: r300/compiler: enable branch emulation for R500 fragment programs
    
    ---
     src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c | 17 +++++++++++++----
     1 file changed, 13 insertions(+), 4 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    index 1e1053483de..25bf373b6fd 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
    @@ -98,6 +98,15 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     {
     	rewrite_depth_out(c);
     
    +	debug_program_log(c, "before compilation");
    +
    +	/* XXX Ideally this should be done only for r3xx, but since
    +	 * we don't have branching support for r5xx, we use the emulation
    +	 * on all chipsets. */
    +	rc_emulate_branches(&c->Base);
    +
    +	debug_program_log(c, "after emulate branches");
    +
     	if (c->is_r500) {
     		struct radeon_program_transformation transformations[] = {
     			{ &r500_transform_IF, 0 },
    @@ -107,6 +116,8 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     		};
     		radeonLocalTransform(&c->Base, 4, transformations);
     
    +		debug_program_log(c, "after native rewrite part 1");
    +
     		c->Base.SwizzleCaps = &r500_swizzle_caps;
     	} else {
     		struct radeon_program_transformation transformations[] = {
    @@ -115,9 +126,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     		};
     		radeonLocalTransform(&c->Base, 2, transformations);
     
    -		debug_program_log(c, "before emulate branches");
    -
    -		rc_emulate_branches(&c->Base);
    +		debug_program_log(c, "after native rewrite part 1");
     
     		c->Base.SwizzleCaps = &r300_swizzle_caps;
     	}
    @@ -135,7 +144,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
     	if (c->Base.Error)
     		return;
     
    -	debug_program_log(c, "after native rewrite");
    +	debug_program_log(c, "after native rewrite part 2");
     
     	rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_use, c);
     	if (c->Base.Error)
    -- 
    cgit v1.2.3
    
    
    From 0321f9c6f13a7571376e5eb9ce6c110061ed09fd Mon Sep 17 00:00:00 2001
    From: Nicolai Hähnle 
    Date: Sun, 11 Oct 2009 14:22:16 +0200
    Subject: r300/compiler: Use memory_pool_array_reserve in r500-fragprog_emit
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    Signed-off-by: Nicolai Hähnle 
    ---
     .../drivers/dri/r300/compiler/r500_fragprog_emit.c    | 19 ++-----------------
     1 file changed, 2 insertions(+), 17 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    index b6dfe28def9..10c5e2349e9 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
    @@ -348,21 +348,6 @@ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_inst
     	return 1;
     }
     
    -static void grow_branches(struct emit_state * s)
    -{
    -	unsigned int newreserved = s->BranchesReserved * 2;
    -	struct branch_info * newbranches;
    -
    -	if (!newreserved)
    -		newreserved = 4;
    -
    -	newbranches = memory_pool_malloc(&s->C->Pool, newreserved*sizeof(struct branch_info));
    -	memcpy(newbranches, s->Branches, s->CurrentBranchDepth*sizeof(struct branch_info));
    -
    -	s->Branches = newbranches;
    -	s->BranchesReserved = newreserved;
    -}
    -
     static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst)
     {
     	if (s->Code->inst_end >= 511) {
    @@ -380,8 +365,8 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
     			return;
     		}
     
    -		if (s->CurrentBranchDepth >= s->BranchesReserved)
    -			grow_branches(s);
    +		memory_pool_array_reserve(&s->C->Pool, struct branch_info,
    +				s->Branches, s->CurrentBranchDepth, s->BranchesReserved, 1);
     
     		struct branch_info * branch = &s->Branches[s->CurrentBranchDepth++];
     		branch->If = newip;
    -- 
    cgit v1.2.3
    
    
    From 65fd6fb2044521511b867c76e270f285d0b15f06 Mon Sep 17 00:00:00 2001
    From: Nicolai Hähnle 
    Date: Sun, 11 Oct 2009 14:24:52 +0200
    Subject: r300/compiler: Use memory_pool_array_reserve in deadcode elimination
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    Signed-off-by: Nicolai Hähnle 
    ---
     .../drivers/dri/r300/compiler/radeon_dataflow_deadcode.c  | 15 ++-------------
     1 file changed, 2 insertions(+), 13 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
    index f3734852cc6..e3c2c83c0cf 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
    @@ -80,19 +80,8 @@ static void or_updatemasks(
     
     static void push_branch(struct deadcode_state * s)
     {
    -	if (s->BranchStackSize >= s->BranchStackReserved) {
    -		unsigned int new_reserve = 2 * s->BranchStackReserved;
    -		struct branchinfo * new_stack;
    -
    -		if (!new_reserve)
    -			new_reserve = 4;
    -
    -		new_stack = memory_pool_malloc(&s->C->Pool, new_reserve * sizeof(struct branchinfo));
    -		memcpy(new_stack, s->BranchStack, s->BranchStackSize * sizeof(struct branchinfo));
    -
    -		s->BranchStack = new_stack;
    -		s->BranchStackReserved = new_reserve;
    -	}
    +	memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack,
    +			s->BranchStackSize, s->BranchStackReserved, 1);
     
     	struct branchinfo * branch = &s->BranchStack[s->BranchStackSize++];
     	branch->HaveElse = 0;
    -- 
    cgit v1.2.3
    
    
    From ebd05a798e34f99bfa35c18803de47662e9e4840 Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sun, 18 Apr 2010 20:49:50 +0200
    Subject: r300/compiler: optimize CMP for vertex shaders a bit
    
    ---
     .../drivers/dri/r300/compiler/radeon_program_alu.c | 29 +++++++---------------
     1 file changed, 9 insertions(+), 20 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    index f5b7d57eab7..fced31d6cb9 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    @@ -511,37 +511,26 @@ static void transform_r300_vertex_CMP(struct radeon_compiler* c,
     {
     	/* There is no decent CMP available, so let's rig one up.
     	 * CMP is defined as dst = src0 < 0.0 ? src1 : src2
    -	 * The following sequence consumes two temps and three extra slots,
    +	 * The following sequence consumes two temps and two extra slots
    +	 * (the second temp and the second slot is consumed by transform_LRP),
     	 * but should be equivalent:
     	 *
     	 * SLT tmp0, src0, 0.0
    -	 * SGE tmp1, src0, 0.0
    -	 * MUL tmp0, tmp0, src1
    -	 * MAD dst, src2, tmp1, tmp0
    +	 * LRP dst, tmp0, src1, src2
     	 *
    -	 * Yes, I know, I'm a mad scientist. ~ C. */
    +	 * Yes, I know, I'm a mad scientist. ~ C. & M. */
     	int tempreg0 = rc_find_free_temporary(c);
    -	int tempreg1 = rc_find_free_temporary(c);
     
     	/* SLT tmp0, src0, 0.0 */
     	emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
     		dstreg(RC_FILE_TEMPORARY, tempreg0),
     		inst->U.I.SrcReg[0], builtin_zero);
     
    -	/* SGE tmp1, src0, 0.0 */
    -	emit2(c, inst->Prev, RC_OPCODE_SGE, 0,
    -		dstreg(RC_FILE_TEMPORARY, tempreg1),
    -		inst->U.I.SrcReg[0], builtin_zero);
    -
    -	/* MUL tmp0, tmp0, src1 */
    -	emit2(c, inst->Prev, RC_OPCODE_MUL, 0,
    -		dstreg(RC_FILE_TEMPORARY, tempreg0),
    -		srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1]);
    -
    -	/* MAD dst, src2, tmp1, tmp0 */
    -	emit3(c, inst->Prev, RC_OPCODE_MAD, inst->U.I.SaturateMode,
    -		inst->U.I.DstReg,
    -		inst->U.I.SrcReg[2], srcreg(RC_FILE_TEMPORARY, tempreg1), srcreg(RC_FILE_TEMPORARY, tempreg0));
    +	/* LRP dst, tmp0, src1, src2 */
    +	transform_LRP(c,
    +		emit3(c, inst->Prev, RC_OPCODE_LRP, 0,
    +		      inst->U.I.DstReg,
    +		      srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1],  inst->U.I.SrcReg[2]));
     
     	rc_remove_instruction(inst);
     }
    -- 
    cgit v1.2.3
    
    
    From e53a1576dde7ba9d22b48a8e4b5d41b71411ec1d Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sun, 18 Apr 2010 19:45:51 +0200
    Subject: r300/compiler: enable branch emulation for vertex shaders
    
    ---
     src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c | 43 +++++++++++-----------
     1 file changed, 22 insertions(+), 21 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
    index 1b2cb8dde7d..4a0b6c02efe 100644
    --- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
    +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
    @@ -29,7 +29,7 @@
     #include "radeon_dataflow.h"
     #include "radeon_program_alu.h"
     #include "radeon_swizzle.h"
    -
    +#include "radeon_emulate_branches.h"
     
     /*
      * Take an already-setup and valid source then swizzle it appropriately to
    @@ -566,6 +566,14 @@ static int swizzle_is_native(rc_opcode opcode, struct rc_src_register reg)
     	return 1;
     }
     
    +static void debug_program_log(struct r300_vertex_program_compiler* c, const char * where)
    +{
    +	if (c->Base.Debug) {
    +		fprintf(stderr, "Vertex Program: %s\n", where);
    +		rc_print_program(&c->Base.Program);
    +	}
    +}
    +
     
     static struct rc_swizzle_caps r300_vertprog_swizzle_caps = {
     	.IsNative = &swizzle_is_native,
    @@ -579,6 +587,15 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
     
     	addArtificialOutputs(compiler);
     
    +	debug_program_log(compiler, "before compilation");
    +
    +	/* XXX Ideally this should be done only for r3xx, but since
    +	 * we don't have branching support for r5xx, we use the emulation
    +	 * on all chipsets. */
    +	rc_emulate_branches(&compiler->Base);
    +
    +	debug_program_log(compiler, "after emulate branches");
    +
     	{
     		struct radeon_program_transformation transformations[] = {
     			{ &r300_transform_vertex_alu, 0 },
    @@ -586,11 +603,7 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
     		radeonLocalTransform(&compiler->Base, 1, transformations);
     	}
     
    -	if (compiler->Base.Debug) {
    -		fprintf(stderr, "Vertex program after native rewrite:\n");
    -		rc_print_program(&compiler->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(compiler, "after native rewrite");
     
     	{
     		/* Note: This pass has to be done seperately from ALU rewrite,
    @@ -603,29 +616,17 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
     		radeonLocalTransform(&compiler->Base, 1, transformations);
     	}
     
    -	if (compiler->Base.Debug) {
    -		fprintf(stderr, "Vertex program after source conflict resolve:\n");
    -		rc_print_program(&compiler->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(compiler, "after source conflict resolve");
     
     	rc_dataflow_deadcode(&compiler->Base, &dataflow_outputs_mark_used, compiler);
     
    -	if (compiler->Base.Debug) {
    -		fprintf(stderr, "Vertex program after deadcode:\n");
    -		rc_print_program(&compiler->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(compiler, "after deadcode");
     
     	rc_dataflow_swizzles(&compiler->Base);
     
     	allocate_temporary_registers(compiler);
     
    -	if (compiler->Base.Debug) {
    -		fprintf(stderr, "Vertex program after dataflow:\n");
    -		rc_print_program(&compiler->Base.Program);
    -		fflush(stderr);
    -	}
    +	debug_program_log(compiler, "after dataflow");
     
     	translate_vertex_program(compiler);
     
    -- 
    cgit v1.2.3
    
    
    From 394803b2cd7fd9d4c0a394eb6998ccafec19bcd3 Mon Sep 17 00:00:00 2001
    From: Marek Olšák 
    Date: Sun, 18 Apr 2010 23:40:01 +0200
    Subject: r300/compiler: lower CEIL
    
    ---
     src/gallium/drivers/r300/r300_tgsi_to_rc.c         |  2 +-
     .../drivers/dri/r300/compiler/radeon_opcodes.c     |  7 +++++++
     .../drivers/dri/r300/compiler/radeon_opcodes.h     |  3 +++
     .../drivers/dri/r300/compiler/radeon_program_alu.c | 24 +++++++++++++++++++++-
     4 files changed, 34 insertions(+), 2 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
    index 21a1c45982d..fcc0f9a3c02 100644
    --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
    +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
    @@ -115,7 +115,7 @@ static unsigned translate_opcode(unsigned opcode)
          /* case TGSI_OPCODE_ENDREP: return RC_OPCODE_ENDREP; */
          /* case TGSI_OPCODE_PUSHA: return RC_OPCODE_PUSHA; */
          /* case TGSI_OPCODE_POPA: return RC_OPCODE_POPA; */
    -     /* case TGSI_OPCODE_CEIL: return RC_OPCODE_CEIL; */
    +        case TGSI_OPCODE_CEIL: return RC_OPCODE_CEIL;
          /* case TGSI_OPCODE_I2F: return RC_OPCODE_I2F; */
          /* case TGSI_OPCODE_NOT: return RC_OPCODE_NOT; */
          /* case TGSI_OPCODE_TRUNC: return RC_OPCODE_TRUNC; */
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    index ffc91241ab8..d593b3e81ae 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
    @@ -59,6 +59,13 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
     		.NumSrcRegs = 1,
     		.HasDstReg = 1
     	},
    +	{
    +		.Opcode = RC_OPCODE_CEIL,
    +		.Name = "CEIL",
    +		.NumSrcRegs = 1,
    +		.HasDstReg = 1,
    +		.IsComponentwise = 1
    +	},
     	{
     		.Opcode = RC_OPCODE_CMP,
     		.Name = "CMP",
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
    index 1c9b34df78e..87a2e23084c 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
    @@ -47,6 +47,9 @@ typedef enum {
     	 * dst.x = floor(src.x), where dst must be an address register */
     	RC_OPCODE_ARL,
     
    +	/** vec4 instruction: dst.c = ceil(src0.c) */
    +	RC_OPCODE_CEIL,
    +
     	/** vec4 instruction: dst.c = src0.c < 0.0 ? src1.c : src2.c */
     	RC_OPCODE_CMP,
     
    diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    index fced31d6cb9..05b874ba7cf 100644
    --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
    @@ -175,6 +175,26 @@ static void transform_ABS(struct radeon_compiler* c,
     	rc_remove_instruction(inst);
     }
     
    +static void transform_CEIL(struct radeon_compiler* c,
    +	struct rc_instruction* inst)
    +{
    +	/* Assuming:
    +	 *     ceil(x) = -floor(-x)
    +	 *
    +	 * After inlining floor:
    +	 *     ceil(x) = -(-x-frac(-x))
    +	 *
    +	 * After simplification:
    +	 *     ceil(x) = x+frac(-x)
    +	 */
    +
    +	int tempreg = rc_find_free_temporary(c);
    +	emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstreg(RC_FILE_TEMPORARY, tempreg), negate(inst->U.I.SrcReg[0]));
    +	emit2(c, inst->Prev, RC_OPCODE_ADD, inst->U.I.SaturateMode, inst->U.I.DstReg,
    +		inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, tempreg));
    +	rc_remove_instruction(inst);
    +}
    +
     static void transform_DP3(struct radeon_compiler* c,
     	struct rc_instruction* inst)
     {
    @@ -458,7 +478,7 @@ static void transform_XPD(struct radeon_compiler* c,
      * no userData necessary.
      *
      * Eliminates the following ALU instructions:
    - *  ABS, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD
    + *  ABS, CEIL, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD
      * using:
      *  MOV, ADD, MUL, MAD, FRC, DP3, LG2, EX2, CMP
      *
    @@ -474,6 +494,7 @@ int radeonTransformALU(
     {
     	switch(inst->U.I.Opcode) {
     	case RC_OPCODE_ABS: transform_ABS(c, inst); return 1;
    +	case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
     	case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
     	case RC_OPCODE_DST: transform_DST(c, inst); return 1;
     	case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
    @@ -546,6 +567,7 @@ int r300_transform_vertex_alu(
     {
     	switch(inst->U.I.Opcode) {
     	case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
    +	case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
     	case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1;
     	case RC_OPCODE_DP3: transform_DP3(c, inst); return 1;
     	case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
    -- 
    cgit v1.2.3
    
    
    From 986eb4b99fd9304abc949407e48dade5e122712e Mon Sep 17 00:00:00 2001
    From: Alex Deucher 
    Date: Thu, 22 Apr 2010 02:33:10 -0400
    Subject: r300: fix vertex unit setup
    
    RV3xx is 2, RV560,RV570 is 8
    
    Noticed by Tormod Volden.
    ---
     src/mesa/drivers/dri/r300/r300_state.c | 15 ++++++++-------
     1 file changed, 8 insertions(+), 7 deletions(-)
    
    (limited to 'src/mesa/drivers/dri/r300')
    
    diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
    index 5979dedac4f..188169ce87a 100644
    --- a/src/mesa/drivers/dri/r300/r300_state.c
    +++ b/src/mesa/drivers/dri/r300/r300_state.c
    @@ -1658,20 +1658,21 @@ void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
     				    (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
     				    (5 << R300_VF_MAX_VTX_NUM_SHIFT));
     
    -    if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515)
    -	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (2 << R300_PVS_NUM_FPUS_SHIFT);
    -    else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) ||
    -	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) ||
    -	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570))
    +    if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) ||
    +	(rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R350))
    +	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (4 << R300_PVS_NUM_FPUS_SHIFT);
    +    else if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530)
     	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (5 << R300_PVS_NUM_FPUS_SHIFT);
         else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) ||
     	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420))
     	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (6 << R300_PVS_NUM_FPUS_SHIFT);
         else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) ||
    -	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580))
    +	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580) ||
    +	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) ||
    +	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570))
     	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (8 << R300_PVS_NUM_FPUS_SHIFT);
         else
    -	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (4 << R300_PVS_NUM_FPUS_SHIFT);
    +	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (2 << R300_PVS_NUM_FPUS_SHIFT);
     
     }
     
    -- 
    cgit v1.2.3