瀏覽代碼

nouveau: convert nvfx and nv50 to pipe_resources

Compile tested only.

This was a deeper change than I was hoping for, due to the
layering of the pipe_texture implementation in each driver on
top of a shared pipe_buffer implementation in the shared code.

Have modified the shared code to act as a set of convenience
routines operating on nouveau_bo objects.

Each driver now uses the u_resource_vtbl technique to split the
implementation of pipe_resources between the existing miptree code
for textures and a new, minimal buffer implementation in each
driver.

Eventually these should be combined, not least because APIs are now
allowing things like binding buffer resources as textures and render
targets.
gallium-resources
Keith Whitwell 15 年之前
父節點
當前提交
961cbcb622
共有 49 個文件被更改,包括 1234 次插入575 次删除
  1. 1
    1
      configs/default
  2. 1
    1
      configs/linux-debug
  3. 4
    2
      src/gallium/drivers/nouveau/Makefile
  4. 0
    41
      src/gallium/drivers/nouveau/nouveau_context.c
  5. 0
    11
      src/gallium/drivers/nouveau/nouveau_context.h
  6. 51
    114
      src/gallium/drivers/nouveau/nouveau_screen.c
  7. 41
    29
      src/gallium/drivers/nouveau/nouveau_screen.h
  8. 3
    3
      src/gallium/drivers/nouveau/nouveau_util.h
  9. 0
    1
      src/gallium/drivers/nouveau/nouveau_winsys.h
  10. 2
    0
      src/gallium/drivers/nv50/Makefile
  11. 147
    0
      src/gallium/drivers/nv50/nv50_buffer.c
  12. 0
    3
      src/gallium/drivers/nv50/nv50_context.c
  13. 4
    33
      src/gallium/drivers/nv50/nv50_context.h
  14. 88
    40
      src/gallium/drivers/nv50/nv50_miptree.c
  15. 7
    4
      src/gallium/drivers/nv50/nv50_program.c
  16. 4
    3
      src/gallium/drivers/nv50/nv50_push.c
  17. 67
    0
      src/gallium/drivers/nv50/nv50_resource.c
  18. 90
    0
      src/gallium/drivers/nv50/nv50_resource.h
  19. 1
    1
      src/gallium/drivers/nv50/nv50_screen.h
  20. 4
    4
      src/gallium/drivers/nv50/nv50_state.c
  21. 3
    2
      src/gallium/drivers/nv50/nv50_state_validate.c
  22. 1
    0
      src/gallium/drivers/nv50/nv50_surface.c
  23. 1
    0
      src/gallium/drivers/nv50/nv50_tex.c
  24. 44
    40
      src/gallium/drivers/nv50/nv50_transfer.c
  25. 31
    0
      src/gallium/drivers/nv50/nv50_transfer.h
  26. 16
    13
      src/gallium/drivers/nv50/nv50_vbo.c
  27. 5
    0
      src/gallium/drivers/nvfx/Makefile
  28. 11
    11
      src/gallium/drivers/nvfx/nv04_surface_2d.c
  29. 1
    1
      src/gallium/drivers/nvfx/nv04_surface_2d.h
  30. 3
    2
      src/gallium/drivers/nvfx/nv30_fragtex.c
  31. 3
    2
      src/gallium/drivers/nvfx/nv40_fragtex.c
  32. 151
    0
      src/gallium/drivers/nvfx/nvfx_buffer.c
  33. 0
    3
      src/gallium/drivers/nvfx/nvfx_context.c
  34. 4
    5
      src/gallium/drivers/nvfx/nvfx_context.h
  35. 17
    11
      src/gallium/drivers/nvfx/nvfx_draw.c
  36. 34
    17
      src/gallium/drivers/nvfx/nvfx_fragprog.c
  37. 111
    59
      src/gallium/drivers/nvfx/nvfx_miptree.c
  38. 67
    0
      src/gallium/drivers/nvfx/nvfx_resource.c
  39. 91
    0
      src/gallium/drivers/nvfx/nvfx_resource.h
  40. 3
    9
      src/gallium/drivers/nvfx/nvfx_screen.c
  41. 1
    0
      src/gallium/drivers/nvfx/nvfx_screen.h
  42. 5
    5
      src/gallium/drivers/nvfx/nvfx_state.c
  43. 4
    16
      src/gallium/drivers/nvfx/nvfx_state.h
  44. 1
    7
      src/gallium/drivers/nvfx/nvfx_state_fb.c
  45. 59
    59
      src/gallium/drivers/nvfx/nvfx_transfer.c
  46. 26
    0
      src/gallium/drivers/nvfx/nvfx_transfer.h
  47. 18
    16
      src/gallium/drivers/nvfx/nvfx_vbo.c
  48. 7
    5
      src/gallium/drivers/nvfx/nvfx_vertprog.c
  49. 1
    1
      src/gallium/drivers/svga/svga_resource_buffer.c

+ 1
- 1
configs/default 查看文件

@@ -98,7 +98,7 @@ EGL_DRIVERS_DIRS = glx
# Gallium directories and
GALLIUM_DIRS = auxiliary drivers state_trackers
GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a
GALLIUM_DRIVERS_DIRS = softpipe trace identity i915 i965 svga r300
GALLIUM_DRIVERS_DIRS = softpipe trace identity i915 i965 svga r300 nvfx nv50
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
GALLIUM_WINSYS_DIRS = null xlib drm
GALLIUM_TARGET_DIRS = libgl-xlib

+ 1
- 1
configs/linux-debug 查看文件

@@ -5,5 +5,5 @@ include $(TOP)/configs/linux
CONFIG_NAME = linux-debug

OPT_FLAGS = -g
CFLAGS += -pedantic
#CFLAGS += -pedantic
DEFINES += -DDEBUG -DDEBUG_MATH

+ 4
- 2
src/gallium/drivers/nouveau/Makefile 查看文件

@@ -3,7 +3,9 @@ include $(TOP)/configs/current

LIBNAME = nouveau

C_SOURCES = nouveau_screen.c \
nouveau_context.c
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/nouveau/include

C_SOURCES = nouveau_screen.c

include ../../Makefile.template

+ 0
- 41
src/gallium/drivers/nouveau/nouveau_context.c 查看文件

@@ -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);
}


+ 0
- 11
src/gallium/drivers/nouveau/nouveau_context.h 查看文件

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

+ 51
- 114
src/gallium/drivers/nouveau/nouveau_screen.c 查看文件

@@ -32,28 +32,9 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen)
return "nouveau";
}

static struct pipe_buffer *
nouveau_screen_bo_skel(struct pipe_screen *pscreen, struct nouveau_bo *bo,
unsigned alignment, unsigned usage, unsigned size)
{
struct pipe_buffer *pb;

pb = CALLOC(1, sizeof(struct pipe_buffer)+sizeof(struct nouveau_bo *));
if (!pb) {
nouveau_bo_ref(NULL, &bo);
return NULL;
}

pipe_reference_init(&pb->reference, 1);
pb->screen = pscreen;
pb->alignment = alignment;
pb->usage = usage;
pb->size = size;
*(struct nouveau_bo **)(pb + 1) = bo;
return pb;
}

static struct pipe_buffer *
struct nouveau_bo *
nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
unsigned usage, unsigned size)
{
@@ -93,10 +74,10 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
if (ret)
return NULL;

return nouveau_screen_bo_skel(pscreen, bo, alignment, usage, size);
return bo;
}

static struct pipe_buffer *
struct nouveau_bo *
nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
@@ -107,7 +88,7 @@ nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
if (ret)
return NULL;

return nouveau_screen_bo_skel(pscreen, bo, 0, 0, bytes);
return bo;
}

static inline uint32_t
@@ -130,23 +111,14 @@ nouveau_screen_map_flags(unsigned pipe)
return flags;
}

static void *
nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
void *
nouveau_screen_bo_map(struct pipe_screen *pscreen,
struct nouveau_bo *pb,
unsigned usage)
{
struct nouveau_bo *bo = nouveau_bo(pb);
struct nouveau_screen *nscreen = nouveau_screen(pscreen);
int ret;

if (nscreen->pre_pipebuffer_map_callback) {
ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
if (ret) {
debug_printf("pre_pipebuffer_map_callback failed %d\n",
ret);
return NULL;
}
}

ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage));
if (ret) {
debug_printf("map failed: %d\n", ret);
@@ -156,24 +128,14 @@ nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
return bo->map;
}

static void *
nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
void *
nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
unsigned offset, unsigned length, unsigned usage)
{
struct nouveau_bo *bo = nouveau_bo(pb);
struct nouveau_screen *nscreen = nouveau_screen(pscreen);
uint32_t flags = nouveau_screen_map_flags(usage);
int ret;

if (nscreen->pre_pipebuffer_map_callback) {
ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
if (ret) {
debug_printf("pre_pipebuffer_map_callback failed %d\n",
ret);
return NULL;
}
}

ret = nouveau_bo_map_range(bo, offset, length, flags);
if (ret) {
nouveau_bo_unmap(bo);
@@ -185,30 +147,23 @@ nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
return (char *)bo->map - offset; /* why gallium? why? */
}

static void
nouveau_screen_bo_map_flush(struct pipe_screen *pscreen, struct pipe_buffer *pb,
unsigned offset, unsigned length)
void
nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
unsigned offset, unsigned length)
{
struct nouveau_bo *bo = nouveau_bo(pb);

nouveau_bo_map_flush(bo, offset, length);
}

static void
nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct pipe_buffer *pb)
void
nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo)
{
struct nouveau_bo *bo = nouveau_bo(pb);

nouveau_bo_unmap(bo);
}

static void
nouveau_screen_bo_del(struct pipe_buffer *pb)
void
nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo)
{
struct nouveau_bo *bo = nouveau_bo(pb);

nouveau_bo_ref(NULL, &bo);
FREE(pb);
}

static void
@@ -236,59 +191,32 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
}


/*
* Both texture_{from|get}_handle use drm api defines directly which they
* shouldn't do. The problem is that from|get are pipe functions and as
* such they should be defined in the pipe level. If nouveau had a propper
* winsys interface we would have added from|get to that interface using
* the winsys_handle struct as done with other drivers. However this code
* calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
* we need to translate the handle into something they understand.
*/
static struct pipe_texture *
nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
const struct pipe_texture *templ,
struct winsys_handle *whandle)
struct nouveau_bo *
nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *whandle,
unsigned *out_stride)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct pipe_texture *pt;
struct pipe_buffer *pb;
int ret;

pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
if (!pb)
return NULL;

ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
struct nouveau_bo *bo;
ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo);
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
__func__, whandle->handle, ret);
FREE(pb);
return NULL;
}

pipe_reference_init(&pb->reference, 1);
pb->screen = pscreen;
pb->alignment = 0;
pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE;
pb->size = nouveau_bo(pb)->size;
pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ,
&whandle->stride, pb);
pipe_buffer_reference(&pb, NULL);
return pt;
*out_stride = whandle->stride;
return bo;
}

static boolean
nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
struct pipe_texture *pt,
struct winsys_handle *whandle)
{
struct nouveau_miptree *mt = nouveau_miptree(pt);

if (!mt || !mt->bo)
return false;

boolean
nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
struct nouveau_bo *bo,
unsigned stride,
struct winsys_handle *whandle)
{
whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);

if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
@@ -301,6 +229,26 @@ nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
}
}


