nouveau: Split nouveau_buffers into nouveau_mem and nouveau_fbo
authorBen Skeggs <skeggsb@gmail.com>
Mon, 13 Aug 2007 10:02:04 +0000 (20:02 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Wed, 15 Aug 2007 04:31:25 +0000 (14:31 +1000)
13 files changed:
src/mesa/drivers/dri/nouveau/Makefile
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
src/mesa/drivers/dri/nouveau/nouveau_buffers.c [deleted file]
src/mesa/drivers/dri/nouveau/nouveau_buffers.h [deleted file]
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_fbo.c [new file with mode: 0644]
src/mesa/drivers/dri/nouveau/nouveau_fbo.h [new file with mode: 0644]
src/mesa/drivers/dri/nouveau/nouveau_mem.c [new file with mode: 0644]
src/mesa/drivers/dri/nouveau/nouveau_mem.h [new file with mode: 0644]
src/mesa/drivers/dri/nouveau/nouveau_span.h
src/mesa/drivers/dri/nouveau/nouveau_sync.c
src/mesa/drivers/dri/nouveau/nouveau_sync.h

index 20d2de5eefbbe73e6e08f7eb68e9e32556450044..6ea4594f1e6d3ee2214978377751b3ad3eb4a19b 100644 (file)
@@ -9,12 +9,13 @@ MINIGLX_SOURCES =
 
 DRIVER_SOURCES = \
        nouveau_bufferobj.c      \
-       nouveau_buffers.c        \
        nouveau_card.c           \
        nouveau_context.c        \
        nouveau_driver.c         \
+       nouveau_fbo.c            \
        nouveau_fifo.c           \
        nouveau_lock.c           \
+       nouveau_mem.c            \
        nouveau_object.c         \
        nouveau_screen.c         \
        nouveau_span.c           \
index fc14060c04922d2aa9bed5e2b44e18e381958b36..be6455a01ed29d8f39d6a50ced86e800146115f9 100644 (file)
@@ -2,11 +2,11 @@
 #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_mem.h"
 #include "nouveau_msg.h"
+#include "nouveau_object.h"
 
 #define NOUVEAU_MEM_FREE(mem) do {      \
        nouveau_mem_free(ctx, (mem));   \
index 3439a35e7c85c551b012e55b41a13379768bb4a3..cbc89a151da61b141138ffec5d65d8e672052710 100644 (file)
@@ -2,7 +2,7 @@
 #define __NOUVEAU_BUFFEROBJ_H__
 
 #include "mtypes.h"
-#include "nouveau_buffers.h"
+#include "nouveau_mem.h"
 
 #define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE)
 #define NOUVEAU_BO_GART_OK  (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE)
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
deleted file mode 100644 (file)
index 7cf739f..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-#include "utils.h"
-#include "framebuffer.h"
-#include "renderbuffer.h"
-#include "fbobject.h"
-
-#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 : NvDmaTT;
-       dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT;
-       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)
-{
-       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-       struct drm_nouveau_mem_free 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;
-       memf.offset = mem->offset;
-       drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf,
-                       sizeof(memf));
-       FREE(mem);
-}
-
-nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, uint32_t flags, GLuint size,
-                              GLuint align)
-{
-       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-       struct drm_nouveau_mem_alloc mema;
-       nouveau_mem *mem;
-       int ret;
-
-       if (NOUVEAU_DEBUG & DEBUG_MEM) {
-               fprintf(stderr,
-                       "%s: requested: flags=0x%x, size=0x%x, align=0x%x\n",
-                       __func__, flags, (GLuint) size, align);
-       }
-
-       mem = CALLOC(sizeof(nouveau_mem));
-       if (!mem)
-               return NULL;
-
-       mema.flags = flags;
-       mema.size = mem->size = size;
-       mema.alignment = align;
-       mem->map = NULL;
-       ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC,
-                                 &mema, sizeof(mema));
-       if (ret) {
-               FREE(mem);
-               return NULL;
-       }
-       mem->offset = mema.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 (flags & NOUVEAU_MEM_MAPPED)
-               ret = drmMap(nmesa->driFd, mema.map_handle, mem->size,
-                            &mem->map);
-       if (ret) {
-               mem->map = NULL;
-               nouveau_mem_free(ctx, mem);
-               mem = NULL;
-       }
-
-       return mem;
-}
-
-uint32_t nouveau_mem_gpu_offset_get(GLcontext * ctx, nouveau_mem * mem)
-{
-       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-
-       return mem->offset;
-}
-
-static GLboolean
-nouveau_renderbuffer_pixelformat(nouveau_renderbuffer * nrb,
-                                GLenum internalFormat)
-{
-       nrb->mesa.InternalFormat = internalFormat;
-
-       /*TODO: We probably want to extend this a bit, and maybe make
-        *      card-specific? 
-        */
-       switch (internalFormat) {
-       case GL_RGBA:
-       case GL_RGBA8:
-               nrb->mesa._BaseFormat = GL_RGBA;
-               nrb->mesa._ActualFormat = GL_RGBA8;
-               nrb->mesa.DataType = GL_UNSIGNED_BYTE;
-               nrb->mesa.RedBits = 8;
-               nrb->mesa.GreenBits = 8;
-               nrb->mesa.BlueBits = 8;
-               nrb->mesa.AlphaBits = 8;
-               nrb->cpp = 4;
-               break;
-       case GL_RGB:
-       case GL_RGB5:
-               nrb->mesa._BaseFormat = GL_RGB;
-               nrb->mesa._ActualFormat = GL_RGB5;
-               nrb->mesa.DataType = GL_UNSIGNED_BYTE;
-               nrb->mesa.RedBits = 5;
-               nrb->mesa.GreenBits = 6;
-               nrb->mesa.BlueBits = 5;
-               nrb->mesa.AlphaBits = 0;
-               nrb->cpp = 2;
-               break;
-       case GL_DEPTH_COMPONENT16:
-               nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
-               nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16;
-               nrb->mesa.DataType = GL_UNSIGNED_SHORT;
-               nrb->mesa.DepthBits = 16;
-               nrb->cpp = 2;
-               break;
-       case GL_DEPTH_COMPONENT24:
-               nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
-               nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-               nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
-               nrb->mesa.DepthBits = 24;
-               nrb->cpp = 4;
-               break;
-       case GL_STENCIL_INDEX8_EXT:
-               nrb->mesa._BaseFormat = GL_STENCIL_INDEX;
-               nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-               nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
-               nrb->mesa.StencilBits = 8;
-               nrb->cpp = 4;
-               break;
-       case GL_DEPTH24_STENCIL8_EXT:
-               nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT;
-               nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-               nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
-               nrb->mesa.DepthBits = 24;
-               nrb->mesa.StencilBits = 8;
-               nrb->cpp = 4;
-               break;
-       default:
-               return GL_FALSE;
-               break;
-       }
-
-       return GL_TRUE;
-}
-
-static GLboolean
-nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
-                            GLenum internalFormat,
-                            GLuint width, GLuint height)
-{
-       nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb;
-
-       if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) {
-               fprintf(stderr, "%s: unknown internalFormat\n", __func__);
-               return GL_FALSE;
-       }
-
-       /* If this buffer isn't statically alloc'd, we may need to ask the
-        * drm for more memory */
-       if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) {
-               GLuint pitch;
-
-               /* align pitches to 64 bytes */
-               pitch = ((width * nrb->cpp) + 63) & ~63;
-
-               if (nrb->mem)
-                       nouveau_mem_free(ctx, nrb->mem);
-               nrb->mem = nouveau_mem_alloc(ctx,
-                                            NOUVEAU_MEM_FB |
-                                            NOUVEAU_MEM_MAPPED,
-                                            pitch * height, 0);
-               if (!nrb->mem)
-                       return GL_FALSE;
-
-               /* update nouveau_renderbuffer info */
-               nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem);
-               nrb->pitch = pitch;
-       }
-
-       rb->Width = width;
-       rb->Height = height;
-       rb->InternalFormat = internalFormat;
-       return GL_TRUE;
-}
-
-static void nouveau_renderbuffer_delete(struct gl_renderbuffer *rb)
-{
-       GET_CURRENT_CONTEXT(ctx);
-       nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb;
-
-       if (nrb->mem)
-               nouveau_mem_free(ctx, nrb->mem);
-       FREE(nrb);
-}
-
-nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat,
-                                              GLvoid * map, GLuint offset,
-                                              GLuint pitch,
-                                              __DRIdrawablePrivate *
-                                              dPriv)
-{
-       nouveau_renderbuffer *nrb;
-
-       nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
-       if (nrb) {
-               _mesa_init_renderbuffer(&nrb->mesa, 0);
-
-               nouveau_renderbuffer_pixelformat(nrb, internalFormat);
-
-               nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
-               nrb->mesa.Delete = nouveau_renderbuffer_delete;
-
-               nrb->dPriv = dPriv;
-               nrb->offset = offset;
-               nrb->pitch = pitch;
-               nrb->map = map;
-       }
-
-       return nrb;
-}
-
-static void
-nouveau_cliprects_drawable_set(nouveauContextPtr nmesa,
-                              nouveau_renderbuffer * nrb)
-{
-       __DRIdrawablePrivate *dPriv = nrb->dPriv;
-
-       nmesa->numClipRects = dPriv->numClipRects;
-       nmesa->pClipRects = dPriv->pClipRects;
-       nmesa->drawX = dPriv->x;
-       nmesa->drawY = dPriv->y;
-       nmesa->drawW = dPriv->w;
-       nmesa->drawH = dPriv->h;
-}
-
-static void
-nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa,
-                                  nouveau_renderbuffer * nrb)
-{
-       nmesa->numClipRects = 1;
-       nmesa->pClipRects = &nmesa->osClipRect;
-       nmesa->osClipRect.x1 = 0;
-       nmesa->osClipRect.y1 = 0;
-       nmesa->osClipRect.x2 = nrb->mesa.Width;
-       nmesa->osClipRect.y2 = nrb->mesa.Height;
-       nmesa->drawX = 0;
-       nmesa->drawY = 0;
-       nmesa->drawW = nrb->mesa.Width;
-       nmesa->drawH = nrb->mesa.Height;
-}
-
-void nouveau_window_moved(GLcontext * ctx)
-{
-       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-       nouveau_renderbuffer *nrb;
-
-       nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0];
-       if (!nrb)
-               return;
-
-       if (!nrb->dPriv)
-               nouveau_cliprects_renderbuffer_set(nmesa, nrb);
-       else
-               nouveau_cliprects_drawable_set(nmesa, nrb);
-
-       /* Viewport depends on window size/position, nouveauCalcViewport
-        * will take care of calling the hw-specific WindowMoved
-        */
-       ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
-                            ctx->Viewport.Width, ctx->Viewport.Height);
-       /* Scissor depends on window position */
-       ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
-                           ctx->Scissor.Width, ctx->Scissor.Height);
-}
-
-GLboolean
-nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb)
-{
-       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-       nouveau_renderbuffer *color[MAX_DRAW_BUFFERS];
-       nouveau_renderbuffer *depth;
-
-       _mesa_update_framebuffer(ctx);
-       _mesa_update_draw_buffer_bounds(ctx);
-
-       color[0] = (nouveau_renderbuffer *) fb->_ColorDrawBuffers[0][0];
-       if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
-               depth = (nouveau_renderbuffer *) fb->_DepthBuffer->Wrapped;
-       else
-               depth = (nouveau_renderbuffer *) fb->_DepthBuffer;
-
-       if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth))
-               return GL_FALSE;
-       nouveau_window_moved(ctx);
-
-       return GL_TRUE;
-}
-
-static void nouveauDrawBuffer(GLcontext * ctx, GLenum buffer)
-{
-       nouveau_build_framebuffer(ctx, ctx->DrawBuffer);
-}
-
-static struct gl_framebuffer *nouveauNewFramebuffer(GLcontext * ctx,
-                                                   GLuint name)
-{
-       return _mesa_new_framebuffer(ctx, name);
-}
-
-static struct gl_renderbuffer *nouveauNewRenderbuffer(GLcontext * ctx,
-                                                     GLuint name)
-{
-       nouveau_renderbuffer *nrb;
-
-       nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
-       if (nrb) {
-               _mesa_init_renderbuffer(&nrb->mesa, name);
-
-               nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
-               nrb->mesa.Delete = nouveau_renderbuffer_delete;
-       }
-       return &nrb->mesa;
-}
-
-static void
-nouveauBindFramebuffer(GLcontext * ctx, GLenum target,
-                      struct gl_framebuffer *fb,
-                      struct gl_framebuffer *fbread)
-{
-       if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
-               nouveau_build_framebuffer(ctx, fb);
-       }
-}
-
-static void
-nouveauFramebufferRenderbuffer(GLcontext * ctx,
-                              struct gl_framebuffer *fb,
-                              GLenum attachment,
-                              struct gl_renderbuffer *rb)
-{
-       _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
-       nouveau_build_framebuffer(ctx, fb);
-}
-
-static void
-nouveauRenderTexture(GLcontext * ctx,
-                    struct gl_framebuffer *fb,
-                    struct gl_renderbuffer_attachment *att)
-{
-}
-
-static void
-nouveauFinishRenderTexture(GLcontext * ctx,
-                          struct gl_renderbuffer_attachment *att)
-{
-}
-
-void nouveauInitBufferFuncs(struct dd_function_table *func)
-{
-       func->DrawBuffer = nouveauDrawBuffer;
-
-       func->NewFramebuffer = nouveauNewFramebuffer;
-       func->NewRenderbuffer = nouveauNewRenderbuffer;
-       func->BindFramebuffer = nouveauBindFramebuffer;
-       func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer;
-       func->RenderTexture = nouveauRenderTexture;
-       func->FinishRenderTexture = nouveauFinishRenderTexture;
-}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
deleted file mode 100644 (file)
index f0987d2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __NOUVEAU_BUFFERS_H__
-#define __NOUVEAU_BUFFERS_H__
-
-#include <stdint.h>
-#include "mtypes.h"
-#include "utils.h"
-#include "renderbuffer.h"
-
-typedef struct nouveau_mem_t {
-       int type;
-       uint64_t offset;
-       uint64_t size;
-       void *map;
-} nouveau_mem;
-
-extern nouveau_mem *nouveau_mem_alloc(GLcontext *, uint32_t flags,
-                                     GLuint size, GLuint align);
-extern void nouveau_mem_free(GLcontext *, nouveau_mem *);
-extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *, nouveau_mem *);
-
-extern GLboolean nouveau_memformat_flat_emit(GLcontext *,
-                                            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;
-
-       nouveau_mem *mem;
-       void *map;
-
-       int cpp;
-       uint32_t offset;
-       uint32_t pitch;
-} nouveau_renderbuffer;
-
-extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat,
-                                                     GLvoid *map,
-                                                     GLuint offset,
-                                                     GLuint pitch,
-                                                     __DRIdrawablePrivate *);
-extern void nouveau_window_moved(GLcontext *);
-extern GLboolean nouveau_build_framebuffer(GLcontext *,
-                                          struct gl_framebuffer *);
-extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *);
-
-extern void nouveauInitBufferFuncs(struct dd_function_table *);
-
-#endif
index fdbde51a7289c0783c08d42fa8ac7258b9d3f07a..03f778a13c469c6a529f636f90fea44447f0737d 100644 (file)
@@ -36,10 +36,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "mtypes.h"
 #include "tnl/t_vertex.h"
 
