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.gallium-resources
| @@ -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 | |||
| @@ -5,5 +5,5 @@ include $(TOP)/configs/linux | |||
| CONFIG_NAME = linux-debug | |||
| OPT_FLAGS = -g | |||
| CFLAGS += -pedantic | |||
| #CFLAGS += -pedantic | |||
| DEFINES += -DDEBUG -DDEBUG_MATH | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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" | |||
| @@ -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 \ | |||
| @@ -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; | |||
| } | |||
| @@ -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); | |||
| @@ -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 * | |||
| @@ -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; | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -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); | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -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) { | |||
| @@ -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" | |||
| @@ -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" | |||
| @@ -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, | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| @@ -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 | |||
| @@ -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; | |||
| @@ -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, | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| @@ -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) { | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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 | |||
| @@ -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) | |||
| @@ -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); | |||
| } | |||
| @@ -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 | |||
| @@ -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); | |||
| @@ -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 */ | |||
| @@ -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; | |||