unsigned int
nouveau_reference_flags(struct nouveau_bo *bo)
{
uint32_t bo_flags;
int flags = 0;

bo_flags = nouveau_bo_pending(bo);
if (bo_flags & NOUVEAU_BO_RD)
flags |= PIPE_REFERENCED_FOR_READ;
if (bo_flags & NOUVEAU_BO_WR)
flags |= PIPE_REFERENCED_FOR_WRITE;

return flags;
}





int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@@ -316,21 +264,10 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
pscreen->get_name = nouveau_screen_get_name;
pscreen->get_vendor = nouveau_screen_get_vendor;

pscreen->buffer_create = nouveau_screen_bo_new;
pscreen->user_buffer_create = nouveau_screen_bo_user;
pscreen->buffer_map = nouveau_screen_bo_map;
pscreen->buffer_map_range = nouveau_screen_bo_map_range;
pscreen->buffer_flush_mapped_range = nouveau_screen_bo_map_flush;
pscreen->buffer_unmap = nouveau_screen_bo_unmap;
pscreen->buffer_destroy = nouveau_screen_bo_del;

pscreen->fence_reference = nouveau_screen_fence_ref;
pscreen->fence_signalled = nouveau_screen_fence_signalled;
pscreen->fence_finish = nouveau_screen_fence_finish;

pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
pscreen->texture_get_handle = nouveau_screen_texture_get_handle;

return 0;
}


+ 41
- 29
src/gallium/drivers/nouveau/nouveau_screen.h 查看文件

@@ -5,21 +5,6 @@ struct nouveau_screen {
struct pipe_screen base;
struct nouveau_device *device;
struct nouveau_channel *channel;

/**
* Create a new texture object, using the given template info, but on top of
* existing memory.
*
* It is assumed that the buffer data is layed out according to the expected
* by the hardware. NULL will be returned if any inconsistency is found.
*/
struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
const struct pipe_texture *templat,
const unsigned *stride,
struct pipe_buffer *buffer);

int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen,
struct pipe_buffer *pb, unsigned usage);
};

static inline struct nouveau_screen *
@@ -28,24 +13,51 @@ nouveau_screen(struct pipe_screen *pscreen)
return (struct nouveau_screen *)pscreen;
}

static inline struct nouveau_bo *
nouveau_bo(struct pipe_buffer *pb)
{
return pb ? *(struct nouveau_bo **)(pb + 1) : NULL;
}


/* Not really sure if this is needed, or whether the individual
* drivers are happy to talk to the bo functions themselves. In a way
* this is what we'd expect from a regular winsys interface.
*/
struct nouveau_bo *
nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
unsigned usage, unsigned size);
struct nouveau_bo *
nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes);
void *
nouveau_screen_bo_map(struct pipe_screen *pscreen,
struct nouveau_bo *pb,
unsigned usage);
void *
nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
unsigned offset, unsigned length, unsigned usage);
void
nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
unsigned offset, unsigned length);
void
nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo);
void
nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo);

boolean
nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
struct nouveau_bo *bo,
unsigned stride,
struct winsys_handle *whandle);
struct nouveau_bo *
nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *whandle,
unsigned *out_stride);

unsigned int
nouveau_reference_flags(struct nouveau_bo *bo);



int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
void nouveau_screen_fini(struct nouveau_screen *);

struct nouveau_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
};

static inline struct nouveau_miptree *
nouveau_miptree(struct pipe_texture *pt)
{
return (struct nouveau_miptree *)pt;
}


#endif

+ 3
- 3
src/gallium/drivers/nouveau/nouveau_util.h 查看文件

@@ -98,9 +98,9 @@ struct u_split_prim {
unsigned p_start;
unsigned p_end;

int repeat_first:1;
int close_first:1;
int edgeflag_off:1;
uint repeat_first:1;
uint close_first:1;
uint edgeflag_off:1;
};

static inline void

+ 0
- 1
src/gallium/drivers/nouveau/nouveau_winsys.h 查看文件

@@ -2,7 +2,6 @@
#define NOUVEAU_WINSYS_H

#include <stdint.h>
#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"

#include "nouveau/nouveau_bo.h"

+ 2
- 0
src/gallium/drivers/nv50/Makefile 查看文件

@@ -4,12 +4,14 @@ include $(TOP)/configs/current
LIBNAME = nv50

C_SOURCES = \
nv50_buffer.c \
nv50_clear.c \
nv50_context.c \
nv50_draw.c \
nv50_miptree.c \
nv50_query.c \
nv50_program.c \
nv50_resource.c \
nv50_screen.c \
nv50_state.c \
nv50_state_validate.c \

+ 147
- 0
src/gallium/drivers/nv50/nv50_buffer.c 查看文件

@@ -0,0 +1,147 @@

#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_math.h"

#include "nouveau/nouveau_screen.h"
#include "nv50_resource.h"



static void nv50_buffer_destroy(struct pipe_screen *pscreen,
struct pipe_resource *presource)
{
struct nv50_resource *buffer = nv50_resource(presource);

nouveau_screen_bo_release(pscreen, buffer->bo);
FREE(buffer);
}




/* Utility functions for transfer create/destroy are hooked in and
* just record the arguments to those functions.
*/
static void *
nv50_buffer_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct nv50_resource *buffer = nv50_resource(transfer->resource);
uint8_t *map;

map = nouveau_screen_bo_map_range( pipe->screen,
buffer->bo,
transfer->box.x,
transfer->box.width,
transfer->usage );
if (map == NULL)
return NULL;
return map + transfer->box.x;
}



static void nv50_buffer_transfer_flush_region( struct pipe_context *pipe,
struct pipe_transfer *transfer,
const struct pipe_box *box)
{
struct nv50_resource *buffer = nv50_resource(transfer->resource);

nouveau_screen_bo_map_flush_range(pipe->screen,
buffer->bo,
transfer->box.x + box->x,
box->width);
}

static void nv50_buffer_transfer_unmap( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct nv50_resource *buffer = nv50_resource(transfer->resource);

nouveau_screen_bo_unmap(pipe->screen, buffer->bo);
}




struct u_resource_vtbl nv50_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
nv50_buffer_destroy, /* resource_destroy */
NULL, /* is_resource_referenced */
u_default_get_transfer, /* get_transfer */
u_default_transfer_destroy, /* transfer_destroy */
nv50_buffer_transfer_map, /* transfer_map */
nv50_buffer_transfer_flush_region, /* transfer_flush_region */
nv50_buffer_transfer_unmap, /* transfer_unmap */
u_default_transfer_inline_write /* transfer_inline_write */
};




struct pipe_resource *
nv50_buffer_create(struct pipe_screen *pscreen,
const struct pipe_resource *template)
{
struct nv50_resource *buffer;

buffer = CALLOC_STRUCT(nv50_resource);
if (!buffer)
return NULL;

buffer->base = *template;
buffer->vtbl = &nv50_buffer_vtbl;
pipe_reference_init(&buffer->base.reference, 1);
buffer->base.screen = pscreen;

buffer->bo = nouveau_screen_bo_new(pscreen,
16,
buffer->base.usage,
buffer->base.width0);

if (buffer->bo == NULL)
goto fail;

return &buffer->base;

fail:
FREE(buffer);
return NULL;
}


struct pipe_resource *
nv50_user_buffer_create(struct pipe_screen *pscreen,
void *ptr,
unsigned bytes,
unsigned usage)
{
struct nv50_resource *buffer;

buffer = CALLOC_STRUCT(nv50_resource);
if (!buffer)
return NULL;

pipe_reference_init(&buffer->base.reference, 1);
buffer->vtbl = &nv50_buffer_vtbl;
buffer->base.screen = pscreen;
buffer->base.format = PIPE_FORMAT_R8_UNORM;
buffer->base.usage = usage;
buffer->base.width0 = bytes;
buffer->base.height0 = 1;
buffer->base.depth0 = 1;

buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
if (!buffer->bo)
goto fail;
return &buffer->base;

fail:
FREE(buffer);
return NULL;
}


+ 0
- 3
src/gallium/drivers/nv50/nv50_context.c 查看文件

@@ -89,9 +89,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv)

nv50->pipe.flush = nv50_flush;

nv50->pipe.is_texture_referenced = nouveau_is_texture_referenced;
nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;

screen->base.channel->user_private = nv50;

nv50_init_surface_functions(nv50);

+ 4
- 33
src/gallium/drivers/nv50/nv50_context.h 查看文件

@@ -16,7 +16,6 @@
#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_gldefs.h"
#include "nouveau/nouveau_stateobj.h"
#include "nouveau/nouveau_context.h"

#include "nv50_screen.h"
#include "nv50_program.h"
@@ -101,27 +100,6 @@ get_tile_depth(uint32_t tile_mode)
return 1 << (tile_mode >> 4);
}

struct nv50_miptree_level {
int *image_offset;
unsigned pitch;
unsigned tile_mode;
};

#define NV50_MAX_TEXTURE_LEVELS 16

struct nv50_miptree {
struct nouveau_miptree base;

struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};

static INLINE struct nv50_miptree *
nv50_miptree(struct pipe_texture *pt)
{
return (struct nv50_miptree *)pt;
}

struct nv50_surface {
struct pipe_surface base;
@@ -165,7 +143,7 @@ struct nv50_context {
struct nv50_program *vertprog;
struct nv50_program *fragprog;
struct nv50_program *geomprog;
struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
struct nv50_vtxelt_stateobj *vtxelt;
@@ -206,12 +184,12 @@ extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode,
unsigned startInstance,
unsigned instanceCount);
extern void nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count);
extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count,
@@ -222,7 +200,7 @@ extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);

/* nv50_push.c */
extern void
nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *,
nv50_push_elements_instanced(struct pipe_context *, struct pipe_resource *,
unsigned idxsize, unsigned mode, unsigned start,
unsigned count, unsigned i_start,
unsigned i_count);
@@ -258,13 +236,6 @@ extern boolean nv50_tex_construct(struct nv50_sampler_view *view);
extern void nv50_tex_relocs(struct nv50_context *);
extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);

/* nv50_transfer.c */
extern void
nv50_upload_sifc(struct nv50_context *nv50,
struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc,
unsigned dst_format, int dst_w, int dst_h, int dst_pitch,
void *src, unsigned src_format, int src_pitch,
int x, int y, int w, int h, int cpp);

/* nv50_context.c */
struct pipe_context *

+ 88
- 40
src/gallium/drivers/nv50/nv50_miptree.c 查看文件

@@ -26,6 +26,8 @@
#include "util/u_format.h"

#include "nv50_context.h"
#include "nv50_resource.h"
#include "nv50_transfer.h"

/* The restrictions in tile mode selection probably aren't necessary. */
static INLINE uint32_t
@@ -70,12 +72,66 @@ get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h)
return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d;
}

static struct pipe_texture *
nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)



static void
nv50_miptree_destroy(struct pipe_screen *pscreen,
struct pipe_resource *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
unsigned l;

for (l = 0; l <= pt->last_level; ++l)
FREE(mt->level[l].image_offset);

nouveau_screen_bo_release(pscreen, mt->base.bo);
FREE(mt);
}

static boolean
nv50_miptree_get_handle(struct pipe_screen *pscreen,
struct pipe_resource *pt,
struct winsys_handle *whandle)
{
struct nv50_miptree *mt = nv50_miptree(pt);
unsigned stride;


if (!mt || !mt->base.bo)
return FALSE;

stride = util_format_get_stride(mt->base.base.format,
mt->base.base.width0);

return nouveau_screen_bo_get_handle(pscreen,
mt->base.bo,
stride,
whandle);
}