+#include "nouveau_fbo.h"
 #include "nouveau_screen.h"
-#include "nouveau_state_cache.h"
-#include "nouveau_buffers.h"
 #include "nouveau_shader.h"
+#include "nouveau_state_cache.h"
 #include "nouveau_sync.h"
 
 #include "xmlconfig.h"
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
new file mode 100644 (file)
index 0000000..54c0c26
--- /dev/null
@@ -0,0 +1,304 @@
+#include "utils.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "fbobject.h"
+
+#include "nouveau_context.h"
+#include "nouveau_fbo.h"
+#include "nouveau_fifo.h"
+#include "nouveau_msg.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
+
+static GLboolean
+nouveau_renderbuffer_pixelformat(nouveau_renderbuffer * nrb,
+                                GLenum internalFormat)
+{
+       nrb->mesa.InternalFormat = internalFormat;
+
+       /*TODO: We probably want to extend this a bit, and maybe make
+        *      card-specific? 
+        */
+       switch (internalFormat) {
+       case GL_RGBA:
+       case GL_RGBA8:
+               nrb->mesa._BaseFormat = GL_RGBA;
+               nrb->mesa._ActualFormat = GL_RGBA8;
+               nrb->mesa.DataType = GL_UNSIGNED_BYTE;
+               nrb->mesa.RedBits = 8;
+               nrb->mesa.GreenBits = 8;
+               nrb->mesa.BlueBits = 8;
+               nrb->mesa.AlphaBits = 8;
+               nrb->cpp = 4;
+               break;
+       case GL_RGB:
+       case GL_RGB5:
+               nrb->mesa._BaseFormat = GL_RGB;
+               nrb->mesa._ActualFormat = GL_RGB5;
+               nrb->mesa.DataType = GL_UNSIGNED_BYTE;
+               nrb->mesa.RedBits = 5;
+               nrb->mesa.GreenBits = 6;
+               nrb->mesa.BlueBits = 5;
+               nrb->mesa.AlphaBits = 0;
+               nrb->cpp = 2;
+               break;
+       case GL_DEPTH_COMPONENT16:
+               nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
+               nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16;
+               nrb->mesa.DataType = GL_UNSIGNED_SHORT;
+               nrb->mesa.DepthBits = 16;
+               nrb->cpp = 2;
+               break;
+       case GL_DEPTH_COMPONENT24:
+               nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
+               nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+               nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
+               nrb->mesa.DepthBits = 24;
+               nrb->cpp = 4;
+               break;
+       case GL_STENCIL_INDEX8_EXT:
+               nrb->mesa._BaseFormat = GL_STENCIL_INDEX;
+               nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+               nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
+               nrb->mesa.StencilBits = 8;
+               nrb->cpp = 4;
+               break;
+       case GL_DEPTH24_STENCIL8_EXT:
+               nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT;
+               nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+               nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
+               nrb->mesa.DepthBits = 24;
+               nrb->mesa.StencilBits = 8;
+               nrb->cpp = 4;
+               break;
+       default:
+               return GL_FALSE;
+               break;
+       }
+
+       return GL_TRUE;
+}
+
+static GLboolean
+nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
+                            GLenum internalFormat,
+                            GLuint width, GLuint height)
+{
+       nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb;
+
+       if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) {
+               fprintf(stderr, "%s: unknown internalFormat\n", __func__);
+               return GL_FALSE;
+       }
+
+       /* If this buffer isn't statically alloc'd, we may need to ask the
+        * drm for more memory */
+       if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) {
+               GLuint pitch;
+
+               /* align pitches to 64 bytes */
+               pitch = ((width * nrb->cpp) + 63) & ~63;
+
+               if (nrb->mem)
+                       nouveau_mem_free(ctx, nrb->mem);
+               nrb->mem = nouveau_mem_alloc(ctx,
+                                            NOUVEAU_MEM_FB |
+                                            NOUVEAU_MEM_MAPPED,
+                                            pitch * height, 0);
+               if (!nrb->mem)
+                       return GL_FALSE;
+
+               /* update nouveau_renderbuffer info */
+               nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem);
+               nrb->pitch = pitch;
+       }
+
+       rb->Width = width;
+       rb->Height = height;
+       rb->InternalFormat = internalFormat;
+       return GL_TRUE;
+}
+
+static void nouveau_renderbuffer_delete(struct gl_renderbuffer *rb)
+{
+       GET_CURRENT_CONTEXT(ctx);
+       nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb;
+
+       if (nrb->mem)
+               nouveau_mem_free(ctx, nrb->mem);
+       FREE(nrb);
+}
+
+nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat,
+                                              GLvoid * map, GLuint offset,
+                                              GLuint pitch,
+                                              __DRIdrawablePrivate *
+                                              dPriv)
+{
+       nouveau_renderbuffer *nrb;
+
+       nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
+       if (nrb) {
+               _mesa_init_renderbuffer(&nrb->mesa, 0);
+
+               nouveau_renderbuffer_pixelformat(nrb, internalFormat);
+
+               nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
+               nrb->mesa.Delete = nouveau_renderbuffer_delete;
+
+               nrb->dPriv = dPriv;
+               nrb->offset = offset;
+               nrb->pitch = pitch;
+               nrb->map = map;
+       }
+
+       return nrb;
+}
+
+static void
+nouveau_cliprects_drawable_set(nouveauContextPtr nmesa,
+                              nouveau_renderbuffer * nrb)
+{
+       __DRIdrawablePrivate *dPriv = nrb->dPriv;
+
+       nmesa->numClipRects = dPriv->numClipRects;
+       nmesa->pClipRects = dPriv->pClipRects;
+       nmesa->drawX = dPriv->x;
+       nmesa->drawY = dPriv->y;
+       nmesa->drawW = dPriv->w;
+       nmesa->drawH = dPriv->h;
+}
+
+static void
+nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa,
+                                  nouveau_renderbuffer * nrb)
+{
+       nmesa->numClipRects = 1;
+       nmesa->pClipRects = &nmesa->osClipRect;
+       nmesa->osClipRect.x1 = 0;
+       nmesa->osClipRect.y1 = 0;
+       nmesa->osClipRect.x2 = nrb->mesa.Width;
+       nmesa->osClipRect.y2 = nrb->mesa.Height;
+       nmesa->drawX = 0;
+       nmesa->drawY = 0;
+       nmesa->drawW = nrb->mesa.Width;
+       nmesa->drawH = nrb->mesa.Height;
+}
+
+void nouveau_window_moved(GLcontext * ctx)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       nouveau_renderbuffer *nrb;
+
+       nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+       if (!nrb)
+               return;
+
+       if (!nrb->dPriv)
+               nouveau_cliprects_renderbuffer_set(nmesa, nrb);
+       else
+               nouveau_cliprects_drawable_set(nmesa, nrb);
+
+       /* Viewport depends on window size/position, nouveauCalcViewport
+        * will take care of calling the hw-specific WindowMoved
+        */
+       ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
+                            ctx->Viewport.Width, ctx->Viewport.Height);
+       /* Scissor depends on window position */
+       ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+                           ctx->Scissor.Width, ctx->Scissor.Height);
+}
+
+GLboolean
+nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       nouveau_renderbuffer *color[MAX_DRAW_BUFFERS];
+       nouveau_renderbuffer *depth;
+
+       _mesa_update_framebuffer(ctx);
+       _mesa_update_draw_buffer_bounds(ctx);
+
+       color[0] = (nouveau_renderbuffer *) fb->_ColorDrawBuffers[0][0];
+       if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
+               depth = (nouveau_renderbuffer *) fb->_DepthBuffer->Wrapped;
+       else
+               depth = (nouveau_renderbuffer *) fb->_DepthBuffer;
+
+       if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth))
+               return GL_FALSE;
+       nouveau_window_moved(ctx);
+
+       return GL_TRUE;
+}
+
+static void nouveauDrawBuffer(GLcontext * ctx, GLenum buffer)
+{
+       nouveau_build_framebuffer(ctx, ctx->DrawBuffer);
+}
+
+static struct gl_framebuffer *nouveauNewFramebuffer(GLcontext * ctx,
+                                                   GLuint name)
+{
+       return _mesa_new_framebuffer(ctx, name);
+}
+
+static struct gl_renderbuffer *nouveauNewRenderbuffer(GLcontext * ctx,
+                                                     GLuint name)
+{
+       nouveau_renderbuffer *nrb;
+
+       nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
+       if (nrb) {
+               _mesa_init_renderbuffer(&nrb->mesa, name);
+
+               nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
+               nrb->mesa.Delete = nouveau_renderbuffer_delete;
+       }
+       return &nrb->mesa;
+}
+
+static void
+nouveauBindFramebuffer(GLcontext * ctx, GLenum target,
+                      struct gl_framebuffer *fb,
+                      struct gl_framebuffer *fbread)
+{
+       if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
+               nouveau_build_framebuffer(ctx, fb);
+       }
+}
+
+static void
+nouveauFramebufferRenderbuffer(GLcontext * ctx,
+                              struct gl_framebuffer *fb,
+                              GLenum attachment,
+                              struct gl_renderbuffer *rb)
+{
+       _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+       nouveau_build_framebuffer(ctx, fb);
+}
+
+static void
+nouveauRenderTexture(GLcontext * ctx,
+                    struct gl_framebuffer *fb,
+                    struct gl_renderbuffer_attachment *att)
+{
+}
+
+static void
+nouveauFinishRenderTexture(GLcontext * ctx,
+                          struct gl_renderbuffer_attachment *att)
+{
+}
+
+void nouveauInitBufferFuncs(struct dd_function_table *func)
+{
+       func->DrawBuffer = nouveauDrawBuffer;
+
+       func->NewFramebuffer = nouveauNewFramebuffer;
+       func->NewRenderbuffer = nouveauNewRenderbuffer;
+       func->BindFramebuffer = nouveauBindFramebuffer;
+       func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer;
+       func->RenderTexture = nouveauRenderTexture;
+       func->FinishRenderTexture = nouveauFinishRenderTexture;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h
new file mode 100644 (file)
index 0000000..757a784
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __NOUVEAU_BUFFERS_H__
+#define __NOUVEAU_BUFFERS_H__
+
+#include <stdint.h>
+#include "mtypes.h"
+#include "utils.h"
+#include "renderbuffer.h"
+
+#include "nouveau_mem.h"
+
+typedef struct nouveau_renderbuffer_t {
+       struct gl_renderbuffer mesa;    /* must be first! */
+       __DRIdrawablePrivate *dPriv;
+
+       nouveau_mem *mem;
+       void *map;
+
+       int cpp;
+       uint32_t offset;
+       uint32_t pitch;
+} nouveau_renderbuffer;
+
+extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat,
+                                                     GLvoid *map,
+                                                     GLuint offset,
+                                                     GLuint pitch,
+                                                     __DRIdrawablePrivate *);
+extern void nouveau_window_moved(GLcontext *);
+extern GLboolean nouveau_build_framebuffer(GLcontext *,
+                                          struct gl_framebuffer *);
+extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *);
+
+extern void nouveauInitBufferFuncs(struct dd_function_table *);
+
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_mem.c b/src/mesa/drivers/dri/nouveau/nouveau_mem.c
new file mode 100644 (file)
index 0000000..35c5326
--- /dev/null
@@ -0,0 +1,144 @@
+#include "mtypes.h"
+
+#include "nouveau_context.h"
+#include "nouveau_fifo.h"
+#include "nouveau_mem.h"
+#include "nouveau_msg.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.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 : NvDmaTT;
+       dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT;
+       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)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       struct drm_nouveau_mem_free 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;
+       memf.offset = mem->offset;
+       drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf,
+                       sizeof(memf));
+       FREE(mem);
+}
+
+nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, uint32_t flags, GLuint size,
+                              GLuint align)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       struct drm_nouveau_mem_alloc mema;
+       nouveau_mem *mem;
+       int ret;
+
+       if (NOUVEAU_DEBUG & DEBUG_MEM) {
+               fprintf(stderr,
+                       "%s: requested: flags=0x%x, size=0x%x, align=0x%x\n",
+                       __func__, flags, (GLuint) size, align);
+       }
+
+       mem = CALLOC(sizeof(nouveau_mem));
+       if (!mem)
+               return NULL;
+
+       mema.flags = flags;
+       mema.size = mem->size = size;
+       mema.alignment = align;
+       mem->map = NULL;
+       ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC,
+                                 &mema, sizeof(mema));
+       if (ret) {
+               FREE(mem);
+               return NULL;
+       }
+       mem->offset = mema.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 (flags & NOUVEAU_MEM_MAPPED)
+               ret = drmMap(nmesa->driFd, mema.map_handle, mem->size,
+                            &mem->map);
+       if (ret) {
+               mem->map = NULL;
+               nouveau_mem_free(ctx, mem);
+               mem = NULL;
+       }
+
+       return mem;
+}
+
+uint32_t nouveau_mem_gpu_offset_get(GLcontext * ctx, nouveau_mem * mem)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+       return mem->offset;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_mem.h b/src/mesa/drivers/dri/nouveau/nouveau_mem.h
new file mode 100644 (file)
index 0000000..6db73f4
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __NOUVEAU_MEM_H__
+#define __NOUVEAU_MEM_H__
+
+typedef struct nouveau_mem_t {
+       int type;
+       uint64_t offset;
+       uint64_t size;
+       void *map;
+} nouveau_mem;
+
+extern nouveau_mem *nouveau_mem_alloc(GLcontext *, uint32_t flags,
+                                     GLuint size, GLuint align);
+extern void nouveau_mem_free(GLcontext *, nouveau_mem *);
+extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *, nouveau_mem *);
+
+extern GLboolean nouveau_memformat_flat_emit(GLcontext *,
+                                            nouveau_mem *dst,
+                                            nouveau_mem *src,
+                                            GLuint dst_offset,
+                                            GLuint src_offset,
+                                            GLuint size);
+
+#endif
index bc39ecd17b5933eaaaa484cedbb5f73093ce0413..c4142a10ef4a6e7907b8a77c7d3216a24215a326 100644 (file)
@@ -30,7 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define __NOUVEAU_SPAN_H__
 
 #include "drirenderbuffer.h"
