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; |