summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-03-21 16:51:54 +0000
committerKeith Whitwell <keithw@vmware.com>2010-03-21 16:56:24 +0000
commit961cbcb62232689c959965384c6aa9b8eca697c1 (patch)
tree057a00f9c737beeeebb83bc168b9ee63abd2f6a3
parent18ba74016db13b23282f5033ee37b628a12ee566 (diff)
nouveau: convert nvfx and nv50 to pipe_resources
Compile tested only. This was a deeper change than I was hoping for, due to the layering of the pipe_texture implementation in each driver on top of a shared pipe_buffer implementation in the shared code. Have modified the shared code to act as a set of convenience routines operating on nouveau_bo objects. Each driver now uses the u_resource_vtbl technique to split the implementation of pipe_resources between the existing miptree code for textures and a new, minimal buffer implementation in each driver. Eventually these should be combined, not least because APIs are now allowing things like binding buffer resources as textures and render targets.
-rw-r--r--configs/default2
-rw-r--r--configs/linux-debug2
-rw-r--r--src/gallium/drivers/nouveau/Makefile6
-rw-r--r--src/gallium/drivers/nouveau/nouveau_context.c41
-rw-r--r--src/gallium/drivers/nouveau/nouveau_context.h11
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c165
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h70
-rw-r--r--src/gallium/drivers/nouveau/nouveau_util.h6
-rw-r--r--src/gallium/drivers/nouveau/nouveau_winsys.h1
-rw-r--r--src/gallium/drivers/nv50/Makefile2
-rw-r--r--src/gallium/drivers/nv50/nv50_buffer.c147
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h37
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c128
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c11
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c7
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.c67
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.h90
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c84
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.h31
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c29
-rw-r--r--src/gallium/drivers/nvfx/Makefile5
-rw-r--r--src/gallium/drivers/nvfx/nv04_surface_2d.c22
-rw-r--r--src/gallium/drivers/nvfx/nv04_surface_2d.h2
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c5
-rw-r--r--src/gallium/drivers/nvfx/nv40_fragtex.c5
-rw-r--r--src/gallium/drivers/nvfx/nvfx_buffer.c151
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.c3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h9
-rw-r--r--src/gallium/drivers/nvfx/nvfx_draw.c28
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragprog.c51
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c170
-rw-r--r--src/gallium/drivers/nvfx/nvfx_resource.c67
-rw-r--r--src/gallium/drivers/nvfx/nvfx_resource.h91
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c12
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.c10
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.h20
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_fb.c8
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.c118
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.h26
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c34
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vertprog.c12
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.c2
49 files changed, 1234 insertions, 575 deletions
diff --git a/configs/default b/configs/default
index b3387d3517..087bea2e3d 100644
--- a/configs/default
+++ b/configs/default
@@ -98,7 +98,7 @@ EGL_DRIVERS_DIRS = glx
# Gallium directories and
GALLIUM_DIRS = auxiliary drivers state_trackers
GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a
-GALLIUM_DRIVERS_DIRS = softpipe trace identity i915 i965 svga r300
+GALLIUM_DRIVERS_DIRS = softpipe trace identity i915 i965 svga r300 nvfx nv50
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
GALLIUM_WINSYS_DIRS = null xlib drm
GALLIUM_TARGET_DIRS = libgl-xlib
diff --git a/configs/linux-debug b/configs/linux-debug
index 01763b1a30..60e0b9769f 100644
--- a/configs/linux-debug
+++ b/configs/linux-debug
@@ -5,5 +5,5 @@ include $(TOP)/configs/linux
CONFIG_NAME = linux-debug
OPT_FLAGS = -g
-CFLAGS += -pedantic
+#CFLAGS += -pedantic
DEFINES += -DDEBUG -DDEBUG_MATH
diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile
index 0cb66041d5..db591b756c 100644
--- a/src/gallium/drivers/nouveau/Makefile
+++ b/src/gallium/drivers/nouveau/Makefile
@@ -3,7 +3,9 @@ include $(TOP)/configs/current
LIBNAME = nouveau
-C_SOURCES = nouveau_screen.c \
- nouveau_context.c
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/drivers/nouveau/include
+
+C_SOURCES = nouveau_screen.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/nouveau/nouveau_context.c b/src/gallium/drivers/nouveau/nouveau_context.c
deleted file mode 100644
index 15174983e7..0000000000
--- a/src/gallium/drivers/nouveau/nouveau_context.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "pipe/p_defines.h"
-#include "pipe/p_context.h"
-
-#include "nouveau/nouveau_screen.h"
-#include "nouveau/nouveau_context.h"
-
-#include "nouveau/nouveau_bo.h"
-
-static unsigned int
-nouveau_reference_flags(struct nouveau_bo *bo)
-{
- uint32_t bo_flags;
- int flags = 0;
-
- bo_flags = nouveau_bo_pending(bo);
- if (bo_flags & NOUVEAU_BO_RD)
- flags |= PIPE_REFERENCED_FOR_READ;
- if (bo_flags & NOUVEAU_BO_WR)
- flags |= PIPE_REFERENCED_FOR_WRITE;
-
- return flags;
-}
-
-unsigned int
-nouveau_is_texture_referenced(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level)
-{
- struct nouveau_miptree *mt = nouveau_miptree(pt);
-
- return nouveau_reference_flags(mt->bo);
-}
-
-unsigned int
-nouveau_is_buffer_referenced(struct pipe_context *pipe, struct pipe_buffer *pb)
-{
- struct nouveau_bo *bo = nouveau_bo(pb);
-
- return nouveau_reference_flags(bo);
-}
-
diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h
deleted file mode 100644
index 6a28d40da7..0000000000
--- a/src/gallium/drivers/nouveau/nouveau_context.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __NOUVEAU_CONTEXT_H__
-#define __NOUVEAU_CONTEXT_H__
-
-unsigned int
-nouveau_is_texture_referenced(struct pipe_context *, struct pipe_texture *,
- unsigned face, unsigned level);
-
-unsigned int
-nouveau_is_buffer_referenced(struct pipe_context *, struct pipe_buffer *);
-
-#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index b1ad686022..944d2c0954 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -32,28 +32,9 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen)
return "nouveau";
}
-static struct pipe_buffer *
-nouveau_screen_bo_skel(struct pipe_screen *pscreen, struct nouveau_bo *bo,
- unsigned alignment, unsigned usage, unsigned size)
-{
- struct pipe_buffer *pb;
- pb = CALLOC(1, sizeof(struct pipe_buffer)+sizeof(struct nouveau_bo *));
- if (!pb) {
- nouveau_bo_ref(NULL, &bo);
- return NULL;
- }
-
- pipe_reference_init(&pb->reference, 1);
- pb->screen = pscreen;
- pb->alignment = alignment;
- pb->usage = usage;
- pb->size = size;
- *(struct nouveau_bo **)(pb + 1) = bo;
- return pb;
-}
-static struct pipe_buffer *
+struct nouveau_bo *
nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
unsigned usage, unsigned size)
{
@@ -93,10 +74,10 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
if (ret)
return NULL;
- return nouveau_screen_bo_skel(pscreen, bo, alignment, usage, size);
+ return bo;
}
-static struct pipe_buffer *
+struct nouveau_bo *
nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
@@ -107,7 +88,7 @@ nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
if (ret)
return NULL;
- return nouveau_screen_bo_skel(pscreen, bo, 0, 0, bytes);
+ return bo;
}
static inline uint32_t
@@ -130,23 +111,14 @@ nouveau_screen_map_flags(unsigned pipe)
return flags;
}
-static void *
-nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+void *
+nouveau_screen_bo_map(struct pipe_screen *pscreen,
+ struct nouveau_bo *pb,
unsigned usage)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
struct nouveau_screen *nscreen = nouveau_screen(pscreen);
int ret;
- if (nscreen->pre_pipebuffer_map_callback) {
- ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
- if (ret) {
- debug_printf("pre_pipebuffer_map_callback failed %d\n",
- ret);
- return NULL;
- }
- }
-
ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage));
if (ret) {
debug_printf("map failed: %d\n", ret);
@@ -156,24 +128,14 @@ nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
return bo->map;
}
-static void *
-nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+void *
+nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
unsigned offset, unsigned length, unsigned usage)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
struct nouveau_screen *nscreen = nouveau_screen(pscreen);
uint32_t flags = nouveau_screen_map_flags(usage);
int ret;
- if (nscreen->pre_pipebuffer_map_callback) {
- ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
- if (ret) {
- debug_printf("pre_pipebuffer_map_callback failed %d\n",
- ret);
- return NULL;
- }
- }
-
ret = nouveau_bo_map_range(bo, offset, length, flags);
if (ret) {
nouveau_bo_unmap(bo);
@@ -185,30 +147,23 @@ nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
return (char *)bo->map - offset; /* why gallium? why? */
}
-static void
-nouveau_screen_bo_map_flush(struct pipe_screen *pscreen, struct pipe_buffer *pb,
- unsigned offset, unsigned length)
+void
+nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
+ unsigned offset, unsigned length)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
-
nouveau_bo_map_flush(bo, offset, length);
}
-static void
-nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct pipe_buffer *pb)
+void
+nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
-
nouveau_bo_unmap(bo);
}
-static void
-nouveau_screen_bo_del(struct pipe_buffer *pb)
+void
+nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
-
nouveau_bo_ref(NULL, &bo);
- FREE(pb);
}
static void
@@ -236,59 +191,32 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
}
-/*
- * Both texture_{from|get}_handle use drm api defines directly which they
- * shouldn't do. The problem is that from|get are pipe functions and as
- * such they should be defined in the pipe level. If nouveau had a propper
- * winsys interface we would have added from|get to that interface using
- * the winsys_handle struct as done with other drivers. However this code
- * calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
- * we need to translate the handle into something they understand.
- */
-static struct pipe_texture *
-nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
- const struct pipe_texture *templ,
- struct winsys_handle *whandle)
+struct nouveau_bo *
+nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
+ struct winsys_handle *whandle,
+ unsigned *out_stride)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
- struct pipe_texture *pt;
- struct pipe_buffer *pb;
- int ret;
-
- pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
- if (!pb)
- return NULL;
-
- ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
+ struct nouveau_bo *bo;
+
+ ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo);
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
__func__, whandle->handle, ret);
- FREE(pb);
return NULL;
}
- pipe_reference_init(&pb->reference, 1);
- pb->screen = pscreen;
- pb->alignment = 0;
- pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ_WRITE;
- pb->size = nouveau_bo(pb)->size;
- pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ,
- &whandle->stride, pb);
- pipe_buffer_reference(&pb, NULL);
- return pt;
+ *out_stride = whandle->stride;
+ return bo;
}
-static boolean
-nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
- struct pipe_texture *pt,
- struct winsys_handle *whandle)
-{
- struct nouveau_miptree *mt = nouveau_miptree(pt);
-
- if (!mt || !mt->bo)
- return false;
+boolean
+nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
+ struct nouveau_bo *bo,
+ unsigned stride,
+ struct winsys_handle *whandle)
+{
whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
@@ -301,6 +229,26 @@ nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
}
}
+
+unsigned int
+nouveau_reference_flags(struct nouveau_bo *bo)
+{
+ uint32_t bo_flags;
+ int flags = 0;
+
+ bo_flags = nouveau_bo_pending(bo);
+ if (bo_flags & NOUVEAU_BO_RD)
+ flags |= PIPE_REFERENCED_FOR_READ;
+ if (bo_flags & NOUVEAU_BO_WR)
+ flags |= PIPE_REFERENCED_FOR_WRITE;
+
+ return flags;
+}
+
+
+
+
+
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@@ -316,21 +264,10 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
pscreen->get_name = nouveau_screen_get_name;
pscreen->get_vendor = nouveau_screen_get_vendor;
- pscreen->buffer_create = nouveau_screen_bo_new;
- pscreen->user_buffer_create = nouveau_screen_bo_user;
- pscreen->buffer_map = nouveau_screen_bo_map;
- pscreen->buffer_map_range = nouveau_screen_bo_map_range;
- pscreen->buffer_flush_mapped_range = nouveau_screen_bo_map_flush;
- pscreen->buffer_unmap = nouveau_screen_bo_unmap;
- pscreen->buffer_destroy = nouveau_screen_bo_del;
-
pscreen->fence_reference = nouveau_screen_fence_ref;
pscreen->fence_signalled = nouveau_screen_fence_signalled;
pscreen->fence_finish = nouveau_screen_fence_finish;
- pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
- pscreen->texture_get_handle = nouveau_screen_texture_get_handle;
-
return 0;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index f4a7a2bc23..1ba4113bfc 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -5,21 +5,6 @@ struct nouveau_screen {
struct pipe_screen base;
struct nouveau_device *device;
struct nouveau_channel *channel;
-
- /**
- * Create a new texture object, using the given template info, but on top of
- * existing memory.
- *
- * It is assumed that the buffer data is layed out according to the expected
- * by the hardware. NULL will be returned if any inconsistency is found.
- */
- struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
- const struct pipe_texture *templat,
- const unsigned *stride,
- struct pipe_buffer *buffer);
-
- int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen,
- struct pipe_buffer *pb, unsigned usage);
};
static inline struct nouveau_screen *
@@ -28,24 +13,51 @@ nouveau_screen(struct pipe_screen *pscreen)
return (struct nouveau_screen *)pscreen;
}
-static inline struct nouveau_bo *
-nouveau_bo(struct pipe_buffer *pb)
-{
- return pb ? *(struct nouveau_bo **)(pb + 1) : NULL;
-}
+
+
+/* Not really sure if this is needed, or whether the individual
+ * drivers are happy to talk to the bo functions themselves. In a way
+ * this is what we'd expect from a regular winsys interface.
+ */
+struct nouveau_bo *
+nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
+ unsigned usage, unsigned size);
+struct nouveau_bo *
+nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes);
+void *
+nouveau_screen_bo_map(struct pipe_screen *pscreen,
+ struct nouveau_bo *pb,
+ unsigned usage);
+void *
+nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
+ unsigned offset, unsigned length, unsigned usage);
+void
+nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
+ unsigned offset, unsigned length);
+void
+nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo);
+void
+nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo);
+
+boolean
+nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
+ struct nouveau_bo *bo,
+ unsigned stride,
+ struct winsys_handle *whandle);
+struct nouveau_bo *
+nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
+ struct winsys_handle *whandle,
+ unsigned *out_stride);
+
+unsigned int
+nouveau_reference_flags(struct nouveau_bo *bo);
+
+
int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
void nouveau_screen_fini(struct nouveau_screen *);
-struct nouveau_miptree {
- struct pipe_texture base;
- struct nouveau_bo *bo;
-};
-static inline struct nouveau_miptree *
-nouveau_miptree(struct pipe_texture *pt)
-{
- return (struct nouveau_miptree *)pt;
-}
+
#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h
index ab7761a31d..ed6e643785 100644
--- a/src/gallium/drivers/nouveau/nouveau_util.h
+++ b/src/gallium/drivers/nouveau/nouveau_util.h
@@ -98,9 +98,9 @@ struct u_split_prim {
unsigned p_start;
unsigned p_end;
- int repeat_first:1;
- int close_first:1;
- int edgeflag_off:1;
+ uint repeat_first:1;
+ uint close_first:1;
+ uint edgeflag_off:1;
};
static inline void
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index bed014b9ce..9c73a015c7 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -2,7 +2,6 @@
#define NOUVEAU_WINSYS_H
#include <stdint.h>
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "nouveau/nouveau_bo.h"
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile
index 5d622e1c13..e31e6f8662 100644
--- a/src/gallium/drivers/nv50/Makefile
+++ b/src/gallium/drivers/nv50/Makefile
@@ -4,12 +4,14 @@ include $(TOP)/configs/current
LIBNAME = nv50
C_SOURCES = \
+ nv50_buffer.c \
nv50_clear.c \
nv50_context.c \
nv50_draw.c \
nv50_miptree.c \
nv50_query.c \
nv50_program.c \
+ nv50_resource.c \
nv50_screen.c \
nv50_state.c \
nv50_state_validate.c \
diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c
new file mode 100644
index 0000000000..3b2e58116d
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_buffer.c
@@ -0,0 +1,147 @@
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "nouveau/nouveau_screen.h"
+#include "nv50_resource.h"
+
+
+
+static void nv50_buffer_destroy(struct pipe_screen *pscreen,
+ struct pipe_resource *presource)
+{
+ struct nv50_resource *buffer = nv50_resource(presource);
+
+ nouveau_screen_bo_release(pscreen, buffer->bo);
+ FREE(buffer);
+}
+
+
+
+
+/* Utility functions for transfer create/destroy are hooked in and
+ * just record the arguments to those functions.
+ */
+static void *
+nv50_buffer_transfer_map( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct nv50_resource *buffer = nv50_resource(transfer->resource);
+ uint8_t *map;
+
+ map = nouveau_screen_bo_map_range( pipe->screen,
+ buffer->bo,
+ transfer->box.x,
+ transfer->box.width,
+ transfer->usage );
+ if (map == NULL)
+ return NULL;
+
+ return map + transfer->box.x;
+}
+
+
+
+static void nv50_buffer_transfer_flush_region( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
+{
+ struct nv50_resource *buffer = nv50_resource(transfer->resource);
+
+ nouveau_screen_bo_map_flush_range(pipe->screen,
+ buffer->bo,
+ transfer->box.x + box->x,
+ box->width);
+}
+
+static void nv50_buffer_transfer_unmap( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct nv50_resource *buffer = nv50_resource(transfer->resource);
+
+ nouveau_screen_bo_unmap(pipe->screen, buffer->bo);
+}
+
+
+
+
+struct u_resource_vtbl nv50_buffer_vtbl =
+{
+ u_default_resource_get_handle, /* get_handle */
+ nv50_buffer_destroy, /* resource_destroy */
+ NULL, /* is_resource_referenced */
+ u_default_get_transfer, /* get_transfer */
+ u_default_transfer_destroy, /* transfer_destroy */
+ nv50_buffer_transfer_map, /* transfer_map */
+ nv50_buffer_transfer_flush_region, /* transfer_flush_region */
+ nv50_buffer_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+
+
+
+struct pipe_resource *
+nv50_buffer_create(struct pipe_screen *pscreen,
+ const struct pipe_resource *template)
+{
+ struct nv50_resource *buffer;
+
+ buffer = CALLOC_STRUCT(nv50_resource);
+ if (!buffer)
+ return NULL;
+
+ buffer->base = *template;
+ buffer->vtbl = &nv50_buffer_vtbl;
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = pscreen;
+
+ buffer->bo = nouveau_screen_bo_new(pscreen,
+ 16,
+ buffer->base.usage,
+ buffer->base.width0);
+
+ if (buffer->bo == NULL)
+ goto fail;
+
+ return &buffer->base;
+
+fail:
+ FREE(buffer);
+ return NULL;
+}
+
+
+struct pipe_resource *
+nv50_user_buffer_create(struct pipe_screen *pscreen,
+ void *ptr,
+ unsigned bytes,
+ unsigned usage)
+{
+ struct nv50_resource *buffer;
+
+ buffer = CALLOC_STRUCT(nv50_resource);
+ if (!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->vtbl = &nv50_buffer_vtbl;
+ buffer->base.screen = pscreen;
+ buffer->base.format = PIPE_FORMAT_R8_UNORM;
+ buffer->base.usage = usage;
+ buffer->base.width0 = bytes;
+ buffer->base.height0 = 1;
+ buffer->base.depth0 = 1;
+
+ buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
+ if (!buffer->bo)
+ goto fail;
+
+ return &buffer->base;
+
+fail:
+ FREE(buffer);
+ return NULL;
+}
+
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index aa14e17872..7a3da01866 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -89,9 +89,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50->pipe.flush = nv50_flush;
- nv50->pipe.is_texture_referenced = nouveau_is_texture_referenced;
- nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
-
screen->base.channel->user_private = nv50;
nv50_init_surface_functions(nv50);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index bc7831d9ac..8bf465378e 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -16,7 +16,6 @@
#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_gldefs.h"
#include "nouveau/nouveau_stateobj.h"
-#include "nouveau/nouveau_context.h"
#include "nv50_screen.h"
#include "nv50_program.h"
@@ -101,27 +100,6 @@ get_tile_depth(uint32_t tile_mode)
return 1 << (tile_mode >> 4);
}
-struct nv50_miptree_level {
- int *image_offset;
- unsigned pitch;
- unsigned tile_mode;
-};
-
-#define NV50_MAX_TEXTURE_LEVELS 16
-
-struct nv50_miptree {
- struct nouveau_miptree base;
-
- struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
- int image_nr;
- int total_size;
-};
-
-static INLINE struct nv50_miptree *
-nv50_miptree(struct pipe_texture *pt)
-{
- return (struct nv50_miptree *)pt;
-}
struct nv50_surface {
struct pipe_surface base;
@@ -165,7 +143,7 @@ struct nv50_context {
struct nv50_program *vertprog;
struct nv50_program *fragprog;
struct nv50_program *geomprog;
- struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
+ struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
struct nv50_vtxelt_stateobj *vtxelt;
@@ -206,12 +184,12 @@ extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode,
unsigned startInstance,
unsigned instanceCount);
extern void nv50_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count);
extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count,
@@ -222,7 +200,7 @@ extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
/* nv50_push.c */
extern void
-nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *,
+nv50_push_elements_instanced(struct pipe_context *, struct pipe_resource *,
unsigned idxsize, unsigned mode, unsigned start,
unsigned count, unsigned i_start,
unsigned i_count);
@@ -258,13 +236,6 @@ extern boolean nv50_tex_construct(struct nv50_sampler_view *view);
extern void nv50_tex_relocs(struct nv50_context *);
extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
-/* nv50_transfer.c */
-extern void
-nv50_upload_sifc(struct nv50_context *nv50,
- struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc,
- unsigned dst_format, int dst_w, int dst_h, int dst_pitch,
- void *src, unsigned src_format, int src_pitch,
- int x, int y, int w, int h, int cpp);
/* nv50_context.c */
struct pipe_context *
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index e091cae602..8186938b79 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -26,6 +26,8 @@
#include "util/u_format.h"
#include "nv50_context.h"
+#include "nv50_resource.h"
+#include "nv50_transfer.h"
/* The restrictions in tile mode selection probably aren't necessary. */
static INLINE uint32_t
@@ -70,12 +72,66 @@ get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h)
return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d;
}
-static struct pipe_texture *
-nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
+
+
+
+static void
+nv50_miptree_destroy(struct pipe_screen *pscreen,
+ struct pipe_resource *pt)
+{
+ struct nv50_miptree *mt = nv50_miptree(pt);
+ unsigned l;
+
+ for (l = 0; l <= pt->last_level; ++l)
+ FREE(mt->level[l].image_offset);
+
+ nouveau_screen_bo_release(pscreen, mt->base.bo);
+ FREE(mt);
+}
+
+static boolean
+nv50_miptree_get_handle(struct pipe_screen *pscreen,
+ struct pipe_resource *pt,
+ struct winsys_handle *whandle)
+{
+ struct nv50_miptree *mt = nv50_miptree(pt);
+ unsigned stride;
+
+
+ if (!mt || !mt->base.bo)
+ return FALSE;
+
+ stride = util_format_get_stride(mt->base.base.format,
+ mt->base.base.width0);
+
+ return nouveau_screen_bo_get_handle(pscreen,
+ mt->base.bo,
+ stride,
+ whandle);
+}
+
+
+struct u_resource_vtbl nv50_miptree_vtbl =
+{
+ nv50_miptree_get_handle, /* get_handle */
+ nv50_miptree_destroy, /* resource_destroy */
+ NULL, /* is_resource_referenced */
+ nv50_miptree_transfer_new, /* get_transfer */
+ nv50_miptree_transfer_del, /* transfer_destroy */
+ nv50_miptree_transfer_map, /* transfer_map */
+ u_default_transfer_flush_region, /* transfer_flush_region */
+ nv50_miptree_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+
+
+struct pipe_resource *
+nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *tmp)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
- struct pipe_texture *pt = &mt->base.base;
+ struct pipe_resource *pt = &mt->base.base;
unsigned width = tmp->width0, height = tmp->height0;
unsigned depth = tmp->depth0, image_alignment;
uint32_t tile_flags;
@@ -165,49 +221,53 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
return pt;
}
-static struct pipe_texture *
-nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
- const unsigned *stride, struct pipe_buffer *pb)
+
+struct pipe_resource *
+nv50_miptree_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
struct nv50_miptree *mt;
+ unsigned stride;
/* Only supports 2D, non-mipmapped textures for the moment */
- if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
- pt->depth0 != 1)
+ if (template->target != PIPE_TEXTURE_2D ||
+ template->last_level != 0 ||
+ template->depth0 != 1)
return NULL;
mt = CALLOC_STRUCT(nv50_miptree);
if (!mt)
return NULL;
- mt->base.base = *pt;
+ mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
+ if (mt->base.bo == NULL) {
+ FREE(mt);
+ return NULL;
+ }
+
+
+ mt->base.base = *template;
pipe_reference_init(&mt->base.base.reference, 1);
mt->base.base.screen = pscreen;
mt->image_nr = 1;
- mt->level[0].pitch = *stride;
+ mt->level[0].pitch = stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
- mt->level[0].tile_mode = bo->tile_mode;
+ mt->level[0].tile_mode = mt->base.bo->tile_mode;
- nouveau_bo_ref(bo, &mt->base.bo);
+ /* XXX: Need to adjust bo refcount??
+ */
+ /* nouveau_bo_ref(bo, &mt->base.bo); */
return &mt->base.base;
}
-static void
-nv50_miptree_destroy(struct pipe_texture *pt)
-{
- struct nv50_miptree *mt = nv50_miptree(pt);
- unsigned l;
- for (l = 0; l <= pt->last_level; ++l)
- FREE(mt->level[l].image_offset);
- nouveau_bo_ref(NULL, &mt->base.bo);
- FREE(mt);
-}
+/* Surface functions
+ */
-static struct pipe_surface *
-nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+struct pipe_surface *
+nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
@@ -222,7 +282,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ps = CALLOC_STRUCT(pipe_surface);
if (!ps)
return NULL;
- pipe_texture_reference(&ps->texture, pt);
+ pipe_resource_reference(&ps->texture, pt);
ps->format = pt->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
@@ -242,23 +302,11 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
return ps;
}
-static void
+void
nv50_miptree_surface_del(struct pipe_surface *ps)
{
struct nv50_surface *s = nv50_surface(ps);
- pipe_texture_reference(&ps->texture, NULL);
+ pipe_resource_reference(&ps->texture, NULL);
FREE(s);
}
-
-void
-nv50_screen_init_miptree_functions(struct pipe_screen *pscreen)
-{
- pscreen->texture_create = nv50_miptree_create;
- pscreen->texture_destroy = nv50_miptree_destroy;
- pscreen->get_tex_surface = nv50_miptree_surface_new;
- pscreen->tex_surface_destroy = nv50_miptree_surface_del;
-
- nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket;
-}
-
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index c857816b31..a1bcdf489e 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -4157,7 +4157,8 @@ nv50_program_upload_data(struct nv50_context *nv50, uint32_t *map,
static void
nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
{
- struct pipe_screen *pscreen = nv50->pipe.screen;
+ struct pipe_context *pipe = &nv50->pipe;
+ struct pipe_transfer *transfer;
if (!p->data[0] && p->immd_nr) {
struct nouveau_resource *heap = nv50->screen->immd_heap[0];
@@ -4182,9 +4183,10 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
if (p->param_nr) {
unsigned cb;
- uint32_t *map = pipe_buffer_map(pscreen,
+ uint32_t *map = pipe_buffer_map(pipe,
nv50->constbuf[p->type],
- PIPE_BUFFER_USAGE_CPU_READ);
+ PIPE_TRANSFER_READ,
+ &transfer);
switch (p->type) {
case PIPE_SHADER_GEOMETRY: cb = NV50_CB_PGP; break;
case PIPE_SHADER_FRAGMENT: cb = NV50_CB_PFP; break;
@@ -4195,7 +4197,8 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
}
nv50_program_upload_data(nv50, map, 0, p->param_nr, cb);
- pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]);
+ pipe_buffer_unmap(pipe, nv50->constbuf[p->type],
+ transfer);
}
}
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
index 96a1f32d30..6981e5b919 100644
--- a/src/gallium/drivers/nv50/nv50_push.c
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -5,6 +5,7 @@
#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
+#include "nv50_resource.h"
struct push_context {
struct nv50_context *nv50;
@@ -171,7 +172,7 @@ emit_verts(void *priv, unsigned start, unsigned count)
void
nv50_push_elements_instanced(struct pipe_context *pipe,
- struct pipe_buffer *idxbuf, unsigned idxsize,
+ struct pipe_resource *idxbuf, unsigned idxsize,
unsigned mode, unsigned start, unsigned count,
unsigned i_start, unsigned i_count)
{
@@ -199,7 +200,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe,
for (i = 0; i < nv50->vtxelt->num_elements; i++) {
struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
unsigned size, nr_components, n;
if (!(nv50->vbo_fifo & (1 << i)))
@@ -260,7 +261,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe,
/* map index buffer, if present */
if (idxbuf) {
- struct nouveau_bo *bo = nouveau_bo(idxbuf);
+ struct nouveau_bo *bo = nv50_resource(idxbuf)->bo;
if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
assert(bo->map);
diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c
new file mode 100644
index 0000000000..cfdb60418b
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_resource.c
@@ -0,0 +1,67 @@
+
+#include "pipe/p_context.h"
+#include "nv50_resource.h"
+#include "nouveau/nouveau_screen.h"
+
+
+/* This doesn't look quite right - this query is supposed to ask
+ * whether the particular context has references to the resource in
+ * any unflushed rendering command buffer, and hence requires a
+ * pipe->flush() for serializing some modification to that resource.
+ *
+ * This seems to be answering the question of whether the resource is
+ * currently on hardware.
+ */
+static unsigned int
+nv50_resource_is_referenced(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned face, unsigned level)
+{
+ return nouveau_reference_flags(nv50_resource(resource)->bo);
+}
+
+static struct pipe_resource *
+nv50_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *template)
+{
+ if (template->target == PIPE_BUFFER)
+ return nv50_buffer_create(screen, template);
+ else
+ return nv50_miptree_create(screen, template);
+}
+
+static struct pipe_resource *
+nv50_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
+{
+ if (template->target == PIPE_BUFFER)
+ return NULL;
+ else
+ return nv50_miptree_from_handle(screen, template, whandle);
+}
+
+void
+nv50_init_resource_functions(struct pipe_context *pcontext)
+{
+ pcontext->get_transfer = u_get_transfer_vtbl;
+ pcontext->transfer_map = u_transfer_map_vtbl;
+ pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
+ pcontext->transfer_unmap = u_transfer_unmap_vtbl;
+ pcontext->transfer_destroy = u_transfer_destroy_vtbl;
+ pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
+ pcontext->is_resource_referenced = nv50_resource_is_referenced;
+}
+
+void
+nv50_screen_init_resource_functions(struct pipe_screen *pscreen)
+{
+ pscreen->resource_create = nv50_resource_create;
+ pscreen->resource_from_handle = nv50_resource_from_handle;
+ pscreen->resource_get_handle = u_resource_get_handle_vtbl;
+ pscreen->resource_destroy = u_resource_destroy_vtbl;
+ pscreen->user_buffer_create = nv50_user_buffer_create;
+
+ pscreen->get_tex_surface = nv50_miptree_surface_new;
+ pscreen->tex_surface_destroy = nv50_miptree_surface_del;
+}
diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h
new file mode 100644
index 0000000000..963a1100ce
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_resource.h
@@ -0,0 +1,90 @@
+
+#ifndef NV50_RESOURCE_H
+#define NV50_RESOURCE_H
+
+#include "util/u_transfer.h"
+
+struct pipe_resource;
+struct nouveau_bo;
+
+
+/* This gets further specialized into either buffer or texture
+ * structures. In the future we'll want to remove much of that
+ * distinction, but for now try to keep as close to the existing code
+ * as possible and use the vtbl struct to choose between the two
+ * underlying implementations.
+ */
+struct nv50_resource {
+ struct pipe_resource base;
+ struct u_resource_vtbl *vtbl;
+ struct nouveau_bo *bo;
+};
+
+struct nv50_miptree_level {
+ int *image_offset;
+ unsigned pitch;
+ unsigned tile_mode;
+};
+
+#define NV50_MAX_TEXTURE_LEVELS 16
+
+struct nv50_miptree {
+ struct nv50_resource base;
+
+ struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
+ int image_nr;
+ int total_size;
+};
+
+static INLINE struct nv50_miptree *
+nv50_miptree(struct pipe_resource *pt)
+{
+ return (struct nv50_miptree *)pt;
+}
+
+
+static INLINE
+struct nv50_resource *nv50_resource(struct pipe_resource *resource)
+{
+ return (struct nv50_resource *)resource;
+}
+
+
+void
+nv50_init_resource_functions(struct pipe_context *pcontext);
+
+void
+nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
+
+/* Internal functions
+ */
+struct pipe_resource *
+nv50_miptree_create(struct pipe_screen *pscreen,
+ const struct pipe_resource *tmp);
+
+struct pipe_resource *
+nv50_miptree_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle);
+
+struct pipe_resource *
+nv50_buffer_create(struct pipe_screen *pscreen,
+ const struct pipe_resource *template);
+
+struct pipe_resource *
+nv50_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes,
+ unsigned usage);
+
+
+struct pipe_surface *
+nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned flags);
+
+void
+nv50_miptree_surface_del(struct pipe_surface *ps);
+
+
+#endif
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index ec19ea655b..22fe7e46bb 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -22,7 +22,7 @@ struct nv50_screen {
struct nouveau_resource *immd_heap[1];
struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES];
- struct pipe_buffer *strm_vbuf[16];
+ struct pipe_resource *strm_vbuf[16];
struct nouveau_bo *tic;
struct nouveau_bo *tsc;
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index c162808928..e885a2b719 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -310,13 +310,13 @@ static void
nv50_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
- pipe_texture_reference(&view->texture, NULL);
+ pipe_resource_reference(&view->texture, NULL);
FREE(nv50_sampler_view(view));
}
static struct pipe_sampler_view *
nv50_create_sampler_view(struct pipe_context *pipe,
- struct pipe_texture *texture,
+ struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view);
@@ -324,7 +324,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
view->pipe = *templ;
view->pipe.reference.count = 1;
view->pipe.texture = NULL;
- pipe_texture_reference(&view->pipe.texture, texture);
+ pipe_resource_reference(&view->pipe.texture, texture);
view->pipe.context = pipe;
if (!nv50_tex_construct(view)) {
@@ -690,7 +690,7 @@ nv50_set_clip_state(struct pipe_context *pipe,
static void
nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_buffer *buf )
+ struct pipe_resource *buf )
{
struct nv50_context *nv50 = nv50_context(pipe);
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index 63d73b5ce8..356bdcd74b 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -23,6 +23,7 @@
#include "util/u_format.h"
#include "nv50_context.h"
+#include "nv50_resource.h"
#include "nouveau/nouveau_stateobj.h"
static struct nouveau_stateobj *
@@ -43,7 +44,7 @@ validate_fb(struct nv50_context *nv50)
(4 << 16) | (5 << 19) | (6 << 22) | (7 << 25));
for (i = 0; i < fb->nr_cbufs; i++) {
- struct pipe_texture *pt = fb->cbufs[i]->texture;
+ struct pipe_resource *pt = fb->cbufs[i]->texture;
struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
if (!gw) {
@@ -104,7 +105,7 @@ validate_fb(struct nv50_context *nv50)
}
if (fb->zsbuf) {
- struct pipe_texture *pt = fb->zsbuf->texture;
+ struct pipe_resource *pt = fb->zsbuf->texture;
struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
if (!gw) {
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 6467c48a32..2bab023397 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "nouveau/nouveau_pushbuf.h"
#include "nv50_context.h"
+#include "nv50_resource.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 85ab947c00..ea539635ae 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -22,6 +22,7 @@
#include "nv50_context.h"
#include "nv50_texture.h"
+#include "nv50_resource.h"
#include "nouveau/nouveau_stateobj.h"
#include "nouveau/nouveau_reloc.h"
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index c30b787167..293bdf1df5 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -5,6 +5,8 @@
#include "util/u_math.h"
#include "nv50_context.h"
+#include "nv50_transfer.h"
+#include "nv50_resource.h"
struct nv50_transfer {
struct pipe_transfer base;
@@ -120,44 +122,51 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
}
}
-static struct pipe_transfer *
-nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
+struct pipe_transfer *
+nv50_miptree_transfer_new(struct pipe_context *pcontext,
+ struct pipe_resource *pt,
+ struct pipe_subresource sr,
+ enum pipe_transfer_usage usage,
+ const struct pipe_box *box)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = nv50_miptree(pt);
- struct nv50_miptree_level *lvl = &mt->level[level];
+ struct nv50_miptree_level *lvl = &mt->level[sr.level];
struct nv50_transfer *tx;
unsigned nx, ny, image = 0;
int ret;
if (pt->target == PIPE_TEXTURE_CUBE)
- image = face;
+ image = sr.face;
tx = CALLOC_STRUCT(nv50_transfer);
if (!tx)
return NULL;
- pipe_texture_reference(&tx->base.texture, pt);
- tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level));
- tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level));
- tx->base.width = w;
- tx->base.height = h;
+ /* Don't handle 3D transfers yet.
+ */
+ assert(box->depth == 1);
+
+
+ pipe_resource_reference(&tx->base.resource, pt);
+ tx->base.sr = sr;
+ tx->base.usage = usage;
+ tx->base.box = *box;
+ tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, sr.level));
+ tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, sr.level));
tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format);
tx->base.usage = usage;
tx->level_pitch = lvl->pitch;
- tx->level_width = u_minify(mt->base.base.width0, level);
- tx->level_height = u_minify(mt->base.base.height0, level);
- tx->level_depth = u_minify(mt->base.base.depth0, level);
+ tx->level_width = u_minify(mt->base.base.width0, sr.level);
+ tx->level_height = u_minify(mt->base.base.height0, sr.level);
+ tx->level_depth = u_minify(mt->base.base.depth0, sr.level);
tx->level_offset = lvl->image_offset[image];
tx->level_tiling = lvl->tile_mode;
- tx->level_z = zslice;
- tx->level_x = util_format_get_nblocksx(pt->format, x);
- tx->level_y = util_format_get_nblocksy(pt->format, y);
+ tx->level_z = box->z;
+ tx->level_x = util_format_get_nblocksx(pt->format, box->x);
+ tx->level_y = util_format_get_nblocksy(pt->format, box->y);
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
tx->nblocksy * tx->base.stride, &tx->bo);
if (ret) {
@@ -166,12 +175,12 @@ nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
}
if (usage & PIPE_TRANSFER_READ) {
- nx = util_format_get_nblocksx(pt->format, tx->base.width);
- ny = util_format_get_nblocksy(pt->format, tx->base.height);
+ nx = util_format_get_nblocksx(pt->format, box->width);
+ ny = util_format_get_nblocksy(pt->format, box->height);
nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
tx->level_pitch, tx->level_tiling,
- x, y, zslice,
+ box->x, box->y, box->z,
tx->nblocksx, tx->nblocksy,
tx->level_depth,
tx->bo, 0,
@@ -186,15 +195,16 @@ nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
return &tx->base;
}
-static void
-nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+void
+nv50_miptree_transfer_del(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
- struct nv50_miptree *mt = nv50_miptree(ptx->texture);
- struct pipe_texture *pt = ptx->texture;
+ struct nv50_miptree *mt = nv50_miptree(ptx->resource);
+ struct pipe_resource *pt = ptx->resource;
- unsigned nx = util_format_get_nblocksx(pt->format, tx->base.width);
- unsigned ny = util_format_get_nblocksy(pt->format, tx->base.height);
+ unsigned nx = util_format_get_nblocksx(pt->format, tx->base.box.width);
+ unsigned ny = util_format_get_nblocksy(pt->format, tx->base.box.height);
if (ptx->usage & PIPE_TRANSFER_WRITE) {
struct pipe_screen *pscreen = pcontext->screen;
@@ -214,12 +224,13 @@ nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
}
nouveau_bo_ref(NULL, &tx->bo);
- pipe_texture_reference(&ptx->texture, NULL);
+ pipe_resource_reference(&ptx->resource, NULL);
FREE(ptx);
}
-static void *
-nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+void *
+nv50_miptree_transfer_map(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
unsigned flags = 0;
@@ -236,22 +247,15 @@ nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
return tx->bo->map;
}
-static void
-nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+void
+nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
nouveau_bo_unmap(tx->bo);
}
-void
-nv50_init_transfer_functions(struct nv50_context *nv50)
-{
- nv50->pipe.get_transfer = nv50_transfer_new;
- nv50->pipe.transfer_destroy = nv50_transfer_del;
- nv50->pipe.transfer_map = nv50_transfer_map;
- nv50->pipe.transfer_unmap = nv50_transfer_unmap;
-}
void
nv50_upload_sifc(struct nv50_context *nv50,
diff --git a/src/gallium/drivers/nv50/nv50_transfer.h b/src/gallium/drivers/nv50/nv50_transfer.h
new file mode 100644
index 0000000000..c6373f1f80
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_transfer.h
@@ -0,0 +1,31 @@
+
+#ifndef NV50_TRANSFER_H
+#define NV50_TRANSFER_H
+
+#include "pipe/p_state.h"
+
+
+struct pipe_transfer *
+nv50_miptree_transfer_new(struct pipe_context *pcontext,
+ struct pipe_resource *pt,
+ struct pipe_subresource sr,
+ enum pipe_transfer_usage usage,
+ const struct pipe_box *box);
+void
+nv50_miptree_transfer_del(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx);
+void *
+nv50_miptree_transfer_map(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx);
+void
+nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx);
+
+extern void
+nv50_upload_sifc(struct nv50_context *nv50,
+ struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc,
+ unsigned dst_format, int dst_w, int dst_h, int dst_pitch,
+ void *src, unsigned src_format, int src_pitch,
+ int x, int y, int w, int h, int cpp);
+
+#endif
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 5047286806..72b796edf6 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -27,6 +27,7 @@
#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
+#include "nv50_resource.h"
static INLINE uint32_t
nv50_vbo_type_to_hw(enum pipe_format format)
@@ -139,7 +140,7 @@ instance_init(struct nv50_context *nv50, struct instance *a, unsigned first)
if (a[i].divisor) {
vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- a[i].bo = nouveau_bo(vb->buffer);
+ a[i].bo = nv50_resource(vb->buffer)->bo;
a[i].stride = vb->stride;
a[i].step = first % a[i].divisor;
a[i].delta = vb->buffer_offset + ve->src_offset +
@@ -307,14 +308,14 @@ inline_edgeflag(void *priv, boolean enabled)
static void
nv50_draw_elements_inline(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer, unsigned indexSize,
+ struct pipe_resource *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count,
unsigned startInstance, unsigned instanceCount)
{
- struct pipe_screen *pscreen = pipe->screen;
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct pipe_transfer *transfer;
struct instance a[16];
struct inline_ctx ctx;
struct u_split_prim s;
@@ -337,7 +338,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe,
s.edge = inline_edgeflag;
ctx.nv50 = nv50;
- ctx.map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
+ ctx.map = pipe_buffer_map(pipe, indexBuffer, PIPE_TRANSFER_READ, &transfer);
assert(ctx.map);
if (!ctx.map)
return;
@@ -380,12 +381,12 @@ nv50_draw_elements_inline(struct pipe_context *pipe,
nzi = TRUE;
}
- pipe_buffer_unmap(pscreen, indexBuffer);
+ pipe_buffer_unmap(pipe, indexBuffer, transfer);
}
void
nv50_draw_elements_instanced(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count,
unsigned startInstance, unsigned instanceCount)
@@ -431,7 +432,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
if (indexSize == 4) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
OUT_RING (chan, count);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ nouveau_pushbuf_submit(chan,
+ nv50_resource(indexBuffer)->bo,
start << 2, count << 2);
} else
if (indexSize == 2) {
@@ -443,7 +445,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
OUT_RING (chan, ((start & 1) << 31) | count);
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
OUT_RING (chan, dwords);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ nouveau_pushbuf_submit(chan,
+ nv50_resource(indexBuffer)->bo,
vb_start << 1, dwords << 2);
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
OUT_RING (chan, 0);
@@ -457,7 +460,7 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
void
nv50_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer, unsigned indexSize,
+ struct pipe_resource *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
nv50_draw_elements_instanced(pipe, indexBuffer, indexSize,
@@ -473,7 +476,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
{
struct nouveau_stateobj *so;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
float v[4];
int ret;
unsigned nr_components = util_format_get_nr_components(ve->src_format);
@@ -571,7 +574,7 @@ nv50_vbo_validate(struct nv50_context *nv50)
struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
- struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
uint32_t hw = nv50->vtxelt->hw[i];
if (!vb->stride &&
@@ -608,10 +611,10 @@ nv50_vbo_validate(struct nv50_context *nv50)
/* vertex array limits */
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
- so_reloc (vtxbuf, bo, vb->buffer->size - 1,
+ so_reloc (vtxbuf, bo, vb->buffer->width0 - 1,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (vtxbuf, bo, vb->buffer->size - 1,
+ so_reloc (vtxbuf, bo, vb->buffer->width0 - 1,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
}
diff --git a/src/gallium/drivers/nvfx/Makefile b/src/gallium/drivers/nvfx/Makefile
index dfe97e6ed5..c1d57ca396 100644
--- a/src/gallium/drivers/nvfx/Makefile
+++ b/src/gallium/drivers/nvfx/Makefile
@@ -5,6 +5,7 @@ LIBNAME = nvfx
C_SOURCES = \
nv04_surface_2d.c \
+ nvfx_buffer.c \
nvfx_context.c \
nvfx_clear.c \
nvfx_draw.c \
@@ -14,6 +15,7 @@ C_SOURCES = \
nv40_fragtex.c \
nvfx_miptree.c \
nvfx_query.c \
+ nvfx_resource.c \
nvfx_screen.c \
nvfx_state.c \
nvfx_state_blend.c \
@@ -29,4 +31,7 @@ C_SOURCES = \
nvfx_vbo.c \
nvfx_vertprog.c
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/drivers/nouveau/include
+
include ../../Makefile.template
diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.c b/src/gallium/drivers/nvfx/nv04_surface_2d.c
index ed18c9f24d..c0b7ee25c2 100644
--- a/src/gallium/drivers/nvfx/nv04_surface_2d.c
+++ b/src/gallium/drivers/nvfx/nv04_surface_2d.c
@@ -125,8 +125,8 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
struct nouveau_channel *chan = ctx->swzsurf->channel;
struct nouveau_grobj *swzsurf = ctx->swzsurf;
struct nouveau_grobj *sifm = ctx->sifm;
- struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
- struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
+ struct nouveau_bo *src_bo = ctx->buf(src);
+ struct nouveau_bo *dst_bo = ctx->buf(dst);
const unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
/* Max width & height may not be the same on all HW, but must be POT */
const unsigned max_w = 1024;
@@ -205,8 +205,8 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
{
struct nouveau_channel *chan = ctx->m2mf->channel;
struct nouveau_grobj *m2mf = ctx->m2mf;
- struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
- struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
+ struct nouveau_bo *src_bo = ctx->buf(src);
+ struct nouveau_bo *dst_bo = ctx->buf(dst);
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
unsigned dst_offset = dst->offset + dy * dst_pitch +
@@ -252,8 +252,8 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
struct nouveau_channel *chan = ctx->surf2d->channel;
struct nouveau_grobj *surf2d = ctx->surf2d;
struct nouveau_grobj *blit = ctx->blit;
- struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
- struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
+ struct nouveau_bo *src_bo = ctx->buf(src);
+ struct nouveau_bo *dst_bo = ctx->buf(dst);
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
int format;
@@ -317,7 +317,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
struct nouveau_channel *chan = ctx->surf2d->channel;
struct nouveau_grobj *surf2d = ctx->surf2d;
struct nouveau_grobj *rect = ctx->rect;
- struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
+ struct nouveau_bo *dst_bo = ctx->buf(dst);
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
int cs2d_format, gdirect_format;
@@ -507,10 +507,10 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d
// printf("creating temp, flags is %i!\n", flags);
- if(ns->base.usage & PIPE_BUFFER_USAGE_DISCARD)
+ if(0 /*ns->base.usage & PIPE_BUFFER_USAGE_DISCARD*/)
{
temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ;
- ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_DISCARD;
+ ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER /*| PIPE_BUFFER_USAGE_DISCARD */;
}
else
{
@@ -520,7 +520,7 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d
ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
- struct pipe_texture templ;
+ struct pipe_resource templ;
memset(&templ, 0, sizeof(templ));
templ.format = ns->base.texture->format;
templ.target = PIPE_TEXTURE_2D;
@@ -534,7 +534,7 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d
templ.tex_usage = ns->base.texture->tex_usage | PIPE_TEXTURE_USAGE_RENDER_TARGET;
- struct pipe_texture* temp_tex = pscreen->texture_create(pscreen, &templ);
+ struct pipe_resource* temp_tex = pscreen->resource_create(pscreen, &templ);
struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags);
temp_ns->backing = ns;
diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.h b/src/gallium/drivers/nvfx/nv04_surface_2d.h
index ce696a11a3..dbc9e50af1 100644
--- a/src/gallium/drivers/nvfx/nv04_surface_2d.h
+++ b/src/gallium/drivers/nvfx/nv04_surface_2d.h
@@ -16,7 +16,7 @@ struct nv04_surface_2d {
struct nouveau_grobj *blit;
struct nouveau_grobj *sifm;
- struct pipe_buffer *(*buf)(struct pipe_surface *);
+ struct nouveau_bo *(*buf)(struct pipe_surface *);
void (*copy)(struct nv04_surface_2d *, struct pipe_surface *dst,
int dx, int dy, struct pipe_surface *src, int sx, int sy,
diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c
index 2b56f45492..40cdde3f63 100644
--- a/src/gallium/drivers/nvfx/nv30_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv30_fragtex.c
@@ -3,6 +3,7 @@
#include "nvfx_context.h"
#include "nouveau/nouveau_util.h"
#include "nvfx_tex.h"
+#include "nvfx_resource.h"
void
nv30_sampler_state_init(struct pipe_context *pipe,
@@ -92,8 +93,8 @@ nv30_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
struct nvfx_miptree *nv30mt = nvfx->tex_miptree[unit];
- struct pipe_texture *pt = &nv30mt->base;
- struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
+ struct pipe_resource *pt = &nv30mt->base.base;
+ struct nouveau_bo *bo = nv30mt->base.bo;
struct nv30_texture_format *tf;
struct nouveau_stateobj *so;
uint32_t txf, txs;
diff --git a/src/gallium/drivers/nvfx/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c
index 5889b5e40d..3f03afe9f1 100644
--- a/src/gallium/drivers/nvfx/nv40_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv40_fragtex.c
@@ -1,6 +1,7 @@
#include "util/u_format.h"
#include "nvfx_context.h"
#include "nvfx_tex.h"
+#include "nvfx_resource.h"
void
nv40_sampler_state_init(struct pipe_context *pipe,
@@ -110,8 +111,8 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
struct nvfx_miptree *nv40mt = nvfx->tex_miptree[unit];
- struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
- struct pipe_texture *pt = &nv40mt->base;
+ struct nouveau_bo *bo = nv40mt->base.bo;
+ struct pipe_resource *pt = &nv40mt->base.base;
struct nv40_texture_format *tf;
struct nouveau_stateobj *so;
uint32_t txf, txs, txp;
diff --git a/src/gallium/drivers/nvfx/nvfx_buffer.c b/src/gallium/drivers/nvfx/nvfx_buffer.c
new file mode 100644
index 0000000000..8efb84a5ad
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_buffer.c
@@ -0,0 +1,151 @@
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "nouveau/nouveau_screen.h"
+#include "nvfx_resource.h"
+
+
+/* Currently using separate implementations for buffers and textures,
+ * even though gallium has a unified abstraction of these objects.
+ * Eventually these should be combined, and mechanisms like transfers
+ * be adapted to work for both buffer and texture uploads.
+ */
+static void nvfx_buffer_destroy(struct pipe_screen *pscreen,
+ struct pipe_resource *presource)
+{
+ struct nvfx_resource *buffer = nvfx_resource(presource);
+
+ nouveau_screen_bo_release(pscreen, buffer->bo);
+ FREE(buffer);
+}
+
+
+
+
+/* Utility functions for transfer create/destroy are hooked in and
+ * just record the arguments to those functions.
+ */
+static void *
+nvfx_buffer_transfer_map( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct nvfx_resource *buffer = nvfx_resource(transfer->resource);
+ uint8_t *map;
+
+ map = nouveau_screen_bo_map_range( pipe->screen,
+ buffer->bo,
+ transfer->box.x,
+ transfer->box.width,
+ transfer->usage );
+ if (map == NULL)
+ return NULL;
+
+ return map + transfer->box.x;
+}
+
+
+
+static void nvfx_buffer_transfer_flush_region( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
+{
+ struct nvfx_resource *buffer = nvfx_resource(transfer->resource);
+
+ nouveau_screen_bo_map_flush_range(pipe->screen,
+ buffer->bo,
+ transfer->box.x + box->x,
+ box->width);
+}
+
+static void nvfx_buffer_transfer_unmap( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct nvfx_resource *buffer = nvfx_resource(transfer->resource);
+
+ nouveau_screen_bo_unmap(pipe->screen, buffer->bo);
+}
+
+
+
+
+struct u_resource_vtbl nvfx_buffer_vtbl =
+{
+ u_default_resource_get_handle, /* get_handle */
+ nvfx_buffer_destroy, /* resource_destroy */
+ NULL, /* is_resource_referenced */
+ u_default_get_transfer, /* get_transfer */
+ u_default_transfer_destroy, /* transfer_destroy */
+ nvfx_buffer_transfer_map, /* transfer_map */
+ nvfx_buffer_transfer_flush_region, /* transfer_flush_region */
+ nvfx_buffer_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+
+
+
+struct pipe_resource *
+nvfx_buffer_create(struct pipe_screen *pscreen,
+ const struct pipe_resource *template)
+{
+ struct nvfx_resource *buffer;
+
+ buffer = CALLOC_STRUCT(nvfx_resource);
+ if (!buffer)
+ return NULL;
+
+ buffer->base = *template;
+ buffer->vtbl = &nvfx_buffer_vtbl;
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = pscreen;
+
+ buffer->bo = nouveau_screen_bo_new(pscreen,
+ 16,
+ buffer->base.usage,
+ buffer->base.width0);
+
+ if (buffer->bo == NULL)
+ goto fail;
+
+ return &buffer->base;
+
+fail:
+ FREE(buffer);
+ return NULL;
+}
+
+
+struct pipe_resource *
+nvfx_user_buffer_create(struct pipe_screen *pscreen,
+ void *ptr,
+ unsigned bytes,
+ unsigned usage)
+{
+ struct nvfx_resource *buffer;
+
+ buffer = CALLOC_STRUCT(nvfx_resource);
+ if (!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->vtbl = &nvfx_buffer_vtbl;
+ buffer->base.screen = pscreen;
+ buffer->base.format = PIPE_FORMAT_R8_UNORM;
+ buffer->base.usage = usage;
+ buffer->base.width0 = bytes;
+ buffer->base.height0 = 1;
+ buffer->base.depth0 = 1;
+
+ buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
+ if (!buffer->bo)
+ goto fail;
+
+ return &buffer->base;
+
+fail:
+ FREE(buffer);
+ return NULL;
+}
+
diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c
index fc3cbdb558..1420484aa2 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.c
+++ b/src/gallium/drivers/nvfx/nvfx_context.c
@@ -65,9 +65,6 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
nvfx->pipe.clear = nvfx_clear;
nvfx->pipe.flush = nvfx_flush;
- nvfx->pipe.is_texture_referenced = nouveau_is_texture_referenced;
- nvfx->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
-
screen->base.channel->user_private = nvfx;
screen->base.channel->flush_notify = nvfx_state_flush_notify;
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index 001b19eedf..63d66a7801 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -16,7 +16,6 @@
#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_gldefs.h"
-#include "nouveau/nouveau_context.h"
#include "nouveau/nouveau_stateobj.h"
#include "nvfx_state.h"
@@ -146,7 +145,7 @@ struct nvfx_context {
struct pipe_clip_state clip;
struct nvfx_vertex_program *vertprog;
struct nvfx_fragment_program *fragprog;
- struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
+ struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
unsigned constbuf_nr[PIPE_SHADER_TYPES];
struct nvfx_rasterizer_state *rasterizer;
struct nvfx_zsa_state *zsa;
@@ -155,7 +154,7 @@ struct nvfx_context {
struct pipe_stencil_ref stencil_ref;
struct pipe_viewport_state viewport;
struct pipe_framebuffer_state framebuffer;
- struct pipe_buffer *idxbuf;
+ struct pipe_resource *idxbuf;
unsigned idxbuf_format;
struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct nvfx_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
@@ -211,7 +210,7 @@ extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers,
/* nvfx_draw.c */
extern struct draw_stage *nvfx_draw_render_stage(struct nvfx_context *nvfx);
extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe,
- struct pipe_buffer *idxbuf,
+ struct pipe_resource *idxbuf,
unsigned ib_size, unsigned mode,
unsigned start, unsigned count);
@@ -253,7 +252,7 @@ extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx);
extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode,
unsigned start, unsigned count);
extern void nvfx_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count);
diff --git a/src/gallium/drivers/nvfx/nvfx_draw.c b/src/gallium/drivers/nvfx/nvfx_draw.c
index 5379b29efd..9ef6918b7f 100644
--- a/src/gallium/drivers/nvfx/nvfx_draw.c
+++ b/src/gallium/drivers/nvfx/nvfx_draw.c
@@ -228,11 +228,13 @@ nvfx_draw_render_stage(struct nvfx_context *nvfx)
void
nvfx_draw_elements_swtnl(struct pipe_context *pipe,
- struct pipe_buffer *idxbuf, unsigned idxbuf_size,
+ struct pipe_resource *idxbuf, unsigned idxbuf_size,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
- struct pipe_screen *pscreen = pipe->screen;
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *ib_transfer;
+ struct pipe_transfer *cb_transfer;
unsigned i;
void *map;
@@ -242,14 +244,16 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe,
nvfx_state_emit(nvfx);
for (i = 0; i < nvfx->vtxbuf_nr; i++) {
- map = pipe_buffer_map(pscreen, nvfx->vtxbuf[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe, nvfx->vtxbuf[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &vb_transfer[i]);
draw_set_mapped_vertex_buffer(nvfx->draw, i, map);
}
if (idxbuf) {
- map = pipe_buffer_map(pscreen, idxbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe, idxbuf,
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &ib_transfer);
draw_set_mapped_element_buffer(nvfx->draw, idxbuf_size, map);
} else {
draw_set_mapped_element_buffer(nvfx->draw, 0, NULL);
@@ -258,9 +262,10 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe,
if (nvfx->constbuf[PIPE_SHADER_VERTEX]) {
const unsigned nr = nvfx->constbuf_nr[PIPE_SHADER_VERTEX];
- map = pipe_buffer_map(pscreen,
+ map = pipe_buffer_map(pipe,
nvfx->constbuf[PIPE_SHADER_VERTEX],
- PIPE_BUFFER_USAGE_CPU_READ);
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &cb_transfer);
draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0,
map, nr);
}
@@ -268,13 +273,14 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe,
draw_arrays(nvfx->draw, mode, start, count);
for (i = 0; i < nvfx->vtxbuf_nr; i++)
- pipe_buffer_unmap(pscreen, nvfx->vtxbuf[i].buffer);
+ pipe_buffer_unmap(pipe, nvfx->vtxbuf[i].buffer, vb_transfer[i]);
if (idxbuf)
- pipe_buffer_unmap(pscreen, idxbuf);
+ pipe_buffer_unmap(pipe, idxbuf, ib_transfer);
if (nvfx->constbuf[PIPE_SHADER_VERTEX])
- pipe_buffer_unmap(pscreen, nvfx->constbuf[PIPE_SHADER_VERTEX]);
+ pipe_buffer_unmap(pipe, nvfx->constbuf[PIPE_SHADER_VERTEX],
+ cb_transfer);
draw_flush(nvfx->draw);
pipe->flush(pipe, 0, NULL);
diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c
index 76351430f4..d85484dbe6 100644
--- a/src/gallium/drivers/nvfx/nvfx_fragprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c
@@ -9,6 +9,7 @@
#include "nvfx_context.h"
#include "nvfx_shader.h"
+#include "nvfx_resource.h"
#define MAX_CONSTS 128
#define MAX_IMM 32
@@ -825,12 +826,8 @@ static void
nvfx_fragprog_upload(struct nvfx_context *nvfx,
struct nvfx_fragment_program *fp)
{
- struct pipe_screen *pscreen = nvfx->pipe.screen;
+ struct pipe_context *pipe = &nvfx->pipe;
const uint32_t le = 1;
- uint32_t *map;
- int i;
-
- map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
#if 0
for (i = 0; i < fp->insn_len; i++) {
@@ -841,25 +838,37 @@ nvfx_fragprog_upload(struct nvfx_context *nvfx,
#endif
if ((*(const uint8_t *)&le)) {
- for (i = 0; i < fp->insn_len; i++) {
- map[i] = fp->insn[i];
- }
+ /* Can do this with an inline transfer */
+ pipe_buffer_write(pipe,
+ fp->buffer,
+ 0,
+ fp->insn_len * sizeof fp->insn[0],
+ fp->insn);
} else {
+ struct pipe_transfer *transfer;
+ uint32_t *map;
+ int i;
+
+ map = pipe_buffer_map(pipe, fp->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE,
+ &transfer);
+
/* Weird swapping for big-endian chips */
for (i = 0; i < fp->insn_len; i++) {
map[i] = ((fp->insn[i] & 0xffff) << 16) |
((fp->insn[i] >> 16) & 0xffff);
}
- }
- pipe_buffer_unmap(pscreen, fp->buffer);
+ pipe_buffer_unmap(pipe, fp->buffer, transfer);
+ }
}
static boolean
nvfx_fragprog_validate(struct nvfx_context *nvfx)
{
+ struct pipe_context *pipe = &nvfx->pipe;
struct nvfx_fragment_program *fp = nvfx->fragprog;
- struct pipe_buffer *constbuf =
+ struct pipe_resource *constbuf =
nvfx->constbuf[PIPE_SHADER_FRAGMENT];
struct pipe_screen *pscreen = nvfx->pipe.screen;
struct nouveau_stateobj *so;
@@ -876,12 +885,12 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
return FALSE;
}
- fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
+ fp->buffer = pipe_buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
nvfx_fragprog_upload(nvfx, fp);
so = so_new(4, 4, 1);
so_method(so, nvfx->screen->eng3d, NV34TCL_FP_ACTIVE_PROGRAM, 1);
- so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
+ so_reloc (so, nvfx_resource(fp->buffer)->bo, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
@@ -899,10 +908,18 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
update_constants:
if (fp->nr_consts) {
+ struct pipe_transfer *transfer;
float *map;
- map = pipe_buffer_map(pscreen, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe, constbuf,
+ PIPE_TRANSFER_READ,
+ &transfer);
+
+ /* XXX: probably a bad idea to be reading back data
+ * from a buffer the gpu has been using. Not really
+ * sure what this code is doing though, or how to
+ * avoid it - kw.
+ */
for (i = 0; i < fp->nr_consts; i++) {
struct nvfx_fragment_program_data *fpd = &fp->consts[i];
uint32_t *p = &fp->insn[fpd->offset];
@@ -913,7 +930,7 @@ update_constants:
memcpy(p, cb, 4 * sizeof(float));
new_consts = TRUE;
}
- pipe_buffer_unmap(pscreen, constbuf);
+ pipe_buffer_unmap(pipe, constbuf, transfer);
if (new_consts)
nvfx_fragprog_upload(nvfx, fp);
@@ -932,7 +949,7 @@ nvfx_fragprog_destroy(struct nvfx_context *nvfx,
struct nvfx_fragment_program *fp)
{
if (fp->buffer)
- pipe_buffer_reference(&fp->buffer, NULL);
+ pipe_resource_reference(&fp->buffer, NULL);
if (fp->so)
so_ref(NULL, &fp->so);
diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 0f5ed61aab..0999dd9106 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -5,14 +5,22 @@
#include "util/u_math.h"
#include "nvfx_context.h"
+#include "nvfx_resource.h"
+#include "nvfx_transfer.h"
#include "nv04_surface_2d.h"
+#include "nouveau/nouveau_util.h"
+/* Currently using separate implementations for buffers and textures,
+ * even though gallium has a unified abstraction of these objects.
+ * Eventually these should be combined, and mechanisms like transfers
+ * be adapted to work for both buffer and texture uploads.
+ */
static void
nvfx_miptree_layout(struct nvfx_miptree *mt)
{
- struct pipe_texture *pt = &mt->base;
+ struct pipe_resource *pt = &mt->base.base;
uint width = pt->width0;
uint offset = 0;
int nr_faces, l, f;
@@ -61,32 +69,84 @@ nvfx_miptree_layout(struct nvfx_miptree *mt)
mt->total_size = offset;
}
-static struct pipe_texture *
-nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
+static boolean
+nvfx_miptree_get_handle(struct pipe_screen *pscreen,
+ struct pipe_resource *ptexture,
+ struct winsys_handle *whandle)
+{
+ struct nvfx_miptree* mt = (struct nvfx_miptree*)ptexture;
+
+ if (!mt || !mt->base.bo)
+ return FALSE;
+
+ return nouveau_screen_bo_get_handle(pscreen,
+ mt->base.bo,
+ mt->level[0].pitch,
+ whandle);
+}
+
+
+static void
+nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
+{
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+ int l;
+
+ nouveau_screen_bo_release(screen, mt->base.bo);
+
+ for (l = 0; l <= pt->last_level; l++) {
+ if (mt->level[l].image_offset)
+ FREE(mt->level[l].image_offset);
+ }
+
+ FREE(mt);
+}
+
+
+
+
+struct u_resource_vtbl nvfx_miptree_vtbl =
+{
+ nvfx_miptree_get_handle, /* get_handle */
+ nvfx_miptree_destroy, /* resource_destroy */
+ NULL, /* is_resource_referenced */
+ nvfx_miptree_transfer_new, /* get_transfer */
+ nvfx_miptree_transfer_del, /* transfer_destroy */
+ nvfx_miptree_transfer_map, /* transfer_map */
+ u_default_transfer_flush_region, /* transfer_flush_region */
+ nvfx_miptree_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+
+
+struct pipe_resource *
+nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt)
{
struct nvfx_miptree *mt;
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
NOUVEAU_BUFFER_USAGE_TEXTURE;
- mt = MALLOC(sizeof(struct nvfx_miptree));
+ mt = CALLOC_STRUCT(nvfx_miptree);
if (!mt)
return NULL;
- mt->base = *pt;
- pipe_reference_init(&mt->base.reference, 1);
- mt->base.screen = pscreen;
+
+ mt->base.base = *pt;
+ pipe_reference_init(&mt->base.base.reference, 1);
+ mt->base.base.screen = pscreen;
/* Swizzled textures must be POT */
if (pt->width0 & (pt->width0 - 1) ||
pt->height0 & (pt->height0 - 1))
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else {
switch (pt->format) {
case PIPE_FORMAT_B5G6R5_UNORM:
@@ -98,7 +158,7 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
are just preserving the pre-unification behavior.
The whole 2D code is going to be rewritten anyway. */
if(nvfx_screen(pscreen)->is_nv4x) {
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
/* TODO: Figure out which formats can be swizzled */
@@ -107,11 +167,11 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
case PIPE_FORMAT_R16_SNORM:
{
if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
default:
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
}
}
@@ -122,65 +182,68 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
* If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
* This also happens for small mipmaps of large textures. */
if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
nvfx_miptree_layout(mt);
- mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage, mt->total_size);
- if (!mt->buffer) {
+ mt->base.bo = nouveau_screen_bo_new(pscreen, 256, buf_usage, mt->total_size);
+ if (!mt->base.bo) {
FREE(mt);
return NULL;
}
- mt->bo = nouveau_bo(mt->buffer);
- return &mt->base;
+ return &mt->base.base;
}
-static struct pipe_texture *
-nvfx_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
- const unsigned *stride, struct pipe_buffer *pb)
+
+
+
+struct pipe_resource *
+nvfx_miptree_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
{
struct nvfx_miptree *mt;
+ unsigned stride;
/* Only supports 2D, non-mipmapped textures for the moment */
- if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
- pt->depth0 != 1)
+ if (template->target != PIPE_TEXTURE_2D ||
+ template->last_level != 0 ||
+ template->depth0 != 1)
return NULL;
mt = CALLOC_STRUCT(nvfx_miptree);
if (!mt)
return NULL;
- mt->base = *pt;
- pipe_reference_init(&mt->base.reference, 1);
- mt->base.screen = pscreen;
- mt->level[0].pitch = stride[0];
+ mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
+ if (mt->base.bo == NULL) {
+ FREE(mt);
+ return NULL;
+ }
+
+ mt->base.base = *template;
+ pipe_reference_init(&mt->base.base.reference, 1);
+ mt->base.base.screen = pscreen;
+ mt->level[0].pitch = stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
/* Assume whoever created this buffer expects it to be linear for now */
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- pipe_buffer_reference(&mt->buffer, pb);
- mt->bo = nouveau_bo(mt->buffer);
- return &mt->base;
+ /* XXX: Need to adjust bo refcount??
+ */
+ /* nouveau_bo_ref(bo, &mt->base.bo); */
+ return &mt->base.base;
}
-static void
-nvfx_miptree_destroy(struct pipe_texture *pt)
-{
- struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
- int l;
- pipe_buffer_reference(&mt->buffer, NULL);
- for (l = 0; l <= pt->last_level; l++) {
- if (mt->level[l].image_offset)
- FREE(mt->level[l].image_offset);
- }
- FREE(mt);
-}
-static struct pipe_surface *
-nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+
+/* Surface helpers, not strictly required to implement the resource vtbl:
+ */
+struct pipe_surface *
+nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
@@ -190,7 +253,7 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ns = CALLOC_STRUCT(nv04_surface);
if (!ns)
return NULL;
- pipe_texture_reference(&ns->base.texture, pt);
+ pipe_resource_reference(&ns->base.texture, pt);
ns->base.format = pt->format;
ns->base.width = u_minify(pt->width0, level);
ns->base.height = u_minify(pt->height0, level);
@@ -219,7 +282,7 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
return &ns->base;
}
-static void
+void
nvfx_miptree_surface_del(struct pipe_surface *ps)
{
struct nv04_surface* ns = (struct nv04_surface*)ps;
@@ -231,17 +294,6 @@ nvfx_miptree_surface_del(struct pipe_surface *ps)
nvfx_miptree_surface_del(&ns->backing->base);
}
- pipe_texture_reference(&ps->texture, NULL);
+ pipe_resource_reference(&ps->texture, NULL);
FREE(ps);
}
-
-void
-nvfx_screen_init_miptree_functions(struct pipe_screen *pscreen)
-{
- pscreen->texture_create = nvfx_miptree_create;
- pscreen->texture_destroy = nvfx_miptree_destroy;
- pscreen->get_tex_surface = nvfx_miptree_surface_new;
- pscreen->tex_surface_destroy = nvfx_miptree_surface_del;
-
- nouveau_screen(pscreen)->texture_blanket = nvfx_miptree_blanket;
-}
diff --git a/src/gallium/drivers/nvfx/nvfx_resource.c b/src/gallium/drivers/nvfx/nvfx_resource.c
new file mode 100644
index 0000000000..5bf1e5cb65
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_resource.c
@@ -0,0 +1,67 @@
+
+#include "pipe/p_context.h"
+#include "nvfx_resource.h"
+#include "nouveau/nouveau_screen.h"
+
+
+/* This doesn't look quite right - this query is supposed to ask
+ * whether the particular context has references to the resource in
+ * any unflushed rendering command buffer, and hence requires a
+ * pipe->flush() for serializing some modification to that resource.
+ *
+ * This seems to be answering the question of whether the resource is
+ * currently on hardware.
+ */
+static unsigned int
+nvfx_resource_is_referenced(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned face, unsigned level)
+{
+ return nouveau_reference_flags(nvfx_resource(resource)->bo);
+}
+
+static struct pipe_resource *
+nvfx_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *template)
+{
+ if (template->target == PIPE_BUFFER)
+ return nvfx_buffer_create(screen, template);
+ else
+ return nvfx_miptree_create(screen, template);
+}
+
+static struct pipe_resource *
+nvfx_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
+{
+ if (template->target == PIPE_BUFFER)
+ return NULL;
+ else
+ return nvfx_miptree_from_handle(screen, template, whandle);
+}
+
+void
+nvfx_init_resource_functions(struct pipe_context *pcontext)
+{
+ pcontext->get_transfer = u_get_transfer_vtbl;
+ pcontext->transfer_map = u_transfer_map_vtbl;
+ pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
+ pcontext->transfer_unmap = u_transfer_unmap_vtbl;
+ pcontext->transfer_destroy = u_transfer_destroy_vtbl;
+ pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
+ pcontext->is_resource_referenced = nvfx_resource_is_referenced;
+}
+
+void
+nvfx_screen_init_resource_functions(struct pipe_screen *pscreen)
+{
+ pscreen->resource_create = nvfx_resource_create;
+ pscreen->resource_from_handle = nvfx_resource_from_handle;
+ pscreen->resource_get_handle = u_resource_get_handle_vtbl;
+ pscreen->resource_destroy = u_resource_destroy_vtbl;
+ pscreen->user_buffer_create = nvfx_user_buffer_create;
+
+ pscreen->get_tex_surface = nvfx_miptree_surface_new;
+ pscreen->tex_surface_destroy = nvfx_miptree_surface_del;
+}
diff --git a/src/gallium/drivers/nvfx/nvfx_resource.h b/src/gallium/drivers/nvfx/nvfx_resource.h
new file mode 100644
index 0000000000..93133e8eed
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_resource.h
@@ -0,0 +1,91 @@
+
+#ifndef NVFX_RESOURCE_H
+#define NVFX_RESOURCE_H
+
+#include "util/u_transfer.h"
+
+struct pipe_resource;
+struct nouveau_bo;
+
+
+/* This gets further specialized into either buffer or texture
+ * structures. In the future we'll want to remove much of that
+ * distinction, but for now try to keep as close to the existing code
+ * as possible and use the vtbl struct to choose between the two
+ * underlying implementations.
+ */
+struct nvfx_resource {
+ struct pipe_resource base;
+ struct u_resource_vtbl *vtbl;
+ struct nouveau_bo *bo;
+};
+
+#define NVFX_MAX_TEXTURE_LEVELS 16
+
+struct nvfx_miptree {
+ struct nvfx_resource base;
+ uint total_size;
+
+ struct {
+ uint pitch;
+ uint *image_offset;
+ } level[NVFX_MAX_TEXTURE_LEVELS];
+
+ unsigned image_nr;
+};
+
+static INLINE
+struct nvfx_resource *nvfx_resource(struct pipe_resource *resource)
+{
+ return (struct nvfx_resource *)resource;
+}
+
+static INLINE struct nouveau_bo *
+nvfx_surface_buffer(struct pipe_surface *surf)
+{
+ struct nvfx_resource *mt = nvfx_resource(surf->texture);
+
+ return mt->bo;
+}
+
+
+void
+nvfx_init_resource_functions(struct pipe_context *pcontext);
+
+void
+nvfx_screen_init_resource_functions(struct pipe_screen *pscreen);
+
+
+/* Internal:
+ */
+
+struct pipe_resource *
+nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt);
+
+struct pipe_resource *
+nvfx_miptree_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle);
+
+struct pipe_resource *
+nvfx_buffer_create(struct pipe_screen *pscreen,
+ const struct pipe_resource *template);
+
+struct pipe_resource *
+nvfx_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes,
+ unsigned usage);
+
+
+
+void
+nvfx_miptree_surface_del(struct pipe_surface *ps);
+
+struct pipe_surface *
+nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned flags);
+
+
+#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 8138715cc7..2638892088 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -5,6 +5,7 @@
#include "nvfx_context.h"
#include "nvfx_screen.h"
+#include "nvfx_resource.h"
#define NV30TCL_CHIPSET_3X_MASK 0x00000003
#define NV34TCL_CHIPSET_3X_MASK 0x00000010
@@ -16,7 +17,7 @@
* with same number of bits everywhere.
*/
struct nouveau_winsys {
- struct pipe_winsys base;
+ //struct pipe_winsys base;
struct pipe_screen *pscreen;
@@ -174,13 +175,6 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
return FALSE;
}
-static struct pipe_buffer *
-nvfx_surface_buffer(struct pipe_surface *surf)
-{
- struct nvfx_miptree *mt = (struct nvfx_miptree *)surf->texture;
-
- return mt->buffer;
-}
static void
nvfx_screen_destroy(struct pipe_screen *pscreen)
@@ -352,7 +346,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- nvfx_screen_init_miptree_functions(pscreen);
+ nvfx_screen_init_resource_functions(pscreen);
ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
if (ret) {
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index c0b4b9899d..a83dffe0af 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -3,6 +3,7 @@
#include "nouveau/nouveau_screen.h"
#include "nv04_surface_2d.h"
+#include "nvfx_context.h"
struct nvfx_screen {
struct nouveau_screen base;
diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c
index ecaa0dcb16..e11ab46c42 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.c
+++ b/src/gallium/drivers/nvfx/nvfx_state.c
@@ -163,7 +163,7 @@ nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
static struct pipe_sampler_view *
nvfx_create_sampler_view(struct pipe_context *pipe,
- struct pipe_texture *texture,
+ struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
@@ -172,7 +172,7 @@ nvfx_create_sampler_view(struct pipe_context *pipe,
*view = *templ;
view->reference.count = 1;
view->texture = NULL;
- pipe_texture_reference(&view->texture, texture);
+ pipe_resource_reference(&view->texture, texture);
view->context = pipe;
}
@@ -184,7 +184,7 @@ static void
nvfx_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
- pipe_texture_reference(&view->texture, NULL);
+ pipe_resource_reference(&view->texture, NULL);
FREE(view);
}
@@ -499,12 +499,12 @@ nvfx_set_clip_state(struct pipe_context *pipe,
static void
nvfx_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_buffer *buf )
+ struct pipe_resource *buf )
{
struct nvfx_context *nvfx = nvfx_context(pipe);
nvfx->constbuf[shader] = buf;
- nvfx->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
+ nvfx->constbuf_nr[shader] = buf->width0 / (4 * sizeof(float));
if (shader == PIPE_SHADER_VERTEX) {
nvfx->dirty |= NVFX_NEW_VERTPROG;
diff --git a/src/gallium/drivers/nvfx/nvfx_state.h b/src/gallium/drivers/nvfx/nvfx_state.h
index e585246879..1f612ea95f 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.h
+++ b/src/gallium/drivers/nvfx/nvfx_state.h
@@ -58,26 +58,14 @@ struct nvfx_fragment_program {
struct nvfx_fragment_program_data *consts;
unsigned nr_consts;
-
- struct pipe_buffer *buffer;
+
+ /* XXX: just use a nouveau_bo for this?
+ */
+ struct pipe_resource *buffer;
uint32_t fp_control;
struct nouveau_stateobj *so;
};
-#define NVFX_MAX_TEXTURE_LEVELS 16
-
-struct nvfx_miptree {
- struct pipe_texture base;
- struct nouveau_bo *bo;
-
- struct pipe_buffer *buffer;
- uint total_size;
-
- struct {
- uint pitch;
- uint *image_offset;
- } level[NVFX_MAX_TEXTURE_LEVELS];
-};
#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_state_fb.c b/src/gallium/drivers/nvfx/nvfx_state_fb.c
index dd64ba4193..665c0c36bb 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_fb.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_fb.c
@@ -1,14 +1,8 @@
#include "nvfx_context.h"
+#include "nvfx_resource.h"
#include "nouveau/nouveau_util.h"
-static struct pipe_buffer *
-nvfx_do_surface_buffer(struct pipe_surface *surface)
-{
- struct nvfx_miptree *mt = (struct nvfx_miptree *)surface->texture;
- return mt->buffer;
-}
-#define nvfx_surface_buffer(ps) nouveau_bo(nvfx_do_surface_buffer(ps))
static boolean
nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c
index b9124757e7..09eca00493 100644
--- a/src/gallium/drivers/nvfx/nvfx_transfer.c
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.c
@@ -8,6 +8,8 @@
#include "nvfx_context.h"
#include "nvfx_screen.h"
#include "nvfx_state.h"
+#include "nvfx_resource.h"
+#include "nvfx_transfer.h"
struct nvfx_transfer {
struct pipe_transfer base;
@@ -16,10 +18,10 @@ struct nvfx_transfer {
};
static void
-nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
- struct pipe_texture *template)
+nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned height,
+ struct pipe_resource *template)
{
- memset(template, 0, sizeof(struct pipe_texture));
+ memset(template, 0, sizeof(struct pipe_resource));
template->target = pt->target;
template->format = pt->format;
template->width0 = width;
@@ -32,49 +34,57 @@ nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
NOUVEAU_TEXTURE_USAGE_LINEAR;
}
-static struct pipe_transfer *
-nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
+struct pipe_transfer *
+nvfx_miptree_transfer_new(struct pipe_context *pcontext,
+ struct pipe_resource *pt,
+ struct pipe_subresource sr,
+ enum pipe_transfer_usage usage,
+ const struct pipe_box *box)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nvfx_transfer *tx;
- struct pipe_texture tx_tex_template, *tx_tex;
+ struct pipe_resource tx_tex_template, *tx_tex;
+ static boolean firsttime = TRUE;
+ static boolean no_transfer = FALSE;
+
+ if (firsttime) {
+ no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER",
+ TRUE/*XXX:FALSE*/);
+ firsttime = FALSE;
+ }
tx = CALLOC_STRUCT(nvfx_transfer);
if (!tx)
return NULL;
- pipe_texture_reference(&tx->base.texture, pt);
- tx->base.x = x;
- tx->base.y = y;
- tx->base.width = w;
- tx->base.height = h;
- tx->base.stride = mt->level[level].pitch;
+ /* Don't handle 3D transfers yet.
+ */
+ assert(box->depth == 1);
+
+ pipe_resource_reference(&tx->base.resource, pt);
+ tx->base.sr = sr;
tx->base.usage = usage;
- tx->base.face = face;
- tx->base.level = level;
- tx->base.zslice = zslice;
+ tx->base.box = *box;
+ tx->base.stride = mt->level[sr.level].pitch;
/* Direct access to texture */
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
- debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) &&
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
{
tx->direct = true;
tx->surface = pscreen->get_tex_surface(pscreen, pt,
- face, level, zslice,
+ sr.face, sr.level,
+ box->z,
pipe_transfer_buffer_flags(&tx->base));
return &tx->base;
}
tx->direct = false;
- nvfx_compatible_transfer_tex(pt, w, h, &tx_tex_template);
+ nvfx_compatible_transfer_tex(pt, box->width, box->height, &tx_tex_template);
- tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
+ tx_tex = pscreen->resource_create(pscreen, &tx_tex_template);
if (!tx_tex)
{
FREE(tx);
@@ -87,7 +97,7 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
0, 0, 0,
pipe_transfer_buffer_flags(&tx->base));
- pipe_texture_reference(&tx_tex, NULL);
+ pipe_resource_reference(&tx_tex, NULL);
if (!tx->surface)
{
@@ -101,15 +111,16 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
struct pipe_surface *src;
src = pscreen->get_tex_surface(pscreen, pt,
- face, level, zslice,
+ sr.face, sr.level, box->z,
PIPE_BUFFER_USAGE_GPU_READ);
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
/* TODO: Check if SIFM can un-swizzle */
nvscreen->eng2d->copy(nvscreen->eng2d,
tx->surface, 0, 0,
- src, x, y,
- w, h);
+ src,
+ box->x, box->y,
+ box->width, box->height);
pipe_surface_reference(&src, NULL);
}
@@ -117,9 +128,9 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
return &tx->base;
}
-static void
-nvfx_transfer_del(struct pipe_context *pcontext,
- struct pipe_transfer *ptx)
+void
+nvfx_miptree_transfer_del(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx)
{
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
@@ -128,62 +139,51 @@ nvfx_transfer_del(struct pipe_context *pcontext,
struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
struct pipe_surface *dst;
- dst = pscreen->get_tex_surface(pscreen, ptx->texture,
- ptx->face, ptx->level, ptx->zslice,
+ dst = pscreen->get_tex_surface(pscreen,
+ ptx->resource,
+ ptx->sr.face,
+ ptx->sr.level,
+ ptx->box.z,
PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
nvscreen->eng2d->copy(nvscreen->eng2d,
- dst, tx->base.x, tx->base.y,
+ dst, ptx->box.x, ptx->box.y,
tx->surface, 0, 0,
- tx->base.width, tx->base.height);
+ ptx->box.width, ptx->box.height);
pipe_surface_reference(&dst, NULL);
}
pipe_surface_reference(&tx->surface, NULL);
- pipe_texture_reference(&ptx->texture, NULL);
+ pipe_resource_reference(&ptx->resource, NULL);
FREE(ptx);
}
-static void *
-nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+void *
+nvfx_miptree_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
- void *map = pipe_buffer_map(pscreen, mt->buffer,
- pipe_transfer_buffer_flags(ptx));
+ uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo,
+ pipe_transfer_buffer_flags(ptx));
if(!tx->direct)
return map + ns->base.offset;
else
- return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
+ return (map + ns->base.offset +
+ ptx->box.y * ns->pitch +
+ ptx->box.x * util_format_get_blocksize(ptx->resource->format));
}
-static void
-nvfx_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+void
+nvfx_miptree_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
- pipe_buffer_unmap(pscreen, mt->buffer);
-}
-
-void
-nvfx_init_transfer_functions(struct nvfx_context *nvfx)
-{
-<<<<<<< HEAD:src/gallium/drivers/nv30/nv30_transfer.c
- nv30->pipe.get_transfer = nv30_transfer_new;
- nv30->pipe.transfer_destroy = nv30_transfer_del;
- nv30->pipe.transfer_map = nv30_transfer_map;
- nv30->pipe.transfer_unmap = nv30_transfer_unmap;
-=======
- nvfx->pipe.get_tex_transfer = nvfx_transfer_new;
- nvfx->pipe.tex_transfer_destroy = nvfx_transfer_del;
- nvfx->pipe.transfer_map = nvfx_transfer_map;
- nvfx->pipe.transfer_unmap = nvfx_transfer_unmap;
->>>>>>> origin/gallium-sampler-view:src/gallium/drivers/nvfx/nvfx_transfer.c
+ nouveau_screen_bo_unmap(pscreen, mt->base.bo);
}
diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.h b/src/gallium/drivers/nvfx/nvfx_transfer.h
new file mode 100644
index 0000000000..b2b920176e
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.h
@@ -0,0 +1,26 @@
+
+#ifndef NVFX_TRANSFER_H
+#define NVFX_TRANSFER_H
+
+#include "util/u_transfer.h"
+#include "pipe/p_state.h"
+
+
+struct pipe_transfer *
+nvfx_miptree_transfer_new(struct pipe_context *pcontext,
+ struct pipe_resource *pt,
+ struct pipe_subresource sr,
+ enum pipe_transfer_usage usage,
+ const struct pipe_box *box);
+void
+nvfx_miptree_transfer_del(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx);
+void *
+nvfx_miptree_transfer_map(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx);
+void
+nvfx_miptree_transfer_unmap(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx);
+
+
+#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index 257087f8f6..887aa1fa96 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -5,6 +5,7 @@
#include "nvfx_context.h"
#include "nvfx_state.h"
+#include "nvfx_resource.h"
#include "nouveau/nouveau_channel.h"
#include "nouveau/nouveau_pushbuf.h"
@@ -76,7 +77,7 @@ nvfx_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
}
static boolean
-nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib,
+nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib,
unsigned ib_size)
{
struct pipe_screen *pscreen = &nvfx->screen->base.base;
@@ -117,21 +118,22 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
int attrib, struct pipe_vertex_element *ve,
struct pipe_vertex_buffer *vb)
{
- struct pipe_screen *pscreen = nvfx->pipe.screen;
+ struct pipe_context *pipe = &nvfx->pipe;
struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+ struct pipe_transfer *transfer;
unsigned type, ncomp;
- void *map;
+ uint8_t *map;
if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp))
return FALSE;
- map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ, &transfer);
map += vb->buffer_offset + ve->src_offset;
switch (type) {
case NV34TCL_VTXFMT_TYPE_FLOAT:
{
- float *v = map;
+ float *v = (float *)map;
switch (ncomp) {
case 4:
@@ -157,17 +159,17 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
so_data (so, fui(v[0]));
break;
default:
- pipe_buffer_unmap(pscreen, vb->buffer);
+ pipe_buffer_unmap(pipe, vb->buffer, transfer);
return FALSE;
}
}
break;
default:
- pipe_buffer_unmap(pscreen, vb->buffer);
+ pipe_buffer_unmap(pipe, vb->buffer, transfer);
return FALSE;
}
- pipe_buffer_unmap(pscreen, vb->buffer);
+ pipe_buffer_unmap(pipe, vb->buffer, transfer);
return TRUE;
}
@@ -379,14 +381,14 @@ nvfx_draw_elements_u32(struct nvfx_context *nvfx, void *ib,
static void
nvfx_draw_elements_inline(struct pipe_context *pipe,
- struct pipe_buffer *ib, unsigned ib_size,
+ struct pipe_resource *ib, unsigned ib_size,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
- struct pipe_screen *pscreen = pipe->screen;
+ struct pipe_transfer *transfer;
void *map;
- map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe, ib, PIPE_BUFFER_USAGE_CPU_READ, &transfer);
if (!ib) {
NOUVEAU_ERR("failed mapping ib\n");
return;
@@ -407,7 +409,7 @@ nvfx_draw_elements_inline(struct pipe_context *pipe,
break;
}
- pipe_buffer_unmap(pscreen, ib);
+ pipe_buffer_unmap(pipe, ib, transfer);
}
static void
@@ -465,7 +467,7 @@ nvfx_draw_elements_vbo(struct pipe_context *pipe,
void
nvfx_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer, unsigned indexSize,
+ struct pipe_resource *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
@@ -493,7 +495,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
{
struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
- struct pipe_buffer *ib = nvfx->idxbuf;
+ struct pipe_resource *ib = nvfx->idxbuf;
unsigned ib_format = nvfx->idxbuf_format;
unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
int hw;
@@ -529,7 +531,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
return FALSE;
}
- so_reloc(vtxbuf, nouveau_bo(vb->buffer),
+ so_reloc(vtxbuf, nvfx_resource(vb->buffer)->bo,
vb->buffer_offset + ve->src_offset,
vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
0, NV34TCL_VTXBUF_ADDRESS_DMA1);
@@ -538,7 +540,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
}
if (ib) {
- struct nouveau_bo *bo = nouveau_bo(ib);
+ struct nouveau_bo *bo = nvfx_resource(ib)->bo;
so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2);
so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
diff --git a/src/gallium/drivers/nvfx/nvfx_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c
index 2d243be16a..c7bc08eb4e 100644
--- a/src/gallium/drivers/nvfx/nvfx_vertprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c
@@ -833,12 +833,13 @@ out_err:
static boolean
nvfx_vertprog_validate(struct nvfx_context *nvfx)
{
- struct pipe_screen *pscreen = nvfx->pipe.screen;
+ struct pipe_context *pipe = &nvfx->pipe;
struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
struct nouveau_grobj *eng3d = screen->eng3d;
struct nvfx_vertex_program *vp;
- struct pipe_buffer *constbuf;
+ struct pipe_resource *constbuf;
+ struct pipe_transfer *transfer;
boolean upload_code = FALSE, upload_data = FALSE;
int i;
@@ -962,8 +963,9 @@ check_gpu_resources:
float *map = NULL;
if (constbuf) {
- map = pipe_buffer_map(pscreen, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pipe, constbuf,
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &transfer);
}
for (i = 0; i < vp->nr_consts; i++) {
@@ -984,7 +986,7 @@ check_gpu_resources:
}
if (constbuf)
- pipe_buffer_unmap(pscreen, constbuf);
+ pipe_buffer_unmap(pipe, constbuf, transfer);
}
/* Upload vtxprog */
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index b35abc007e..445358b303 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -336,7 +336,7 @@ svga_user_buffer_create(struct pipe_screen *screen,
sbuf->b.vtbl = &svga_buffer_vtbl;
sbuf->b.b.screen = screen;
sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
- sbuf->b.b.usage = PIPE_BUFFER_USAGE_CPU_READ | usage;
+ sbuf->b.b.usage = usage;
sbuf->b.b.width0 = bytes;
sbuf->b.b.height0 = 1;
sbuf->b.b.depth0 = 1;