aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/r600/r600_emit.c
diff options
context:
space:
mode:
authorRichard Li <[email protected]>2009-05-08 19:23:45 -0400
committerAlex Deucher <[email protected]>2009-05-08 19:23:45 -0400
commite2dcebd2e6b2af6269a5ece6d6ced73ec8bb4a47 (patch)
treed8aa42c0ccdf36c283f548dec293d26ee4af601a /src/mesa/drivers/dri/r600/r600_emit.c
parent604dd37f66d9c0e83cb3a9012ff1fc35f38b3e37 (diff)
R6xx/R7xx: WIP r6xx-rewrite code
Diffstat (limited to 'src/mesa/drivers/dri/r600/r600_emit.c')
-rw-r--r--src/mesa/drivers/dri/r600/r600_emit.c224
1 files changed, 215 insertions, 9 deletions
diff --git a/src/mesa/drivers/dri/r600/r600_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c
index 9d43873c4d8..fc8f987cabd 100644
--- a/src/mesa/drivers/dri/r600/r600_emit.c
+++ b/src/mesa/drivers/dri/r600/r600_emit.c
@@ -1,9 +1,8 @@
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+/**************************************************************************
+
+Copyright 2008, 2009 Advanced Micro Devices Inc. (AMD)
-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.
+Copyright (C) Advanced Micro Devices Inc. (AMD) 2009. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -27,10 +26,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/**
- * \file
- *
- * \author Keith Whitwell <[email protected]>
+/*
+ * Authors:
*/
#include "main/glheader.h"
@@ -48,6 +47,105 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r600_context.h"
#include "r600_emit.h"
+#if defined(USE_X86_ASM)
+#define COPY_DWORDS( dst, src, nr ) \
+do { \
+ int __tmp; \
+ __asm__ __volatile__( "rep ; movsl" \
+ : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
+ : "0" (nr), \
+ "D" ((long)dst), \
+ "S" ((long)src) ); \
+} while (0)
+#else
+#define COPY_DWORDS( dst, src, nr ) \
+do { \
+ int j; \
+ for ( j = 0 ; j < nr ; j++ ) \
+ dst[j] = ((int *)src)[j]; \
+ dst += nr; \
+} while (0)
+#endif
+
+static void r600EmitVec4(uint32_t *out, GLvoid * data, int stride, int count)
+{
+ int i;
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
+
+ if (stride == 4)
+ COPY_DWORDS(out, data, count);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out++;
+ data += stride;
+ }
+}
+
+static void r600EmitVec8(uint32_t *out, GLvoid * data, int stride, int count)
+{
+ int i;
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
+
+ if (stride == 8)
+ COPY_DWORDS(out, data, count * 2);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out[1] = *(int *)(data + 4);
+ out += 2;
+ data += stride;
+ }
+}
+
+static void r600EmitVec12(uint32_t *out, GLvoid * data, int stride, int count)
+{
+ int i;
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
+
+ if (stride == 12) {
+ COPY_DWORDS(out, data, count * 3);
+ }
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out[1] = *(int *)(data + 4);
+ out[2] = *(int *)(data + 8);
+ out += 3;
+ data += stride;
+ }
+}
+
+static void r600EmitVec16(uint32_t *out, GLvoid * data, int stride, int count)
+{
+ int i;
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
+
+ if (stride == 16)
+ COPY_DWORDS(out, data, count * 4);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out[1] = *(int *)(data + 4);
+ out[2] = *(int *)(data + 8);
+ out[3] = *(int *)(data + 12);
+ out += 4;
+ data += stride;
+ }
+}
+
/* Emit vertex data to GART memory
* Route inputs to the vertex processor
* This function should never return R600_FALLBACK_TCL when using software tcl.
@@ -73,3 +171,111 @@ void r600EmitCacheFlush(r600ContextPtr rmesa)
COMMIT_BATCH();
*/
}
+
+GLboolean r600EmitShader(GLcontext * ctx,
+ void ** shaderbo,
+ GLvoid * data,
+ int sizeinDWORD)
+{
+ radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
+
+ struct radeon_bo * pbo;
+ uint32_t *out;
+
+shader_again_alloc:
+ pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
+ 0,
+ sizeinDWORD * 4,
+ 256,
+ RADEON_GEM_DOMAIN_GTT,
+ 0);
+
+ if (!pbo)
+ {
+ rcommonFlushCmdBuf(radeonctx, __FUNCTION__);
+ goto shader_again_alloc;
+ }
+
+ radeon_validate_bo(radeonctx, pbo, RADEON_GEM_DOMAIN_GTT, 0);
+
+ if (radeon_revalidate_bos(radeonctx->glCtx) == GL_FALSE)
+ {
+ fprintf(stderr,"failure to revalidate BOs - badness\n");
+ }
+
+ radeon_bo_map(pbo, 1);
+
+ radeon_bo_ref(pbo);
+
+ out = (uint32_t*)(pbo->ptr);
+
+ memcpy(out, data, sizeinDWORD * 4);
+
+ *shaderbo = (void*)pbo;
+
+ return GL_TRUE;
+}
+
+GLboolean r600DeleteShader(GLcontext * ctx,
+ void * shaderbo)
+{
+ struct radeon_bo * pbo = (struct radeon_bo *)shaderbo;
+
+ radeon_bo_unmap(pbo);
+ radeon_bo_unref(pbo); /* when bo->cref <= 0, bo will be bo_free */
+
+ return GL_TRUE;
+}
+
+GLboolean r600EmitVec(GLcontext * ctx,
+ struct radeon_aos *aos,
+ GLvoid * data,
+ int size,
+ int stride,
+ int count)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ uint32_t *out;
+
+ if (stride == 0)
+ {
+ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
+ aos->stride = 0;
+ }
+ else
+ {
+ radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
+ aos->stride = size;
+ }
+
+ aos->components = size;
+ aos->count = count;
+
+ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
+ switch (size) {
+ case 1: r600EmitVec4(out, data, stride, count); break;
+ case 2: r600EmitVec8(out, data, stride, count); break;
+ case 3: r600EmitVec12(out, data, stride, count); break;
+ case 4: r600EmitVec16(out, data, stride, count); break;
+ default:
+ assert(0);
+ break;
+ }
+
+ return GL_TRUE;
+}
+
+void r600ReleaseVec(GLcontext * ctx)
+{
+ radeonReleaseArrays(ctx, ~0);
+}
+
+void r600FreeDmaRegion(context_t *context,
+ void * shaderbo)
+{
+ struct radeon_bo *pbo = (struct radeon_bo *)shaderbo;
+ if(pbo)
+ {
+ radeon_bo_unref(pbo);
+ }
+}