mesa: Branch 'master' - 7 commits
Ben Skeggs
darktama at kemper.freedesktop.org
Wed Dec 27 12:54:38 UTC 2006
src/mesa/drivers/dri/nouveau/Makefile | 1
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c | 272 +++++++++++++++++++++++
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h | 27 ++
src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 77 ++++++
src/mesa/drivers/dri/nouveau/nouveau_buffers.h | 7
src/mesa/drivers/dri/nouveau/nouveau_context.c | 7
src/mesa/drivers/dri/nouveau/nouveau_context.h | 4
src/mesa/drivers/dri/nouveau/nouveau_object.c | 10
src/mesa/drivers/dri/nouveau/nouveau_object.h | 2
src/mesa/drivers/dri/nouveau/nouveau_shader.h | 4
src/mesa/drivers/dri/nouveau/nouveau_sync.c | 5
src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 41 +--
12 files changed, 429 insertions(+), 28 deletions(-)
New commits:
diff-tree 8c180c72d5fed5f26f258759f9649fc647a764ff (from 9a20ae70ecda2e78ea6b52c3fd829d283434c1ad)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 23:52:40 2006 +1100
nouveau: Use bufferobj interface for fragment program uploads
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
index 6e934f2..08cb781 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -2,7 +2,7 @@
#define __SHADER_COMMON_H__
#include "mtypes.h"
-#include "nouveau_buffers.h"
+#include "bufferobj.h"
typedef struct _nvsFunc nvsFunc;
@@ -41,7 +41,7 @@ typedef struct _nouveauShader {
unsigned int program_alloc_size;
unsigned int program_start_id;
unsigned int program_current;
- nouveau_mem *program_buffer;
+ struct gl_buffer_object *program_buffer;
unsigned int inputs_read;
unsigned int outputs_written;
int inst_count;
diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
index b11bc18..cd7c955 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
@@ -10,7 +10,7 @@
#include "nouveau_shader.h"
#include "nouveau_object.h"
#include "nouveau_msg.h"
-#include "nouveau_buffers.h"
+#include "nouveau_bufferobj.h"
#include "nv30_shader.h"
unsigned int NVFP_TX_AOP_COUNT = 64;
@@ -24,29 +24,28 @@ static void
NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t offset;
- if (!nvs->program_buffer) {
- nouveau_mem *fpbuf;
-
- fpbuf = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED,
- nvs->program_size * sizeof(uint32_t), 0);
- if (!fpbuf) {
- fprintf(stderr, "fragprog vram alloc fail!\n");
- return;
- }
- nvs->program_buffer = fpbuf;
- }
-
- /*XXX: should do a DMA.. and not copy over a possibly in-use program.. */
- /* not using state cache here, updated programs at the same address
- * seem to not take effect unless ACTIVE_PROGRAM is called again. hw
- * caches the program somewhere? so, maybe not so bad to just clobber the
- * old program in vram..
+ if (!nvs->program_buffer)
+ nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0,
+ GL_ARRAY_BUFFER_ARB);
+
+ /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */
+ ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB,
+ nvs->program_size * sizeof(uint32_t),
+ (const GLvoid *)nvs->program,
+ GL_DYNAMIC_DRAW_ARB,
+ nvs->program_buffer);
+
+ offset = nouveau_bufferobj_gpu_ref(ctx, GL_READ_ONLY_ARB,
+ nvs->program_buffer);
+
+ /* Not using state cache here, updated programs at the same address don't
+ * seem to take effect unless the ACTIVE_PROGRAM method is called again.
+ * HW caches the program somewhere?
*/
- memcpy(nvs->program_buffer->map, nvs->program,
- nvs->program_size * sizeof(uint32_t));
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
- OUT_RING(nouveau_mem_gpu_offset_get(ctx, nvs->program_buffer) | 1);
+ OUT_RING (offset | 1);
}
static void
diff-tree 9a20ae70ecda2e78ea6b52c3fd829d283434c1ad (from 1780fd4eeeef2358e929c23cfae2c348cb4a709e)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 23:30:34 2006 +1100
nouveau: Initial buffer object support
diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile
index 962978d..d31b42a 100644
--- a/src/mesa/drivers/dri/nouveau/Makefile
+++ b/src/mesa/drivers/dri/nouveau/Makefile
@@ -8,6 +8,7 @@ LIBNAME = nouveau_dri.so
MINIGLX_SOURCES =
DRIVER_SOURCES = \
+ nouveau_bufferobj.c \
nouveau_buffers.c \
nouveau_card.c \
nouveau_context.c \
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
new file mode 100644
index 0000000..d36196a
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
@@ -0,0 +1,272 @@
+#include "bufferobj.h"
+#include "enums.h"
+
+#include "nouveau_bufferobj.h"
+#include "nouveau_buffers.h"
+#include "nouveau_context.h"
+#include "nouveau_drm.h"
+#include "nouveau_object.h"
+#include "nouveau_msg.h"
+
+#define DEBUG(fmt,args...) do { \
+ if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \
+ fprintf(stderr, "%s: "fmt, __func__, ##args); \
+ } \
+} while(0)
+
+/* Wrapper for nouveau_mem_gpu_offset_get() that marks the bufferobj dirty
+ * if the GPU modifies the data.
+ */
+uint32_t
+nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access,
+ struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, access=%s\n", obj, _mesa_lookup_enum_by_nr(access));
+
+ if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB)
+ nbo->gpu_dirty = GL_TRUE;
+
+ return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem);
+}
+
+static void
+nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
+{
+}
+
+static struct gl_buffer_object *
+nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target)
+{
+ nouveau_buffer_object *nbo;
+
+ nbo = CALLOC_STRUCT(nouveau_buffer_object_t);
+ DEBUG("name=0x%08x, target=%s, obj=%p\n",
+ buffer, _mesa_lookup_enum_by_nr(target), nbo);
+ _mesa_initialize_buffer_object(&nbo->mesa, buffer, target);
+ return &nbo->mesa;
+}
+
+static void
+nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p\n", obj);
+
+ if (nbo->gpu_mem) {
+ nouveau_mem_free(ctx, nbo->gpu_mem);
+ }
+ _mesa_delete_buffer_object(ctx, obj);
+}
+
+static void
+nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid *data, GLenum usage,
+ struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, target=%s, usage=%s, size=%d, data=%p\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(usage),
+ (unsigned int)size,
+ data);
+
+ if (nbo->gpu_mem && nbo->gpu_mem->size != size)
+ nouveau_mem_free(ctx, nbo->gpu_mem);
+
+ /* Always have the GPU access the data from VRAM if possible. For
+ * some "usage" values it may be better from AGP be default?
+ *
+ * TODO: At some point we should drop the NOUVEAU_MEM_MAPPED flag.
+ * TODO: Use the NOUVEAU_MEM_AGP_ACCEPTABLE flag.
+ * TODO: What about PCI-E and shared system memory?
+ */
+ if (!nbo->gpu_mem)
+ nbo->gpu_mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_FB |
+ NOUVEAU_MEM_MAPPED,
+ size,
+ 0);
+
+ if (!nbo->gpu_mem) {
+ MESSAGE("AIII bufferobj malloc failed\n");
+ return;
+ }
+
+ obj->Usage = usage;
+ obj->Size = size;
+ if (!data)
+ return;
+
+ ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj);
+ _mesa_memcpy(nbo->cpu_mem->map, data, size);
+ ctx->Driver.UnmapBuffer(ctx, target, obj);
+}
+
+/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */
+static void
+nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ (unsigned int)offset,
+ (unsigned int)size,
+ data);
+
+ ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj);
+ _mesa_memcpy((GLubyte *)obj->Pointer + offset, data, size);
+ ctx->Driver.UnmapBuffer(ctx, target, obj);
+}
+
+/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */
+static void
+nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ (unsigned int)offset,
+ (unsigned int)size,
+ data);
+
+ ctx->Driver.MapBuffer(ctx, target, GL_READ_ONLY_ARB, obj);
+ _mesa_memcpy(data, (GLubyte *)obj->Pointer + offset, size);
+ ctx->Driver.UnmapBuffer(ctx, target, obj);
+}
+
+static void *
+nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access,
+ struct gl_buffer_object *obj)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, target=%s, access=%s\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(access));
+
+ if (obj->Pointer) {
+ DEBUG("already mapped, return NULL\n");
+ return NULL;
+ }
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ /* If GPU is accessing the data from VRAM, copy to faster AGP memory
+ * before CPU access to the buffer.
+ */
+ if (nbo->gpu_mem->type & NOUVEAU_MEM_FB) {
+ DEBUG("Data in VRAM, copying to AGP for CPU access\n");
+
+ /* This can happen if BufferData grows the GPU-access buffer */
+ if (nbo->cpu_mem && nbo->cpu_mem->size != nbo->gpu_mem->size) {
+ nouveau_mem_free(ctx, nbo->cpu_mem);
+ nbo->cpu_mem = NULL;
+ }
+
+ if (!nbo->cpu_mem) {
+ nbo->cpu_mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_AGP |
+ NOUVEAU_MEM_MAPPED,
+ nbo->gpu_mem->size,
+ 0);
+
+ /* Mark GPU data as modified, so it gets copied to
+ * the new buffer */
+ nbo->gpu_dirty = GL_TRUE;
+ }
+
+ if (nbo->cpu_mem && nbo->gpu_dirty) {
+ nouveau_memformat_flat_emit(ctx, nbo->cpu_mem,
+ nbo->gpu_mem,
+ 0, 0,
+ nbo->gpu_mem->size);
+
+ nouveau_notifier_wait_nop(ctx,
+ nmesa->syncNotifier,
+ NvSubMemFormat);
+ nbo->gpu_dirty = GL_FALSE;
+ }
+
+ /* buffer isn't guaranteed to be up-to-date on the card now */
+ nbo->cpu_dirty = GL_TRUE;
+ }
+#endif
+
+ /* If the copy to AGP failed for some reason, just return a pointer
+ * directly to vram..
+ */
+ if (!nbo->cpu_mem) {
+ DEBUG("Returning direct pointer to VRAM\n");
+ nbo->cpu_mem = nbo->gpu_mem;
+ nbo->cpu_dirty = GL_FALSE;
+ }
+
+ obj->Pointer = nbo->cpu_mem->map;
+ return obj->Pointer;
+}
+
+static GLboolean
+nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, target=%s\n", obj, _mesa_lookup_enum_by_nr(target));
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ if (nbo->cpu_dirty && nbo->cpu_mem != nbo->gpu_mem) {
+ DEBUG("Copying potentially modified data back to GPU\n");
+
+ /* blit from GPU buffer -> CPU buffer */
+ nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, nbo->cpu_mem,
+ 0, 0, nbo->cpu_mem->size);
+
+ /* buffer is now up-to-date on the hardware (or rather, will
+ * be by the time any other commands in this channel reference
+ * the data.)
+ */
+ nbo->cpu_dirty = GL_FALSE;
+
+ /* we can avoid this wait in some cases.. */
+ nouveau_notifier_wait_nop(ctx,
+ nmesa->syncNotifier,
+ NvSubMemFormat);
+
+ /* If it's likely CPU access to the buffer will occur often,
+ * keep the cpu_mem around to avoid repeated allocs.
+ */
+ if (obj->Usage != GL_DYNAMIC_DRAW_ARB) {
+
+ nouveau_mem_free(ctx, nbo->cpu_mem);
+ nbo->cpu_mem = NULL;
+ }
+ }
+#endif
+
+ obj->Pointer = NULL;
+ return GL_TRUE;
+}
+
+void
+nouveauInitBufferObjects(GLcontext *ctx)
+{
+ ctx->Driver.BindBuffer = nouveauBindBuffer;
+ ctx->Driver.NewBufferObject = nouveauNewBufferObject;
+ ctx->Driver.DeleteBuffer = nouveauDeleteBuffer;
+ ctx->Driver.BufferData = nouveauBufferData;
+ ctx->Driver.BufferSubData = nouveauBufferSubData;
+ ctx->Driver.GetBufferSubData = nouveauGetBufferSubData;
+ ctx->Driver.MapBuffer = nouveauMapBuffer;
+ ctx->Driver.UnmapBuffer = nouveauUnmapBuffer;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
new file mode 100644
index 0000000..fccc349
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
@@ -0,0 +1,27 @@
+#ifndef __NOUVEAU_BUFFEROBJ_H__
+#define __NOUVEAU_BUFFEROBJ_H__
+
+#include "mtypes.h"
+#include "nouveau_buffers.h"
+
+typedef struct nouveau_buffer_object_t {
+ /* Base class, must be first */
+ struct gl_buffer_object mesa;
+
+ /* Memory used for GPU access to the buffer*/
+ nouveau_mem * gpu_mem;
+ /* Buffer has been dirtied by the GPU */
+ GLboolean gpu_dirty;
+
+ /* Memory used for CPU access to the buffer */
+ nouveau_mem * cpu_mem;
+ /* Buffer has possibly been dirtied by the CPU */
+ GLboolean cpu_dirty;
+} nouveau_buffer_object;
+
+extern uint32_t nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access,
+ struct gl_buffer_object *obj);
+
+extern void nouveauInitBufferObjects(GLcontext *ctx);
+
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index bb67f72..79da46f 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -65,6 +65,7 @@ static const struct dri_debug_control de
{
{ "shaders" , DEBUG_SHADERS },
{ "mem" , DEBUG_MEM },
+ { "bufferobj" , DEBUG_BUFFEROBJ },
{ NULL , 0 }
};
@@ -224,6 +225,7 @@ GLboolean nouveauCreateContext( const __
break;
}
+ nouveauInitBufferObjects(ctx);
if (!nouveauSyncInitFuncs(ctx))
return GL_FALSE;
nmesa->hw_func.InitCard(nmesa);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h
index b095207..134e2a4 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -218,6 +218,7 @@ extern int NOUVEAU_DEBUG;
#define DEBUG_SHADERS 0x00000001
#define DEBUG_MEM 0x00000002
+#define DEBUG_BUFFEROBJ 0x00000004
#endif /* __NOUVEAU_CONTEXT_H__ */
diff-tree 1780fd4eeeef2358e929c23cfae2c348cb4a709e (from 885a7cc38d80366396f463a54ef4af00c9fd07ff)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 15:54:30 2006 +1100
nouveau: We'll need syncNotifier for NV_MEMORY_TO_MEMORY_FORMAT too.
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c
index e27101d..0bf20e7 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c
@@ -125,6 +125,11 @@ GLboolean nouveauSyncInitFuncs(GLcontext
*/
BEGIN_RING_CACHE(NvSub3D, 0x180, 1);
OUT_RING_CACHE (NvSyncNotify);
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ BEGIN_RING_SIZE(NvSubMemFormat,
+ NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
+ OUT_RING (NvSyncNotify);
+#endif
return GL_TRUE;
}
diff-tree 885a7cc38d80366396f463a54ef4af00c9fd07ff (from 2dd37534506e85351fb114c79fd6c994a9c355c0)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 15:50:59 2006 +1100
nouveau: add nouveau_mem_alloc/free debugging
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
index e628dd5..b54f68f 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
@@ -71,6 +71,11 @@ nouveau_mem_free(GLcontext *ctx, nouveau
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
drm_nouveau_mem_free_t memf;
+ if (NOUVEAU_DEBUG & DEBUG_MEM) {
+ fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n",
+ __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size);
+ }
+
if (mem->map)
drmUnmap(mem->map, mem->size);
memf.flags = mem->type;
@@ -87,6 +92,11 @@ nouveau_mem_alloc(GLcontext *ctx, int ty
nouveau_mem *mem;
int ret;
+ if (NOUVEAU_DEBUG & DEBUG_MEM) {
+ fprintf(stderr, "%s: requested: type=0x%x, size=0x%x, align=0x%x\n",
+ __func__, type, (GLuint)size, align);
+ }
+
mem = CALLOC(sizeof(nouveau_mem));
if (!mem)
return NULL;
@@ -104,6 +114,11 @@ nouveau_mem_alloc(GLcontext *ctx, int ty
mem->offset = mema.region_offset;
mem->type = mema.flags;
+ if (NOUVEAU_DEBUG & DEBUG_MEM) {
+ fprintf(stderr, "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n",
+ __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size);
+ }
+
if (type & NOUVEAU_MEM_MAPPED)
ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map);
if (ret) {
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index 3718900..bb67f72 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -63,8 +63,9 @@ int NOUVEAU_DEBUG = 0;
static const struct dri_debug_control debug_control[] =
{
- { "shaders", DEBUG_SHADERS },
- { NULL, 0 }
+ { "shaders" , DEBUG_SHADERS },
+ { "mem" , DEBUG_MEM },
+ { NULL , 0 }
};
#define need_GL_ARB_vertex_program
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h
index 0efbcce..b095207 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -216,7 +216,8 @@ extern void nouveauCopySubBuffer(__DRIdr
/* Debugging utils: */
extern int NOUVEAU_DEBUG;
-#define DEBUG_SHADERS 0x00000001
+#define DEBUG_SHADERS 0x00000001
+#define DEBUG_MEM 0x00000002
#endif /* __NOUVEAU_CONTEXT_H__ */
diff-tree 2dd37534506e85351fb114c79fd6c994a9c355c0 (from 7b59a424b519c37b7c94e4ea8c420794c6a0eb4c)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 15:39:52 2006 +1100
nouveau: record *actual* type of memory that was alloc'd, not the requested types.
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
index 6d73e9f..e628dd5 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
@@ -91,7 +91,7 @@ nouveau_mem_alloc(GLcontext *ctx, int ty
if (!mem)
return NULL;
- mema.flags = mem->type = type;
+ mema.flags = type;
mema.size = mem->size = size;
mema.alignment = align;
mem->map = NULL;
@@ -102,6 +102,7 @@ nouveau_mem_alloc(GLcontext *ctx, int ty
return NULL;
}
mem->offset = mema.region_offset;
+ mem->type = mema.flags;
if (type & NOUVEAU_MEM_MAPPED)
ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
index a8d85b2..d864551 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
@@ -19,8 +19,10 @@ extern void nouveau_mem_free(GLcontext *
extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem);
extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx,
- nouveau_mem *dst, nouveau_mem *src,
- GLuint dst_offset, GLuint src_offset,
+ nouveau_mem *dst,
+ nouveau_mem *src,
+ GLuint dst_offset,
+ GLuint src_offset,
GLuint size);
typedef struct nouveau_renderbuffer_t {
diff-tree 7b59a424b519c37b7c94e4ea8c420794c6a0eb4c (from 297a35eb69382193a4cc9ba4b51619984a8969db)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 15:38:09 2006 +1100
nouveau: Typo
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
index 92329e5..6d73e9f 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
@@ -33,7 +33,7 @@ nouveau_memformat_flat_emit(GLcontext *c
}
src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
- dst_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
+ dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
src_offset += nouveau_mem_gpu_offset_get(ctx, src);
dst_offset += nouveau_mem_gpu_offset_get(ctx, dst);
diff-tree 297a35eb69382193a4cc9ba4b51619984a8969db (from 2dccca57e4325e77d7b2f0a08835eeccc11892cb)
Author: Ben Skeggs <darktama at iinet.net.au>
Date: Wed Dec 27 00:02:38 2006 +1100
nouveau: Add simple wrapper for NV_MEMORY_TO_MEMORY_FORMAT.
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
index f6a03ec..92329e5 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
@@ -5,6 +5,65 @@
#include "nouveau_context.h"
#include "nouveau_buffers.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_msg.h"
+
+#define MAX_MEMFMT_LENGTH 32768
+
+/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */
+GLboolean
+nouveau_memformat_flat_emit(GLcontext *ctx,
+ nouveau_mem *dst, nouveau_mem *src,
+ GLuint dst_offset, GLuint src_offset,
+ GLuint size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t src_handle, dst_handle;
+ GLuint count;
+
+ if (src_offset + size > src->size) {
+ MESSAGE("src out of nouveau_mem bounds\n");
+ return GL_FALSE;
+ }
+ if (dst_offset + size > dst->size) {
+ MESSAGE("dst out of nouveau_mem bounds\n");
+ return GL_FALSE;
+ }
+
+ src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
+ dst_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
+ src_offset += nouveau_mem_gpu_offset_get(ctx, src);
+ dst_offset += nouveau_mem_gpu_offset_get(ctx, dst);
+
+ BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2);
+ OUT_RING (src_handle);
+ OUT_RING (dst_handle);
+
+ count = (size / MAX_MEMFMT_LENGTH) + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0);
+
+ while (count--) {
+ GLuint length = (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size;
+
+ BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+ OUT_RING (src_offset);
+ OUT_RING (dst_offset);
+ OUT_RING (0); /* pitch in */
+ OUT_RING (0); /* pitch out */
+ OUT_RING (length); /* line length */
+ OUT_RING (1); /* number of lines */
+ OUT_RING ((1 << 8) /* dst_inc */ | (1 << 0) /* src_inc */);
+ OUT_RING (0); /* buffer notify? */
+ FIRE_RING();
+
+ src_offset += length;
+ dst_offset += length;
+ size -= length;
+ }
+
+ return GL_TRUE;
+}
void
nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem)
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
index bb297ad..a8d85b2 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
@@ -18,6 +18,11 @@ extern nouveau_mem *nouveau_mem_alloc(GL
extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem);
extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem);
+extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx,
+ nouveau_mem *dst, nouveau_mem *src,
+ GLuint dst_offset, GLuint src_offset,
+ GLuint size);
+
typedef struct nouveau_renderbuffer_t {
struct gl_renderbuffer mesa; /* must be first! */
__DRIdrawablePrivate *dPriv;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c
index cf7284d..1558f29 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_object.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c
@@ -52,10 +52,13 @@ void nouveauObjectInit(nouveauContextPtr
return;
#endif
-/* We need to know vram size.. */
+/* We need to know vram size.. and AGP size (and even if the card is AGP..) */
nouveauCreateDmaObject( nmesa, NvDmaFB,
0, (256*1024*1024),
0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/);
+ nouveauCreateDmaObject( nmesa, NvDmaAGP,
+ nmesa->agp_phys, (128*1024*1024),
+ 3 /* AGP */, 0 /* RW */);
nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d,
0, 0, 0, 0);
@@ -63,6 +66,9 @@ void nouveauObjectInit(nouveauContextPtr
0, 0, 0, 0);
nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT,
NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvMemFormat,
+ NV_MEMORY_TO_MEMORY_FORMAT,
+ 0, 0, 0, 0);
#ifdef ALLOW_MULTI_SUBCHANNEL
nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
@@ -75,6 +81,8 @@ void nouveauObjectInit(nouveauContextPtr
OUT_RING(NvCtxSurf2D);
BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_OPERATION, 1);
OUT_RING(3); /* SRCCOPY */
+
+ nouveauObjectOnSubchannel(nmesa, NvSubMemFormat, NvMemFormat);
#endif
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h
index 87f2dc9..d5fcc6d 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_object.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h
@@ -11,6 +11,7 @@ enum DMAObjects {
Nv3D = 0x80000019,
NvCtxSurf2D = 0x80000020,
NvImageBlit = 0x80000021,
+ NvMemFormat = 0x80000022,
NvDmaFB = 0xD0FB0001,
NvDmaAGP = 0xD0AA0001,
NvSyncNotify = 0xD0000001
@@ -19,6 +20,7 @@ enum DMAObjects {
enum DMASubchannel {
NvSubCtxSurf2D = 0,
NvSubImageBlit = 1,
+ NvSubMemFormat = 2,
NvSub3D = 7,
};
More information about the mesa-commit
mailing list