struct u_resource_vtbl nv50_miptree_vtbl =
{
nv50_miptree_get_handle, /* get_handle */
nv50_miptree_destroy, /* resource_destroy */
NULL, /* is_resource_referenced */
nv50_miptree_transfer_new, /* get_transfer */
nv50_miptree_transfer_del, /* transfer_destroy */
nv50_miptree_transfer_map, /* transfer_map */
u_default_transfer_flush_region, /* transfer_flush_region */
nv50_miptree_transfer_unmap, /* transfer_unmap */
u_default_transfer_inline_write /* transfer_inline_write */
};



struct pipe_resource *
nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *tmp)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
struct pipe_texture *pt = &mt->base.base;
struct pipe_resource *pt = &mt->base.base;
unsigned width = tmp->width0, height = tmp->height0;
unsigned depth = tmp->depth0, image_alignment;
uint32_t tile_flags;
@@ -165,49 +221,53 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
return pt;
}

static struct pipe_texture *
nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
const unsigned *stride, struct pipe_buffer *pb)

struct pipe_resource *
nv50_miptree_from_handle(struct pipe_screen *pscreen,
const struct pipe_resource *template,
struct winsys_handle *whandle)
{
struct nouveau_bo *bo = nouveau_bo(pb);
struct nv50_miptree *mt;
unsigned stride;

/* Only supports 2D, non-mipmapped textures for the moment */
if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
pt->depth0 != 1)
if (template->target != PIPE_TEXTURE_2D ||
template->last_level != 0 ||
template->depth0 != 1)
return NULL;

mt = CALLOC_STRUCT(nv50_miptree);
if (!mt)
return NULL;

mt->base.base = *pt;
mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
if (mt->base.bo == NULL) {
FREE(mt);
return NULL;
}


mt->base.base = *template;
pipe_reference_init(&mt->base.base.reference, 1);
mt->base.base.screen = pscreen;
mt->image_nr = 1;
mt->level[0].pitch = *stride;
mt->level[0].pitch = stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
mt->level[0].tile_mode = bo->tile_mode;
mt->level[0].tile_mode = mt->base.bo->tile_mode;

nouveau_bo_ref(bo, &mt->base.bo);
/* XXX: Need to adjust bo refcount??
*/
/* nouveau_bo_ref(bo, &mt->base.bo); */
return &mt->base.base;
}

static void
nv50_miptree_destroy(struct pipe_texture *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
unsigned l;

for (l = 0; l <= pt->last_level; ++l)
FREE(mt->level[l].image_offset);

nouveau_bo_ref(NULL, &mt->base.bo);
FREE(mt);
}
/* Surface functions
*/

static struct pipe_surface *
nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
struct pipe_surface *
nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
@@ -222,7 +282,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ps = CALLOC_STRUCT(pipe_surface);
if (!ps)
return NULL;
pipe_texture_reference(&ps->texture, pt);
pipe_resource_reference(&ps->texture, pt);
ps->format = pt->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
@@ -242,23 +302,11 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
return ps;
}

static void
void
nv50_miptree_surface_del(struct pipe_surface *ps)
{
struct nv50_surface *s = nv50_surface(ps);

pipe_texture_reference(&ps->texture, NULL);
pipe_resource_reference(&ps->texture, NULL);
FREE(s);
}

void
nv50_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv50_miptree_create;
pscreen->texture_destroy = nv50_miptree_destroy;
pscreen->get_tex_surface = nv50_miptree_surface_new;
pscreen->tex_surface_destroy = nv50_miptree_surface_del;

nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket;
}


+ 7
- 4
src/gallium/drivers/nv50/nv50_program.c 查看文件

@@ -4157,7 +4157,8 @@ nv50_program_upload_data(struct nv50_context *nv50, uint32_t *map,
static void
nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
{
struct pipe_screen *pscreen = nv50->pipe.screen;
struct pipe_context *pipe = &nv50->pipe;
struct pipe_transfer *transfer;

if (!p->data[0] && p->immd_nr) {
struct nouveau_resource *heap = nv50->screen->immd_heap[0];
@@ -4182,9 +4183,10 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)

if (p->param_nr) {
unsigned cb;
uint32_t *map = pipe_buffer_map(pscreen,
uint32_t *map = pipe_buffer_map(pipe,
nv50->constbuf[p->type],
PIPE_BUFFER_USAGE_CPU_READ);
PIPE_TRANSFER_READ,
&transfer);
switch (p->type) {
case PIPE_SHADER_GEOMETRY: cb = NV50_CB_PGP; break;
case PIPE_SHADER_FRAGMENT: cb = NV50_CB_PFP; break;
@@ -4195,7 +4197,8 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
}

nv50_program_upload_data(nv50, map, 0, p->param_nr, cb);
pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]);
pipe_buffer_unmap(pipe, nv50->constbuf[p->type],
transfer);
}
}


+ 4
- 3
src/gallium/drivers/nv50/nv50_push.c 查看文件

@@ -5,6 +5,7 @@

#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
#include "nv50_resource.h"

struct push_context {
struct nv50_context *nv50;
@@ -171,7 +172,7 @@ emit_verts(void *priv, unsigned start, unsigned count)

void
nv50_push_elements_instanced(struct pipe_context *pipe,
struct pipe_buffer *idxbuf, unsigned idxsize,
struct pipe_resource *idxbuf, unsigned idxsize,
unsigned mode, unsigned start, unsigned count,
unsigned i_start, unsigned i_count)
{
@@ -199,7 +200,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe,
for (i = 0; i < nv50->vtxelt->num_elements; i++) {
struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
unsigned size, nr_components, n;

if (!(nv50->vbo_fifo & (1 << i)))
@@ -260,7 +261,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe,

/* map index buffer, if present */
if (idxbuf) {
struct nouveau_bo *bo = nouveau_bo(idxbuf);
struct nouveau_bo *bo = nv50_resource(idxbuf)->bo;

if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
assert(bo->map);

+ 67
- 0
src/gallium/drivers/nv50/nv50_resource.c 查看文件

@@ -0,0 +1,67 @@

#include "pipe/p_context.h"
#include "nv50_resource.h"
#include "nouveau/nouveau_screen.h"


/* This doesn't look quite right - this query is supposed to ask
* whether the particular context has references to the resource in
* any unflushed rendering command buffer, and hence requires a
* pipe->flush() for serializing some modification to that resource.
*
* This seems to be answering the question of whether the resource is
* currently on hardware.
*/
static unsigned int
nv50_resource_is_referenced(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned face, unsigned level)
{
return nouveau_reference_flags(nv50_resource(resource)->bo);
}

static struct pipe_resource *
nv50_resource_create(struct pipe_screen *screen,
const struct pipe_resource *template)
{
if (template->target == PIPE_BUFFER)
return nv50_buffer_create(screen, template);
else
return nv50_miptree_create(screen, template);
}

static struct pipe_resource *
nv50_resource_from_handle(struct pipe_screen * screen,
const struct pipe_resource *template,
struct winsys_handle *whandle)
{
if (template->target == PIPE_BUFFER)
return NULL;
else
return nv50_miptree_from_handle(screen, template, whandle);
}

void
nv50_init_resource_functions(struct pipe_context *pcontext)
{
pcontext->get_transfer = u_get_transfer_vtbl;
pcontext->transfer_map = u_transfer_map_vtbl;
pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
pcontext->transfer_unmap = u_transfer_unmap_vtbl;
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
pcontext->is_resource_referenced = nv50_resource_is_referenced;
}

void
nv50_screen_init_resource_functions(struct pipe_screen *pscreen)
{
pscreen->resource_create = nv50_resource_create;
pscreen->resource_from_handle = nv50_resource_from_handle;
pscreen->resource_get_handle = u_resource_get_handle_vtbl;
pscreen->resource_destroy = u_resource_destroy_vtbl;
pscreen->user_buffer_create = nv50_user_buffer_create;
pscreen->get_tex_surface = nv50_miptree_surface_new;
pscreen->tex_surface_destroy = nv50_miptree_surface_del;
}

+ 90
- 0
src/gallium/drivers/nv50/nv50_resource.h 查看文件

@@ -0,0 +1,90 @@

#ifndef NV50_RESOURCE_H
#define NV50_RESOURCE_H

#include "util/u_transfer.h"

struct pipe_resource;
struct nouveau_bo;


/* This gets further specialized into either buffer or texture
* structures. In the future we'll want to remove much of that
* distinction, but for now try to keep as close to the existing code
* as possible and use the vtbl struct to choose between the two
* underlying implementations.
*/
struct nv50_resource {
struct pipe_resource base;
struct u_resource_vtbl *vtbl;
struct nouveau_bo *bo;
};

struct nv50_miptree_level {
int *image_offset;
unsigned pitch;
unsigned tile_mode;
};

#define NV50_MAX_TEXTURE_LEVELS 16

struct nv50_miptree {
struct nv50_resource base;

struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};

static INLINE struct nv50_miptree *
nv50_miptree(struct pipe_resource *pt)
{
return (struct nv50_miptree *)pt;
}


static INLINE
struct nv50_resource *nv50_resource(struct pipe_resource *resource)
{
return (struct nv50_resource *)resource;
}


void
nv50_init_resource_functions(struct pipe_context *pcontext);

void
nv50_screen_init_resource_functions(struct pipe_screen *pscreen);

/* Internal functions
*/
struct pipe_resource *
nv50_miptree_create(struct pipe_screen *pscreen,
const struct pipe_resource *tmp);

struct pipe_resource *
nv50_miptree_from_handle(struct pipe_screen *pscreen,
const struct pipe_resource *template,
struct winsys_handle *whandle);

struct pipe_resource *
nv50_buffer_create(struct pipe_screen *pscreen,
const struct pipe_resource *template);

struct pipe_resource *
nv50_user_buffer_create(struct pipe_screen *screen,
void *ptr,
unsigned bytes,
unsigned usage);


struct pipe_surface *
nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags);

void
nv50_miptree_surface_del(struct pipe_surface *ps);


#endif

+ 1
- 1
src/gallium/drivers/nv50/nv50_screen.h 查看文件

@@ -22,7 +22,7 @@ struct nv50_screen {
struct nouveau_resource *immd_heap[1];
struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES];

struct pipe_buffer *strm_vbuf[16];
struct pipe_resource *strm_vbuf[16];

struct nouveau_bo *tic;
struct nouveau_bo *tsc;

+ 4
- 4
src/gallium/drivers/nv50/nv50_state.c 查看文件

@@ -310,13 +310,13 @@ static void
nv50_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
pipe_texture_reference(&view->texture, NULL);
pipe_resource_reference(&view->texture, NULL);
FREE(nv50_sampler_view(view));
}

static struct pipe_sampler_view *
nv50_create_sampler_view(struct pipe_context *pipe,
struct pipe_texture *texture,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view);
@@ -324,7 +324,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
view->pipe = *templ;
view->pipe.reference.count = 1;
view->pipe.texture = NULL;
pipe_texture_reference(&view->pipe.texture, texture);
pipe_resource_reference(&view->pipe.texture, texture);
view->pipe.context = pipe;

if (!nv50_tex_construct(view)) {
@@ -690,7 +690,7 @@ nv50_set_clip_state(struct pipe_context *pipe,

static void
nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
struct pipe_buffer *buf )
struct pipe_resource *buf )
{
struct nv50_context *nv50 = nv50_context(pipe);


+ 3
- 2
src/gallium/drivers/nv50/nv50_state_validate.c 查看文件

@@ -23,6 +23,7 @@
#include "util/u_format.h"

#include "nv50_context.h"
#include "nv50_resource.h"
#include "nouveau/nouveau_stateobj.h"

static struct nouveau_stateobj *
@@ -43,7 +44,7 @@ validate_fb(struct nv50_context *nv50)
(4 << 16) | (5 << 19) | (6 << 22) | (7 << 25));

for (i = 0; i < fb->nr_cbufs; i++) {
struct pipe_texture *pt = fb->cbufs[i]->texture;
struct pipe_resource *pt = fb->cbufs[i]->texture;
struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;

if (!gw) {
@@ -104,7 +105,7 @@ validate_fb(struct nv50_context *nv50)
}

if (fb->zsbuf) {
struct pipe_texture *pt = fb->zsbuf->texture;
struct pipe_resource *pt = fb->zsbuf->texture;
struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;

if (!gw) {

+ 1
- 0
src/gallium/drivers/nv50/nv50_surface.c 查看文件

@@ -24,6 +24,7 @@
#include <stdint.h>
#include "nouveau/nouveau_pushbuf.h"
#include "nv50_context.h"
#include "nv50_resource.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"


+ 1
- 0
src/gallium/drivers/nv50/nv50_tex.c 查看文件

@@ -22,6 +22,7 @@

#include "nv50_context.h"
#include "nv50_texture.h"
#include "nv50_resource.h"

#include "nouveau/nouveau_stateobj.h"
#include "nouveau/nouveau_reloc.h"

+ 44
- 40
src/gallium/drivers/nv50/nv50_transfer.c 查看文件

@@ -5,6 +5,8 @@
#include "util/u_math.h"

#include "nv50_context.h"
#include "nv50_transfer.h"
#include "nv50_resource.h"

struct nv50_transfer {
struct pipe_transfer base;
@@ -120,44 +122,51 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
}
}

static struct pipe_transfer *
nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
struct pipe_transfer *
nv50_miptree_transfer_new(struct pipe_context *pcontext,
struct pipe_resource *pt,
struct pipe_subresource sr,
enum pipe_transfer_usage usage,
const struct pipe_box *box)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = nv50_miptree(pt);
struct nv50_miptree_level *lvl = &mt->level[level];
struct nv50_miptree_level *lvl = &mt->level[sr.level];
struct nv50_transfer *tx;
unsigned nx, ny, image = 0;
int ret;

if (pt->target == PIPE_TEXTURE_CUBE)
image = face;
image = sr.face;

tx = CALLOC_STRUCT(nv50_transfer);
if (!tx)
return NULL;

pipe_texture_reference(&tx->base.texture, pt);
tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level));
tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level));
tx->base.width = w;
tx->base.height = h;
/* Don't handle 3D transfers yet.
*/
assert(box->depth == 1);


