diff options
author | Keith Whitwell <keithw@vmware.com> | 2010-03-21 16:51:54 +0000 |
---|---|---|
committer | Keith Whitwell <keithw@vmware.com> | 2010-03-21 16:56:24 +0000 |
commit | 961cbcb62232689c959965384c6aa9b8eca697c1 (patch) | |
tree | 057a00f9c737beeeebb83bc168b9ee63abd2f6a3 | |
parent | 18ba74016db13b23282f5033ee37b628a12ee566 (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.
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; |