-#include "nouveau_buffers.h"
+#include "nouveau_fbo.h"
 
 extern void nouveauSpanInitFunctions( GLcontext *ctx );
 extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis);
index 3f5f6d54e9bdf6b878e1f4daa7a558007ea612e7..abb3088032ba140b486456b3c1a17e518b0af69f 100644 (file)
 #include "vblank.h" /* for DO_USLEEP */
 
 #include "nouveau_context.h"
-#include "nouveau_buffers.h"
-#include "nouveau_object.h"
 #include "nouveau_fifo.h"
-#include "nouveau_reg.h"
+#include "nouveau_mem.h"
 #include "nouveau_msg.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
 #include "nouveau_sync.h"
 
 #define NOTIFIER(__v) \
index 1ff4eca3258b9bbc5ce7242b839f23f3a24142c5..fc37efbe6b2c7a7759a3dfd6b255f269fc8a6c12 100644 (file)
@@ -28,8 +28,6 @@
 #ifndef __NOUVEAU_SYNC_H__
 #define __NOUVEAU_SYNC_H__
 
-#include "nouveau_buffers.h"
-
 #define NV_NOTIFIER_SIZE                                                      32
 #define NV_NOTIFY_TIME_0                                              0x00000000
 #define NV_NOTIFY_TIME_1                                              0x00000004