pipe_resource_reference(&tx->base.resource, pt);
tx->base.sr = sr;
tx->base.usage = usage;
tx->base.box = *box;
tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, sr.level));
tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, sr.level));
tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format);
tx->base.usage = usage;

tx->level_pitch = lvl->pitch;
tx->level_width = u_minify(mt->base.base.width0, level);
tx->level_height = u_minify(mt->base.base.height0, level);
tx->level_depth = u_minify(mt->base.base.depth0, level);
tx->level_width = u_minify(mt->base.base.width0, sr.level);
tx->level_height = u_minify(mt->base.base.height0, sr.level);
tx->level_depth = u_minify(mt->base.base.depth0, sr.level);
tx->level_offset = lvl->image_offset[image];
tx->level_tiling = lvl->tile_mode;
tx->level_z = zslice;
tx->level_x = util_format_get_nblocksx(pt->format, x);
tx->level_y = util_format_get_nblocksy(pt->format, y);
tx->level_z = box->z;
tx->level_x = util_format_get_nblocksx(pt->format, box->x);
tx->level_y = util_format_get_nblocksy(pt->format, box->y);
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
tx->nblocksy * tx->base.stride, &tx->bo);
if (ret) {
@@ -166,12 +175,12 @@ nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
}

if (usage & PIPE_TRANSFER_READ) {
nx = util_format_get_nblocksx(pt->format, tx->base.width);
ny = util_format_get_nblocksy(pt->format, tx->base.height);
nx = util_format_get_nblocksx(pt->format, box->width);
ny = util_format_get_nblocksy(pt->format, box->height);

nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
tx->level_pitch, tx->level_tiling,
x, y, zslice,
box->x, box->y, box->z,
tx->nblocksx, tx->nblocksy,
tx->level_depth,
tx->bo, 0,
@@ -186,15 +195,16 @@ nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
return &tx->base;
}

static void
nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
void
nv50_miptree_transfer_del(struct pipe_context *pcontext,
struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
struct nv50_miptree *mt = nv50_miptree(ptx->texture);
struct pipe_texture *pt = ptx->texture;
struct nv50_miptree *mt = nv50_miptree(ptx->resource);
struct pipe_resource *pt = ptx->resource;

unsigned nx = util_format_get_nblocksx(pt->format, tx->base.width);
unsigned ny = util_format_get_nblocksy(pt->format, tx->base.height);
unsigned nx = util_format_get_nblocksx(pt->format, tx->base.box.width);
unsigned ny = util_format_get_nblocksy(pt->format, tx->base.box.height);

if (ptx->usage & PIPE_TRANSFER_WRITE) {
struct pipe_screen *pscreen = pcontext->screen;
@@ -214,12 +224,13 @@ nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
}

nouveau_bo_ref(NULL, &tx->bo);
pipe_texture_reference(&ptx->texture, NULL);
pipe_resource_reference(&ptx->resource, NULL);
FREE(ptx);
}

static void *
nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
void *
nv50_miptree_transfer_map(struct pipe_context *pcontext,
struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
unsigned flags = 0;
@@ -236,22 +247,15 @@ nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
return tx->bo->map;
}

static void
nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
void
nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;

nouveau_bo_unmap(tx->bo);
}

void
nv50_init_transfer_functions(struct nv50_context *nv50)
{
nv50->pipe.get_transfer = nv50_transfer_new;
nv50->pipe.transfer_destroy = nv50_transfer_del;
nv50->pipe.transfer_map = nv50_transfer_map;
nv50->pipe.transfer_unmap = nv50_transfer_unmap;
}

void
nv50_upload_sifc(struct nv50_context *nv50,

+ 31
- 0
src/gallium/drivers/nv50/nv50_transfer.h 查看文件

@@ -0,0 +1,31 @@

#ifndef NV50_TRANSFER_H
#define NV50_TRANSFER_H

#include "pipe/p_state.h"


struct pipe_transfer *
nv50_miptree_transfer_new(struct pipe_context *pcontext,
struct pipe_resource *pt,
struct pipe_subresource sr,
enum pipe_transfer_usage usage,
const struct pipe_box *box);
void
nv50_miptree_transfer_del(struct pipe_context *pcontext,
struct pipe_transfer *ptx);
void *
nv50_miptree_transfer_map(struct pipe_context *pcontext,
struct pipe_transfer *ptx);
void
nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
struct pipe_transfer *ptx);

extern void
nv50_upload_sifc(struct nv50_context *nv50,
struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc,
unsigned dst_format, int dst_w, int dst_h, int dst_pitch,
void *src, unsigned src_format, int src_pitch,
int x, int y, int w, int h, int cpp);

#endif

+ 16
- 13
src/gallium/drivers/nv50/nv50_vbo.c 查看文件

@@ -27,6 +27,7 @@

#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
#include "nv50_resource.h"

static INLINE uint32_t
nv50_vbo_type_to_hw(enum pipe_format format)
@@ -139,7 +140,7 @@ instance_init(struct nv50_context *nv50, struct instance *a, unsigned first)
if (a[i].divisor) {
vb = &nv50->vtxbuf[ve->vertex_buffer_index];

a[i].bo = nouveau_bo(vb->buffer);
a[i].bo = nv50_resource(vb->buffer)->bo;
a[i].stride = vb->stride;
a[i].step = first % a[i].divisor;
a[i].delta = vb->buffer_offset + ve->src_offset +
@@ -307,14 +308,14 @@ inline_edgeflag(void *priv, boolean enabled)

static void
nv50_draw_elements_inline(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
struct pipe_resource *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count,
unsigned startInstance, unsigned instanceCount)
{
struct pipe_screen *pscreen = pipe->screen;
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct pipe_transfer *transfer;
struct instance a[16];
struct inline_ctx ctx;
struct u_split_prim s;
@@ -337,7 +338,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe,
s.edge = inline_edgeflag;

ctx.nv50 = nv50;
ctx.map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
ctx.map = pipe_buffer_map(pipe, indexBuffer, PIPE_TRANSFER_READ, &transfer);
assert(ctx.map);
if (!ctx.map)
return;
@@ -380,12 +381,12 @@ nv50_draw_elements_inline(struct pipe_context *pipe,
nzi = TRUE;
}

pipe_buffer_unmap(pscreen, indexBuffer);
pipe_buffer_unmap(pipe, indexBuffer, transfer);
}

void
nv50_draw_elements_instanced(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count,
unsigned startInstance, unsigned instanceCount)
@@ -431,7 +432,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
if (indexSize == 4) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
OUT_RING (chan, count);
nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
nouveau_pushbuf_submit(chan,
nv50_resource(indexBuffer)->bo,
start << 2, count << 2);
} else
if (indexSize == 2) {
@@ -443,7 +445,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
OUT_RING (chan, ((start & 1) << 31) | count);
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
OUT_RING (chan, dwords);
nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
nouveau_pushbuf_submit(chan,
nv50_resource(indexBuffer)->bo,
vb_start << 1, dwords << 2);
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
OUT_RING (chan, 0);
@@ -457,7 +460,7 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,

void
nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
struct pipe_resource *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
nv50_draw_elements_instanced(pipe, indexBuffer, indexSize,
@@ -473,7 +476,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
{
struct nouveau_stateobj *so;
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
float v[4];
int ret;
unsigned nr_components = util_format_get_nr_components(ve->src_format);
@@ -571,7 +574,7 @@ nv50_vbo_validate(struct nv50_context *nv50)
struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
uint32_t hw = nv50->vtxelt->hw[i];

if (!vb->stride &&
@@ -608,10 +611,10 @@ nv50_vbo_validate(struct nv50_context *nv50)

/* vertex array limits */
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
so_reloc (vtxbuf, bo, vb->buffer->size - 1,
so_reloc (vtxbuf, bo, vb->buffer->width0 - 1,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
NOUVEAU_BO_HIGH, 0, 0);
so_reloc (vtxbuf, bo, vb->buffer->size - 1,
so_reloc (vtxbuf, bo, vb->buffer->width0 - 1,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
}

+ 5
- 0
src/gallium/drivers/nvfx/Makefile 查看文件

@@ -5,6 +5,7 @@ LIBNAME = nvfx

C_SOURCES = \
nv04_surface_2d.c \
nvfx_buffer.c \
nvfx_context.c \
nvfx_clear.c \
nvfx_draw.c \
@@ -14,6 +15,7 @@ C_SOURCES = \
nv40_fragtex.c \
nvfx_miptree.c \
nvfx_query.c \
nvfx_resource.c \
nvfx_screen.c \
nvfx_state.c \
nvfx_state_blend.c \
@@ -29,4 +31,7 @@ C_SOURCES = \
nvfx_vbo.c \
nvfx_vertprog.c

LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/nouveau/include

include ../../Makefile.template

+ 11
- 11
src/gallium/drivers/nvfx/nv04_surface_2d.c 查看文件

@@ -125,8 +125,8 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
struct nouveau_channel *chan = ctx->swzsurf->channel;
struct nouveau_grobj *swzsurf = ctx->swzsurf;
struct nouveau_grobj *sifm = ctx->sifm;
struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
struct nouveau_bo *src_bo = ctx->buf(src);
struct nouveau_bo *dst_bo = ctx->buf(dst);
const unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
/* Max width & height may not be the same on all HW, but must be POT */
const unsigned max_w = 1024;
@@ -205,8 +205,8 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
{
struct nouveau_channel *chan = ctx->m2mf->channel;
struct nouveau_grobj *m2mf = ctx->m2mf;
struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
struct nouveau_bo *src_bo = ctx->buf(src);
struct nouveau_bo *dst_bo = ctx->buf(dst);
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
unsigned dst_offset = dst->offset + dy * dst_pitch +
@@ -252,8 +252,8 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
struct nouveau_channel *chan = ctx->surf2d->channel;
struct nouveau_grobj *surf2d = ctx->surf2d;
struct nouveau_grobj *blit = ctx->blit;
struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
struct nouveau_bo *src_bo = ctx->buf(src);
struct nouveau_bo *dst_bo = ctx->buf(dst);
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
int format;
@@ -317,7 +317,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
struct nouveau_channel *chan = ctx->surf2d->channel;
struct nouveau_grobj *surf2d = ctx->surf2d;
struct nouveau_grobj *rect = ctx->rect;
struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
struct nouveau_bo *dst_bo = ctx->buf(dst);
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
int cs2d_format, gdirect_format;

@@ -507,10 +507,10 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d

// printf("creating temp, flags is %i!\n", flags);

if(ns->base.usage & PIPE_BUFFER_USAGE_DISCARD)
if(0 /*ns->base.usage & PIPE_BUFFER_USAGE_DISCARD*/)
{
temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ;
ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_DISCARD;
ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER /*| PIPE_BUFFER_USAGE_DISCARD */;
}
else
{
@@ -520,7 +520,7 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d

ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;

struct pipe_texture templ;
struct pipe_resource templ;
memset(&templ, 0, sizeof(templ));
templ.format = ns->base.texture->format;
templ.target = PIPE_TEXTURE_2D;
@@ -534,7 +534,7 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d

templ.tex_usage = ns->base.texture->tex_usage | PIPE_TEXTURE_USAGE_RENDER_TARGET;

struct pipe_texture* temp_tex = pscreen->texture_create(pscreen, &templ);
struct pipe_resource* temp_tex = pscreen->resource_create(pscreen, &templ);
struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags);
temp_ns->backing = ns;


+ 1
- 1
src/gallium/drivers/nvfx/nv04_surface_2d.h 查看文件

@@ -16,7 +16,7 @@ struct nv04_surface_2d {
struct nouveau_grobj *blit;
struct nouveau_grobj *sifm;

struct pipe_buffer *(*buf)(struct pipe_surface *);
struct nouveau_bo *(*buf)(struct pipe_surface *);

void (*copy)(struct nv04_surface_2d *, struct pipe_surface *dst,
int dx, int dy, struct pipe_surface *src, int sx, int sy,

+ 3
- 2
src/gallium/drivers/nvfx/nv30_fragtex.c 查看文件

@@ -3,6 +3,7 @@
#include "nvfx_context.h"
#include "nouveau/nouveau_util.h"
#include "nvfx_tex.h"
#include "nvfx_resource.h"

void
nv30_sampler_state_init(struct pipe_context *pipe,
@@ -92,8 +93,8 @@ nv30_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
struct nvfx_miptree *nv30mt = nvfx->tex_miptree[unit];
struct pipe_texture *pt = &nv30mt->base;
struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
struct pipe_resource *pt = &nv30mt->base.base;
struct nouveau_bo *bo = nv30mt->base.bo;
struct nv30_texture_format *tf;
struct nouveau_stateobj *so;
uint32_t txf, txs;

+ 3
- 2
src/gallium/drivers/nvfx/nv40_fragtex.c 查看文件

@@ -1,6 +1,7 @@
#include "util/u_format.h"
#include "nvfx_context.h"
#include "nvfx_tex.h"
#include "nvfx_resource.h"

void
nv40_sampler_state_init(struct pipe_context *pipe,
@@ -110,8 +111,8 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
struct nvfx_miptree *nv40mt = nvfx->tex_miptree[unit];
struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
struct pipe_texture *pt = &nv40mt->base;
struct nouveau_bo *bo = nv40mt->base.bo;
struct pipe_resource *pt = &nv40mt->base.base;
struct nv40_texture_format *tf;
struct nouveau_stateobj *so;
uint32_t txf, txs, txp;

+ 151
- 0
src/gallium/drivers/nvfx/nvfx_buffer.c 查看文件

@@ -0,0 +1,151 @@

#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_math.h"

#include "nouveau/nouveau_screen.h"
#include "nvfx_resource.h"


/* Currently using separate implementations for buffers and textures,
* even though gallium has a unified abstraction of these objects.
* Eventually these should be combined, and mechanisms like transfers
* be adapted to work for both buffer and texture uploads.
*/
static void nvfx_buffer_destroy(struct pipe_screen *pscreen,
struct pipe_resource *presource)
{
struct nvfx_resource *buffer = nvfx_resource(presource);

nouveau_screen_bo_release(pscreen, buffer->bo);
FREE(buffer);
}




/* Utility functions for transfer create/destroy are hooked in and
* just record the arguments to those functions.
*/
static void *
nvfx_buffer_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct nvfx_resource *buffer = nvfx_resource(transfer->resource);
uint8_t *map;

map = nouveau_screen_bo_map_range( pipe->screen,
buffer->bo,
transfer->box.x,
transfer->box.width,
transfer->usage );
if (map == NULL)
return NULL;
return map + transfer->box.x;
}



static void nvfx_buffer_transfer_flush_region( struct pipe_context *pipe,
struct pipe_transfer *transfer,
const struct pipe_box *box)
{
struct nvfx_resource *buffer = nvfx_resource(transfer->resource);

nouveau_screen_bo_map_flush_range(pipe->screen,
buffer->bo,
transfer->box.x + box->x,
box->width);
}

static void nvfx_buffer_transfer_unmap( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct nvfx_resource *buffer = nvfx_resource(transfer->resource);

nouveau_screen_bo_unmap(pipe->screen, buffer->bo);
}




struct u_resource_vtbl nvfx_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
nvfx_buffer_destroy, /* resource_destroy */
NULL, /* is_resource_referenced */
u_default_get_transfer, /* get_transfer */
u_default_transfer_destroy, /* transfer_destroy */
nvfx_buffer_transfer_map, /* transfer_map */
nvfx_buffer_transfer_flush_region, /* transfer_flush_region */
nvfx_buffer_transfer_unmap, /* transfer_unmap */
u_default_transfer_inline_write /* transfer_inline_write */
};




struct pipe_resource *
nvfx_buffer_create(struct pipe_screen *pscreen,
const struct pipe_resource *template)
{
struct nvfx_resource *buffer;

buffer = CALLOC_STRUCT(nvfx_resource);
if (!buffer)
return NULL;

buffer->base = *template;
buffer->vtbl = &nvfx_buffer_vtbl;
pipe_reference_init(&buffer->base.reference, 1);
buffer->base.screen = pscreen;

buffer->bo = nouveau_screen_bo_new(pscreen,
16,
buffer->base.usage,
buffer->base.width0);

if (buffer->bo == NULL)
goto fail;

return &buffer->base;

fail:
FREE(buffer);
return NULL;
}


struct pipe_resource *
nvfx_user_buffer_create(struct pipe_screen *pscreen,
void *ptr,
unsigned bytes,
unsigned usage)
{
struct nvfx_resource *buffer;

buffer = CALLOC_STRUCT(nvfx_resource);
if (!buffer)
return NULL;

pipe_reference_init(&buffer->base.reference, 1);
buffer->vtbl = &nvfx_buffer_vtbl;
buffer->base.screen = pscreen;
buffer->base.format = PIPE_FORMAT_R8_UNORM;
buffer->base.usage = usage;
buffer->base.width0 = bytes;
buffer->base.height0 = 1;
buffer->base.depth0 = 1;

buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
if (!buffer->bo)
goto fail;
return &buffer->base;

fail:
FREE(buffer);
return NULL;
}


+ 0
- 3
src/gallium/drivers/nvfx/nvfx_context.c 查看文件

@@ -65,9 +65,6 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
nvfx->pipe.clear = nvfx_clear;
nvfx->pipe.flush = nvfx_flush;

nvfx->pipe.is_texture_referenced = nouveau_is_texture_referenced;
nvfx->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;

screen->base.channel->user_private = nvfx;
screen->base.channel->flush_notify = nvfx_state_flush_notify;


+ 4
- 5
src/gallium/drivers/nvfx/nvfx_context.h 查看文件

@@ -16,7 +16,6 @@

#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_gldefs.h"
#include "nouveau/nouveau_context.h"
#include "nouveau/nouveau_stateobj.h"

#include "nvfx_state.h"
@@ -146,7 +145,7 @@ struct nvfx_context {
struct pipe_clip_state clip;
struct nvfx_vertex_program *vertprog;
struct nvfx_fragment_program *fragprog;
struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
unsigned constbuf_nr[PIPE_SHADER_TYPES];
struct nvfx_rasterizer_state *rasterizer;
struct nvfx_zsa_state *zsa;
@@ -155,7 +154,7 @@ struct nvfx_context {
struct pipe_stencil_ref stencil_ref;
struct pipe_viewport_state viewport;
struct pipe_framebuffer_state framebuffer;
struct pipe_buffer *idxbuf;
struct pipe_resource *idxbuf;
unsigned idxbuf_format;
struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct nvfx_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
@@ -211,7 +210,7 @@ extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers,
/* nvfx_draw.c */
extern struct draw_stage *nvfx_draw_render_stage(struct nvfx_context *nvfx);
extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe,
struct pipe_buffer *idxbuf,
struct pipe_resource *idxbuf,
unsigned ib_size, unsigned mode,
unsigned start, unsigned count);

@@ -253,7 +252,7 @@ extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx);
extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode,
unsigned start, unsigned count);
extern void nvfx_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count);

+ 17
- 11
src/gallium/drivers/nvfx/nvfx_draw.c 查看文件

@@ -228,11 +228,13 @@ nvfx_draw_render_stage(struct nvfx_context *nvfx)

void
nvfx_draw_elements_swtnl(struct pipe_context *pipe,
struct pipe_buffer *idxbuf, unsigned idxbuf_size,
struct pipe_resource *idxbuf, unsigned idxbuf_size,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
struct pipe_screen *pscreen = pipe->screen;
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *ib_transfer;
struct pipe_transfer *cb_transfer;
unsigned i;
void *map;

@@ -242,14 +244,16 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe,
nvfx_state_emit(nvfx);

for (i = 0; i < nvfx->vtxbuf_nr; i++) {
map = pipe_buffer_map(pscreen, nvfx->vtxbuf[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
map = pipe_buffer_map(pipe, nvfx->vtxbuf[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ,
&vb_transfer[i]);
draw_set_mapped_vertex_buffer(nvfx->draw, i, map);
}

if (idxbuf) {
map = pipe_buffer_map(pscreen, idxbuf,
PIPE_BUFFER_USAGE_CPU_READ);
map = pipe_buffer_map(pipe, idxbuf,
PIPE_BUFFER_USAGE_CPU_READ,
&ib_transfer);
draw_set_mapped_element_buffer(nvfx->draw, idxbuf_size, map);
} else {
draw_set_mapped_element_buffer(nvfx->draw, 0, NULL);
@@ -258,9 +262,10 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe,
if (nvfx->constbuf[PIPE_SHADER_VERTEX]) {
const unsigned nr = nvfx->constbuf_nr[PIPE_SHADER_VERTEX];

map = pipe_buffer_map(pscreen,
map = pipe_buffer_map(pipe,
nvfx->constbuf[PIPE_SHADER_VERTEX],
PIPE_BUFFER_USAGE_CPU_READ);
PIPE_BUFFER_USAGE_CPU_READ,
&cb_transfer);
draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0,
map, nr);
}
@@ -268,13 +273,14 @@ nvfx_draw_elements_swtnl(struct pipe_context *pipe,
draw_arrays(nvfx->draw, mode, start, count);

for (i = 0; i < nvfx->vtxbuf_nr; i++)
pipe_buffer_unmap(pscreen, nvfx->vtxbuf[i].buffer);
pipe_buffer_unmap(pipe, nvfx->vtxbuf[i].buffer, vb_transfer[i]);

if (idxbuf)
pipe_buffer_unmap(pscreen, idxbuf);
pipe_buffer_unmap(pipe, idxbuf, ib_transfer);

if (nvfx->constbuf[PIPE_SHADER_VERTEX])
pipe_buffer_unmap(pscreen, nvfx->constbuf[PIPE_SHADER_VERTEX]);
pipe_buffer_unmap(pipe, nvfx->constbuf[PIPE_SHADER_VERTEX],
cb_transfer);

draw_flush(nvfx->draw);
pipe->flush(pipe, 0, NULL);

+ 34
- 17
src/gallium/drivers/nvfx/nvfx_fragprog.c 查看文件

@@ -9,6 +9,7 @@

#include "nvfx_context.h"
#include "nvfx_shader.h"
#include "nvfx_resource.h"

#define MAX_CONSTS 128
#define MAX_IMM 32
@@ -825,12 +826,8 @@ static void
nvfx_fragprog_upload(struct nvfx_context *nvfx,
struct nvfx_fragment_program *fp)
{
struct pipe_screen *pscreen = nvfx->pipe.screen;
struct pipe_context *pipe = &nvfx->pipe;
const uint32_t le = 1;
uint32_t *map;
int i;

map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);

#if 0
for (i = 0; i < fp->insn_len; i++) {
@@ -841,25 +838,37 @@ nvfx_fragprog_upload(struct nvfx_context *nvfx,
#endif

if ((*(const uint8_t *)&le)) {
for (i = 0; i < fp->insn_len; i++) {
map[i] = fp->insn[i];
}
/* Can do this with an inline transfer */
pipe_buffer_write(pipe,
fp->buffer,
0,
fp->insn_len * sizeof fp->insn[0],
fp->insn);
} else {
struct pipe_transfer *transfer;
uint32_t *map;
int i;

map = pipe_buffer_map(pipe, fp->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE,
&transfer);
/* Weird swapping for big-endian chips */
for (i = 0; i < fp->insn_len; i++) {
map[i] = ((fp->insn[i] & 0xffff) << 16) |
((fp->insn[i] >> 16) & 0xffff);
}
}

pipe_buffer_unmap(pscreen, fp->buffer);
pipe_buffer_unmap(pipe, fp->buffer, transfer);
}
}

static boolean
nvfx_fragprog_validate(struct nvfx_context *nvfx)
{
struct pipe_context *pipe = &nvfx->pipe;
struct nvfx_fragment_program *fp = nvfx->fragprog;
struct pipe_buffer *constbuf =
struct pipe_resource *constbuf =
nvfx->constbuf[PIPE_SHADER_FRAGMENT];
struct pipe_screen *pscreen = nvfx->pipe.screen;
struct nouveau_stateobj *so;
@@ -876,12 +885,12 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
return FALSE;
}

fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
fp->buffer = pipe_buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
nvfx_fragprog_upload(nvfx, fp);

so = so_new(4, 4, 1);
so_method(so, nvfx->screen->eng3d, NV34TCL_FP_ACTIVE_PROGRAM, 1);
so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
so_reloc (so, nvfx_resource(fp->buffer)->bo, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
@@ -899,10 +908,18 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)

update_constants:
if (fp->nr_consts) {
struct pipe_transfer *transfer;
float *map;

map = pipe_buffer_map(pscreen, constbuf,
PIPE_BUFFER_USAGE_CPU_READ);
map = pipe_buffer_map(pipe, constbuf,
PIPE_TRANSFER_READ,
&transfer);

/* XXX: probably a bad idea to be reading back data
* from a buffer the gpu has been using. Not really
* sure what this code is doing though, or how to
* avoid it - kw.
*/
for (i = 0; i < fp->nr_consts; i++) {
struct nvfx_fragment_program_data *fpd = &fp->consts[i];
uint32_t *p = &fp->insn[fpd->offset];
@@ -913,7 +930,7 @@ update_constants:
memcpy(p, cb, 4 * sizeof(float));
new_consts = TRUE;
}
pipe_buffer_unmap(pscreen, constbuf);
pipe_buffer_unmap(pipe, constbuf, transfer);

if (new_consts)
nvfx_fragprog_upload(nvfx, fp);
@@ -932,7 +949,7 @@ nvfx_fragprog_destroy(struct nvfx_context *nvfx,
struct nvfx_fragment_program *fp)
{
if (fp->buffer)
pipe_buffer_reference(&fp->buffer, NULL);
pipe_resource_reference(&fp->buffer, NULL);

if (fp->so)
so_ref(NULL, &fp->so);

+ 111
- 59
src/gallium/drivers/nvfx/nvfx_miptree.c 查看文件

@@ -5,14 +5,22 @@
#include "util/u_math.h"

#include "nvfx_context.h"
#include "nvfx_resource.h"
#include "nvfx_transfer.h"
#include "nv04_surface_2d.h"

#include "nouveau/nouveau_util.h"

/* Currently using separate implementations for buffers and textures,
* even though gallium has a unified abstraction of these objects.
* Eventually these should be combined, and mechanisms like transfers
* be adapted to work for both buffer and texture uploads.
*/

static void
nvfx_miptree_layout(struct nvfx_miptree *mt)
{
struct pipe_texture *pt = &mt->base;
struct pipe_resource *pt = &mt->base.base;
uint width = pt->width0;
uint offset = 0;
int nr_faces, l, f;
@@ -61,32 +69,84 @@ nvfx_miptree_layout(struct nvfx_miptree *mt)
mt->total_size = offset;
}

static struct pipe_texture *
nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
static boolean
nvfx_miptree_get_handle(struct pipe_screen *pscreen,
struct pipe_resource *ptexture,
struct winsys_handle *whandle)
{
struct nvfx_miptree* mt = (struct nvfx_miptree*)ptexture;

if (!mt || !mt->base.bo)
return FALSE;

return nouveau_screen_bo_get_handle(pscreen,
mt->base.bo,
mt->level[0].pitch,
whandle);
}


static void
nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
int l;

nouveau_screen_bo_release(screen, mt->base.bo);

for (l = 0; l <= pt->last_level; l++) {
if (mt->level[l].image_offset)
FREE(mt->level[l].image_offset);
}

FREE(mt);
}




struct u_resource_vtbl nvfx_miptree_vtbl =
{
nvfx_miptree_get_handle, /* get_handle */
nvfx_miptree_destroy, /* resource_destroy */
NULL, /* is_resource_referenced */
nvfx_miptree_transfer_new, /* get_transfer */
nvfx_miptree_transfer_del, /* transfer_destroy */
nvfx_miptree_transfer_map, /* transfer_map */
u_default_transfer_flush_region, /* transfer_flush_region */
nvfx_miptree_transfer_unmap, /* transfer_unmap */
u_default_transfer_inline_write /* transfer_inline_write */
};



struct pipe_resource *
nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt)
{
struct nvfx_miptree *mt;
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
NOUVEAU_BUFFER_USAGE_TEXTURE;

mt = MALLOC(sizeof(struct nvfx_miptree));
mt = CALLOC_STRUCT(nvfx_miptree);
if (!mt)
return NULL;
mt->base = *pt;
pipe_reference_init(&mt->base.reference, 1);
mt->base.screen = pscreen;

mt->base.base = *pt;
pipe_reference_init(&mt->base.base.reference, 1);
mt->base.base.screen = pscreen;

/* Swizzled textures must be POT */
if (pt->width0 & (pt->width0 - 1) ||
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else {
switch (pt->format) {
case PIPE_FORMAT_B5G6R5_UNORM:
@@ -98,7 +158,7 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
are just preserving the pre-unification behavior.
The whole 2D code is going to be rewritten anyway. */
if(nvfx_screen(pscreen)->is_nv4x) {
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
/* TODO: Figure out which formats can be swizzled */
@@ -107,11 +167,11 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
case PIPE_FORMAT_R16_SNORM:
{
if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
default:
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
}
}

@@ -122,65 +182,68 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
* If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
* This also happens for small mipmaps of large textures. */
if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;

nvfx_miptree_layout(mt);

mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage, mt->total_size);
if (!mt->buffer) {
mt->base.bo = nouveau_screen_bo_new(pscreen, 256, buf_usage, mt->total_size);
if (!mt->base.bo) {
FREE(mt);
return NULL;
}
mt->bo = nouveau_bo(mt->buffer);
return &mt->base;
return &mt->base.base;
}

static struct pipe_texture *
nvfx_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
const unsigned *stride, struct pipe_buffer *pb)



struct pipe_resource *
nvfx_miptree_from_handle(struct pipe_screen *pscreen,
const struct pipe_resource *template,
struct winsys_handle *whandle)
{
struct nvfx_miptree *mt;
unsigned stride;

/* Only supports 2D, non-mipmapped textures for the moment */
if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
pt->depth0 != 1)
if (template->target != PIPE_TEXTURE_2D ||
template->last_level != 0 ||
template->depth0 != 1)
return NULL;

mt = CALLOC_STRUCT(nvfx_miptree);
if (!mt)
return NULL;

mt->base = *pt;
pipe_reference_init(&mt->base.reference, 1);
mt->base.screen = pscreen;
mt->level[0].pitch = stride[0];
mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
if (mt->base.bo == NULL) {
FREE(mt);
return NULL;
}

mt->base.base = *template;
pipe_reference_init(&mt->base.base.reference, 1);
mt->base.base.screen = pscreen;
mt->level[0].pitch = stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));

/* Assume whoever created this buffer expects it to be linear for now */
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;

pipe_buffer_reference(&mt->buffer, pb);
mt->bo = nouveau_bo(mt->buffer);
return &mt->base;
/* XXX: Need to adjust bo refcount??
*/
/* nouveau_bo_ref(bo, &mt->base.bo); */
return &mt->base.base;
}

static void
nvfx_miptree_destroy(struct pipe_texture *pt)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
int l;

pipe_buffer_reference(&mt->buffer, NULL);
for (l = 0; l <= pt->last_level; l++) {
if (mt->level[l].image_offset)
FREE(mt->level[l].image_offset);
}

FREE(mt);
}

static struct pipe_surface *
nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,

/* Surface helpers, not strictly required to implement the resource vtbl:
*/
struct pipe_surface *
nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
@@ -190,7 +253,7 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ns = CALLOC_STRUCT(nv04_surface);
if (!ns)
return NULL;
pipe_texture_reference(&ns->base.texture, pt);
pipe_resource_reference(&ns->base.texture, pt);
ns->base.format = pt->format;
ns->base.width = u_minify(pt->width0, level);
ns->base.height = u_minify(pt->height0, level);
@@ -219,7 +282,7 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
return &ns->base;
}

static void
void
nvfx_miptree_surface_del(struct pipe_surface *ps)
{
struct nv04_surface* ns = (struct nv04_surface*)ps;
@@ -231,17 +294,6 @@ nvfx_miptree_surface_del(struct pipe_surface *ps)
nvfx_miptree_surface_del(&ns->backing->base);
}

pipe_texture_reference(&ps->texture, NULL);
pipe_resource_reference(&ps->texture, NULL);
FREE(ps);
}

void
nvfx_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nvfx_miptree_create;
pscreen->texture_destroy = nvfx_miptree_destroy;
pscreen->get_tex_surface = nvfx_miptree_surface_new;
pscreen->tex_surface_destroy = nvfx_miptree_surface_del;

nouveau_screen(pscreen)->texture_blanket = nvfx_miptree_blanket;
}

+ 67
- 0
src/gallium/drivers/nvfx/nvfx_resource.c 查看文件

@@ -0,0 +1,67 @@

#include "pipe/p_context.h"
#include "nvfx_resource.h"
#include "nouveau/nouveau_screen.h"


/* This doesn't look quite right - this query is supposed to ask
* whether the particular context has references to the resource in
* any unflushed rendering command buffer, and hence requires a
* pipe->flush() for serializing some modification to that resource.
*
* This seems to be answering the question of whether the resource is
* currently on hardware.
*/
static unsigned int
nvfx_resource_is_referenced(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned face, unsigned level)
{
return nouveau_reference_flags(nvfx_resource(resource)->bo);
}

static struct pipe_resource *
nvfx_resource_create(struct pipe_screen *screen,
const struct pipe_resource *template)
{
if (template->target == PIPE_BUFFER)
return nvfx_buffer_create(screen, template);
else
return nvfx_miptree_create(screen, template);
}

static struct pipe_resource *
nvfx_resource_from_handle(struct pipe_screen * screen,
const struct pipe_resource *template,
struct winsys_handle *whandle)
{
if (template->target == PIPE_BUFFER)
return NULL;
else
return nvfx_miptree_from_handle(screen, template, whandle);
}

void
nvfx_init_resource_functions(struct pipe_context *pcontext)
{
pcontext->get_transfer = u_get_transfer_vtbl;
pcontext->transfer_map = u_transfer_map_vtbl;
pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
pcontext->transfer_unmap = u_transfer_unmap_vtbl;
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
pcontext->is_resource_referenced = nvfx_resource_is_referenced;
}

void
nvfx_screen_init_resource_functions(struct pipe_screen *pscreen)
{
pscreen->resource_create = nvfx_resource_create;
pscreen->resource_from_handle = nvfx_resource_from_handle;
pscreen->resource_get_handle = u_resource_get_handle_vtbl;
pscreen->resource_destroy = u_resource_destroy_vtbl;
pscreen->user_buffer_create = nvfx_user_buffer_create;
pscreen->get_tex_surface = nvfx_miptree_surface_new;
pscreen->tex_surface_destroy = nvfx_miptree_surface_del;
}

+ 91
- 0
src/gallium/drivers/nvfx/nvfx_resource.h 查看文件

@@ -0,0 +1,91 @@

#ifndef NVFX_RESOURCE_H
#define NVFX_RESOURCE_H

#include "util/u_transfer.h"

struct pipe_resource;
struct nouveau_bo;


/* This gets further specialized into either buffer or texture
* structures. In the future we'll want to remove much of that
* distinction, but for now try to keep as close to the existing code
* as possible and use the vtbl struct to choose between the two
* underlying implementations.
*/
struct nvfx_resource {
struct pipe_resource base;
struct u_resource_vtbl *vtbl;
struct nouveau_bo *bo;
};

#define NVFX_MAX_TEXTURE_LEVELS 16

struct nvfx_miptree {
struct nvfx_resource base;
uint total_size;

struct {
uint pitch;
uint *image_offset;
} level[NVFX_MAX_TEXTURE_LEVELS];

unsigned image_nr;
};

static INLINE
struct nvfx_resource *nvfx_resource(struct pipe_resource *resource)
{
return (struct nvfx_resource *)resource;
}

static INLINE struct nouveau_bo *
nvfx_surface_buffer(struct pipe_surface *surf)
{
struct nvfx_resource *mt = nvfx_resource(surf->texture);

return mt->bo;
}


void
nvfx_init_resource_functions(struct pipe_context *pcontext);

void
nvfx_screen_init_resource_functions(struct pipe_screen *pscreen);


/* Internal:
*/

struct pipe_resource *
nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt);

struct pipe_resource *
nvfx_miptree_from_handle(struct pipe_screen *pscreen,
const struct pipe_resource *template,
struct winsys_handle *whandle);

struct pipe_resource *
nvfx_buffer_create(struct pipe_screen *pscreen,
const struct pipe_resource *template);

struct pipe_resource *
nvfx_user_buffer_create(struct pipe_screen *screen,
void *ptr,
unsigned bytes,
unsigned usage);



void
nvfx_miptree_surface_del(struct pipe_surface *ps);

struct pipe_surface *
nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags);


#endif

+ 3
- 9
src/gallium/drivers/nvfx/nvfx_screen.c 查看文件

@@ -5,6 +5,7 @@

#include "nvfx_context.h"
#include "nvfx_screen.h"
#include "nvfx_resource.h"

#define NV30TCL_CHIPSET_3X_MASK 0x00000003
#define NV34TCL_CHIPSET_3X_MASK 0x00000010
@@ -16,7 +17,7 @@
* with same number of bits everywhere.
*/
struct nouveau_winsys {
struct pipe_winsys base;
//struct pipe_winsys base;

struct pipe_screen *pscreen;

@@ -174,13 +175,6 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
return FALSE;
}

static struct pipe_buffer *
nvfx_surface_buffer(struct pipe_surface *surf)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)surf->texture;

return mt->buffer;
}

static void
nvfx_screen_destroy(struct pipe_screen *pscreen)
@@ -352,7 +346,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}

nvfx_screen_init_miptree_functions(pscreen);
nvfx_screen_init_resource_functions(pscreen);

ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
if (ret) {

+ 1
- 0
src/gallium/drivers/nvfx/nvfx_screen.h 查看文件

@@ -3,6 +3,7 @@

#include "nouveau/nouveau_screen.h"
#include "nv04_surface_2d.h"
#include "nvfx_context.h"

struct nvfx_screen {
struct nouveau_screen base;

+ 5
- 5
src/gallium/drivers/nvfx/nvfx_state.c 查看文件

@@ -163,7 +163,7 @@ nvfx_set_fragment_sampler_views(struct pipe_context *pipe,

static struct pipe_sampler_view *
nvfx_create_sampler_view(struct pipe_context *pipe,
struct pipe_texture *texture,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
@@ -172,7 +172,7 @@ nvfx_create_sampler_view(struct pipe_context *pipe,
*view = *templ;
view->reference.count = 1;
view->texture = NULL;
pipe_texture_reference(&view->texture, texture);
pipe_resource_reference(&view->texture, texture);
view->context = pipe;
}

@@ -184,7 +184,7 @@ static void
nvfx_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
pipe_texture_reference(&view->texture, NULL);
pipe_resource_reference(&view->texture, NULL);
FREE(view);
}

@@ -499,12 +499,12 @@ nvfx_set_clip_state(struct pipe_context *pipe,

static void
nvfx_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
struct pipe_buffer *buf )
struct pipe_resource *buf )
{
struct nvfx_context *nvfx = nvfx_context(pipe);

nvfx->constbuf[shader] = buf;
nvfx->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
nvfx->constbuf_nr[shader] = buf->width0 / (4 * sizeof(float));

if (shader == PIPE_SHADER_VERTEX) {
nvfx->dirty |= NVFX_NEW_VERTPROG;

+ 4
- 16
src/gallium/drivers/nvfx/nvfx_state.h 查看文件

@@ -58,26 +58,14 @@ struct nvfx_fragment_program {

struct nvfx_fragment_program_data *consts;
unsigned nr_consts;

struct pipe_buffer *buffer;
/* XXX: just use a nouveau_bo for this?
*/
struct pipe_resource *buffer;

uint32_t fp_control;
struct nouveau_stateobj *so;
};

#define NVFX_MAX_TEXTURE_LEVELS 16

struct nvfx_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;

struct pipe_buffer *buffer;
uint total_size;

struct {
uint pitch;
uint *image_offset;
} level[NVFX_MAX_TEXTURE_LEVELS];
};

#endif

+ 1
- 7
src/gallium/drivers/nvfx/nvfx_state_fb.c 查看文件

@@ -1,14 +1,8 @@
#include "nvfx_context.h"
#include "nvfx_resource.h"
#include "nouveau/nouveau_util.h"

static struct pipe_buffer *
nvfx_do_surface_buffer(struct pipe_surface *surface)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)surface->texture;
return mt->buffer;
}

#define nvfx_surface_buffer(ps) nouveau_bo(nvfx_do_surface_buffer(ps))

static boolean
nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)

+ 59
- 59
src/gallium/drivers/nvfx/nvfx_transfer.c 查看文件

@@ -8,6 +8,8 @@
#include "nvfx_context.h"
#include "nvfx_screen.h"
#include "nvfx_state.h"
#include "nvfx_resource.h"
#include "nvfx_transfer.h"

struct nvfx_transfer {
struct pipe_transfer base;
@@ -16,10 +18,10 @@ struct nvfx_transfer {
};

static void
nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
struct pipe_texture *template)
nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned height,
struct pipe_resource *template)
{
memset(template, 0, sizeof(struct pipe_texture));
memset(template, 0, sizeof(struct pipe_resource));
template->target = pt->target;
template->format = pt->format;
template->width0 = width;
@@ -32,49 +34,57 @@ nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
NOUVEAU_TEXTURE_USAGE_LINEAR;
}

static struct pipe_transfer *
nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
struct pipe_transfer *
nvfx_miptree_transfer_new(struct pipe_context *pcontext,
struct pipe_resource *pt,
struct pipe_subresource sr,
enum pipe_transfer_usage usage,
const struct pipe_box *box)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nvfx_transfer *tx;
struct pipe_texture tx_tex_template, *tx_tex;
struct pipe_resource tx_tex_template, *tx_tex;
static boolean firsttime = TRUE;
static boolean no_transfer = FALSE;

if (firsttime) {
no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER",
TRUE/*XXX:FALSE*/);
firsttime = FALSE;
}

tx = CALLOC_STRUCT(nvfx_transfer);
if (!tx)
return NULL;

pipe_texture_reference(&tx->base.texture, pt);
tx->base.x = x;
tx->base.y = y;
tx->base.width = w;
tx->base.height = h;
tx->base.stride = mt->level[level].pitch;
/* Don't handle 3D transfers yet.
*/
assert(box->depth == 1);
pipe_resource_reference(&tx->base.resource, pt);
tx->base.sr = sr;
tx->base.usage = usage;
tx->base.face = face;
tx->base.level = level;
tx->base.zslice = zslice;
tx->base.box = *box;
tx->base.stride = mt->level[sr.level].pitch;

/* Direct access to texture */
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) &&
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
{
tx->direct = true;
tx->surface = pscreen->get_tex_surface(pscreen, pt,
face, level, zslice,
sr.face, sr.level,
box->z,
pipe_transfer_buffer_flags(&tx->base));
return &tx->base;
}

tx->direct = false;

nvfx_compatible_transfer_tex(pt, w, h, &tx_tex_template);
nvfx_compatible_transfer_tex(pt, box->width, box->height, &tx_tex_template);

tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
tx_tex = pscreen->resource_create(pscreen, &tx_tex_template);
if (!tx_tex)
{
FREE(tx);
@@ -87,7 +97,7 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
0, 0, 0,
pipe_transfer_buffer_flags(&tx->base));

pipe_texture_reference(&tx_tex, NULL);
pipe_resource_reference(&tx_tex, NULL);

if (!tx->surface)
{
@@ -101,15 +111,16 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
struct pipe_surface *src;

src = pscreen->get_tex_surface(pscreen, pt,
face, level, zslice,
sr.face, sr.level, box->z,
PIPE_BUFFER_USAGE_GPU_READ);

/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
/* TODO: Check if SIFM can un-swizzle */
nvscreen->eng2d->copy(nvscreen->eng2d,
tx->surface, 0, 0,
src, x, y,
w, h);
src,
box->x, box->y,
box->width, box->height);

pipe_surface_reference(&src, NULL);
}
@@ -117,9 +128,9 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
return &tx->base;
}

static void
nvfx_transfer_del(struct pipe_context *pcontext,
struct pipe_transfer *ptx)
void
nvfx_miptree_transfer_del(struct pipe_context *pcontext,
struct pipe_transfer *ptx)
{
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;

@@ -128,62 +139,51 @@ nvfx_transfer_del(struct pipe_context *pcontext,
struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
struct pipe_surface *dst;

dst = pscreen->get_tex_surface(pscreen, ptx->texture,
ptx->face, ptx->level, ptx->zslice,
dst = pscreen->get_tex_surface(pscreen,
ptx->resource,
ptx->sr.face,
ptx->sr.level,
ptx->box.z,
PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);

/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
nvscreen->eng2d->copy(nvscreen->eng2d,
dst, tx->base.x, tx->base.y,
dst, ptx->box.x, ptx->box.y,
tx->surface, 0, 0,
tx->base.width, tx->base.height);
ptx->box.width, ptx->box.height);

pipe_surface_reference(&dst, NULL);
}

pipe_surface_reference(&tx->surface, NULL);
pipe_texture_reference(&ptx->texture, NULL);
pipe_resource_reference(&ptx->resource, NULL);
FREE(ptx);
}

static void *
nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
void *
nvfx_miptree_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
void *map = pipe_buffer_map(pscreen, mt->buffer,
pipe_transfer_buffer_flags(ptx));
uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo,
pipe_transfer_buffer_flags(ptx));

if(!tx->direct)
return map + ns->base.offset;
else
return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
return (map + ns->base.offset +
ptx->box.y * ns->pitch +
ptx->box.x * util_format_get_blocksize(ptx->resource->format));
}

static void
nvfx_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
void
nvfx_miptree_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct pipe_screen *pscreen = pcontext->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;

pipe_buffer_unmap(pscreen, mt->buffer);
}

void
nvfx_init_transfer_functions(struct nvfx_context *nvfx)
{
<<<<<<< HEAD:src/gallium/drivers/nv30/nv30_transfer.c
nv30->pipe.get_transfer = nv30_transfer_new;
nv30->pipe.transfer_destroy = nv30_transfer_del;
nv30->pipe.transfer_map = nv30_transfer_map;
nv30->pipe.transfer_unmap = nv30_transfer_unmap;
=======
nvfx->pipe.get_tex_transfer = nvfx_transfer_new;
nvfx->pipe.tex_transfer_destroy = nvfx_transfer_del;
nvfx->pipe.transfer_map = nvfx_transfer_map;
nvfx->pipe.transfer_unmap = nvfx_transfer_unmap;
>>>>>>> origin/gallium-sampler-view:src/gallium/drivers/nvfx/nvfx_transfer.c
nouveau_screen_bo_unmap(pscreen, mt->base.bo);
}

+ 26
- 0
src/gallium/drivers/nvfx/nvfx_transfer.h 查看文件

@@ -0,0 +1,26 @@

#ifndef NVFX_TRANSFER_H
#define NVFX_TRANSFER_H

#include "util/u_transfer.h"
#include "pipe/p_state.h"


struct pipe_transfer *
nvfx_miptree_transfer_new(struct pipe_context *pcontext,
struct pipe_resource *pt,
struct pipe_subresource sr,
enum pipe_transfer_usage usage,
const struct pipe_box *box);
void
nvfx_miptree_transfer_del(struct pipe_context *pcontext,
struct pipe_transfer *ptx);
void *
nvfx_miptree_transfer_map(struct pipe_context *pcontext,
struct pipe_transfer *ptx);
void
nvfx_miptree_transfer_unmap(struct pipe_context *pcontext,
struct pipe_transfer *ptx);


#endif

+ 18
- 16
src/gallium/drivers/nvfx/nvfx_vbo.c 查看文件

@@ -5,6 +5,7 @@

#include "nvfx_context.h"
#include "nvfx_state.h"
#include "nvfx_resource.h"

#include "nouveau/nouveau_channel.h"
#include "nouveau/nouveau_pushbuf.h"
@@ -76,7 +77,7 @@ nvfx_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
}

static boolean
nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib,
nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib,
unsigned ib_size)
{
struct pipe_screen *pscreen = &nvfx->screen->base.base;
@@ -117,21 +118,22 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
int attrib, struct pipe_vertex_element *ve,
struct pipe_vertex_buffer *vb)
{
struct pipe_screen *pscreen = nvfx->pipe.screen;
struct pipe_context *pipe = &nvfx->pipe;
struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
struct pipe_transfer *transfer;
unsigned type, ncomp;
void *map;
uint8_t *map;

if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp))
return FALSE;

map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
map = pipe_buffer_map(pipe, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ, &transfer);
map += vb->buffer_offset + ve->src_offset;

switch (type) {
case NV34TCL_VTXFMT_TYPE_FLOAT:
{
float *v = map;
float *v = (float *)map;

switch (ncomp) {
case 4:
@@ -157,17 +159,17 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
so_data (so, fui(v[0]));
break;
default:
pipe_buffer_unmap(pscreen, vb->buffer);
pipe_buffer_unmap(pipe, vb->buffer, transfer);
return FALSE;
}
}
break;
default:
pipe_buffer_unmap(pscreen, vb->buffer);
pipe_buffer_unmap(pipe, vb->buffer, transfer);
return FALSE;
}

pipe_buffer_unmap(pscreen, vb->buffer);
pipe_buffer_unmap(pipe, vb->buffer, transfer);
return TRUE;
}

@@ -379,14 +381,14 @@ nvfx_draw_elements_u32(struct nvfx_context *nvfx, void *ib,

static void
nvfx_draw_elements_inline(struct pipe_context *pipe,
struct pipe_buffer *ib, unsigned ib_size,
struct pipe_resource *ib, unsigned ib_size,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
struct pipe_screen *pscreen = pipe->screen;
struct pipe_transfer *transfer;
void *map;

map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
map = pipe_buffer_map(pipe, ib, PIPE_BUFFER_USAGE_CPU_READ, &transfer);
if (!ib) {
NOUVEAU_ERR("failed mapping ib\n");
return;
@@ -407,7 +409,7 @@ nvfx_draw_elements_inline(struct pipe_context *pipe,
break;
}

pipe_buffer_unmap(pscreen, ib);
pipe_buffer_unmap(pipe, ib, transfer);
}

static void
@@ -465,7 +467,7 @@ nvfx_draw_elements_vbo(struct pipe_context *pipe,

void
nvfx_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
struct pipe_resource *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
@@ -493,7 +495,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
{
struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
struct pipe_buffer *ib = nvfx->idxbuf;
struct pipe_resource *ib = nvfx->idxbuf;
unsigned ib_format = nvfx->idxbuf_format;
unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
int hw;
@@ -529,7 +531,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
return FALSE;
}

so_reloc(vtxbuf, nouveau_bo(vb->buffer),
so_reloc(vtxbuf, nvfx_resource(vb->buffer)->bo,
vb->buffer_offset + ve->src_offset,
vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
0, NV34TCL_VTXBUF_ADDRESS_DMA1);
@@ -538,7 +540,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
}

if (ib) {
struct nouveau_bo *bo = nouveau_bo(ib);
struct nouveau_bo *bo = nvfx_resource(ib)->bo;

so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2);
so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);

+ 7
- 5
src/gallium/drivers/nvfx/nvfx_vertprog.c 查看文件

@@ -833,12 +833,13 @@ out_err:
static boolean
nvfx_vertprog_validate(struct nvfx_context *nvfx)
{
struct pipe_screen *pscreen = nvfx->pipe.screen;
struct pipe_context *pipe = &nvfx->pipe;
struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
struct nouveau_grobj *eng3d = screen->eng3d;
struct nvfx_vertex_program *vp;
struct pipe_buffer *constbuf;
struct pipe_resource *constbuf;
struct pipe_transfer *transfer;
boolean upload_code = FALSE, upload_data = FALSE;
int i;

@@ -962,8 +963,9 @@ check_gpu_resources:
float *map = NULL;

if (constbuf) {
map = pipe_buffer_map(pscreen, constbuf,
PIPE_BUFFER_USAGE_CPU_READ);
map = pipe_buffer_map(pipe, constbuf,
PIPE_BUFFER_USAGE_CPU_READ,
&transfer);
}

for (i = 0; i < vp->nr_consts; i++) {
@@ -984,7 +986,7 @@ check_gpu_resources:
}

if (constbuf)
pipe_buffer_unmap(pscreen, constbuf);
pipe_buffer_unmap(pipe, constbuf, transfer);
}

/* Upload vtxprog */

+ 1
- 1
src/gallium/drivers/svga/svga_resource_buffer.c 查看文件

@@ -336,7 +336,7 @@ svga_user_buffer_create(struct pipe_screen *screen,
sbuf->b.vtbl = &svga_buffer_vtbl;
sbuf->b.b.screen = screen;
sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
sbuf->b.b.usage = PIPE_BUFFER_USAGE_CPU_READ | usage;
sbuf->b.b.usage = usage;
sbuf->b.b.width0 = bytes;
sbuf->b.b.height0 = 1;
sbuf->b.b.depth0 = 1;

Loading…
取消
儲存