From 5c1c4f8593073c0bad9bada9234657dda1b25ff0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 11:30:25 +1000 Subject: nouveau: common linear buffer manager, ported from nv50/nvc0 drivers nv50_resource is being called nv04_resource now temporarily, to avoid a naming conflict with nouveau_resource from libdrm. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 489 +++++++++++++++++++++++++++ 1 file changed, 489 insertions(+) create mode 100644 src/gallium/drivers/nouveau/nouveau_buffer.c (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c') diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c new file mode 100644 index 0000000000..4f4b24fdd2 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -0,0 +1,489 @@ + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "nouveau_screen.h" +#include "nouveau_winsys.h" +#include "nouveau_fence.h" +#include "nouveau_buffer.h" +#include "nouveau_mm.h" + +struct nouveau_transfer { + struct pipe_transfer base; +}; + +static INLINE struct nouveau_transfer * +nouveau_transfer(struct pipe_transfer *transfer) +{ + return (struct nouveau_transfer *)transfer; +} + +static INLINE boolean +nouveau_buffer_allocate(struct nouveau_screen *screen, + struct nv04_resource *buf, unsigned domain) +{ + if (domain == NOUVEAU_BO_VRAM) { + buf->mm = nouveau_mm_allocate(screen->mm_VRAM, buf->base.width0, + &buf->bo, &buf->offset); + if (!buf->bo) + return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART); + } else + if (domain == NOUVEAU_BO_GART) { + buf->mm = nouveau_mm_allocate(screen->mm_GART, buf->base.width0, + &buf->bo, &buf->offset); + if (!buf->bo) + return FALSE; + } + if (domain != NOUVEAU_BO_GART) { + if (!buf->data) { + buf->data = MALLOC(buf->base.width0); + if (!buf->data) + return FALSE; + } + } + buf->domain = domain; + return TRUE; +} + +static INLINE void +release_allocation(struct nouveau_mm_allocation **mm, + struct nouveau_fence *fence) +{ + nouveau_fence_work(fence, nouveau_mm_free_work, *mm); + (*mm) = NULL; +} + +INLINE void +nouveau_buffer_release_gpu_storage(struct nv04_resource *buf) +{ + nouveau_bo_ref(NULL, &buf->bo); + + if (buf->mm) + release_allocation(&buf->mm, buf->fence); + + buf->domain = 0; +} + +static INLINE boolean +nouveau_buffer_reallocate(struct nouveau_screen *screen, + struct nv04_resource *buf, unsigned domain) +{ + nouveau_buffer_release_gpu_storage(buf); + + return nouveau_buffer_allocate(screen, buf, domain); +} + +static void +nouveau_buffer_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource) +{ + struct nv04_resource *res = nv04_resource(presource); + + nouveau_buffer_release_gpu_storage(res); + + if (res->data && !(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) + FREE(res->data); + + FREE(res); +} + +/* Maybe just migrate to GART right away if we actually need to do this. */ +boolean +nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, + unsigned start, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_mm_allocation *mm; + struct nouveau_bo *bounce = NULL; + uint32_t offset; + + assert(buf->domain == NOUVEAU_BO_VRAM); + + mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + if (!bounce) + return FALSE; + + screen->copy_data(pipe, bounce, offset, NOUVEAU_BO_GART, + buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size); + + if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD)) + return FALSE; + memcpy(buf->data + start, bounce->map, size); + nouveau_bo_unmap(bounce); + + buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + + nouveau_bo_ref(NULL, &bounce); + if (mm) + nouveau_mm_free(mm); + return TRUE; +} + +static boolean +nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, + unsigned start, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_mm_allocation *mm; + struct nouveau_bo *bounce = NULL; + uint32_t offset; + + if (size <= 192) { + screen->push_data(pipe, buf->bo, buf->offset + start, buf->domain, + size, buf->data + start); + return TRUE; + } + + mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + if (!bounce) + return FALSE; + + nouveau_bo_map_range(bounce, offset, size, + NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); + memcpy(bounce->map, buf->data + start, size); + nouveau_bo_unmap(bounce); + + screen->copy_data(pipe, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, + bounce, offset, NOUVEAU_BO_GART, size); + + nouveau_bo_ref(NULL, &bounce); + if (mm) + release_allocation(&mm, screen->fence.current); + + if (start == 0 && size == buf->base.width0) + buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + return TRUE; +} + +static struct pipe_transfer * +nouveau_buffer_transfer_get(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, unsigned usage, + const struct pipe_box *box) +{ + struct nv04_resource *buf = nv04_resource(resource); + struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_transfer); + if (!xfr) + return NULL; + + xfr->base.resource = resource; + xfr->base.box.x = box->x; + xfr->base.box.width = box->width; + xfr->base.usage = usage; + + if (buf->domain == NOUVEAU_BO_VRAM) { + if (usage & PIPE_TRANSFER_READ) { + if (buf->status & NOUVEAU_BUFFER_STATUS_DIRTY) + nouveau_buffer_download(pipe, buf, 0, buf->base.width0); + } + } + + return &xfr->base; +} + +static void +nouveau_buffer_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_transfer *xfr = nouveau_transfer(transfer); + + if (xfr->base.usage & PIPE_TRANSFER_WRITE) { + /* writing is worse */ + nouveau_buffer_adjust_score(pipe, buf, -5000); + + if (buf->domain == NOUVEAU_BO_VRAM) { + nouveau_buffer_upload(pipe, buf, transfer->box.x, transfer->box.width); + } + +#if 0 + if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | + PIPE_BIND_INDEX_BUFFER))) + nouveau_context(pipe)->vbo_dirty = TRUE; +#endif + } + + FREE(xfr); +} + +static INLINE boolean +nouveau_buffer_sync(struct nv04_resource *buf, unsigned rw) +{ + if (rw == PIPE_TRANSFER_READ) { + if (!buf->fence_wr) + return TRUE; + if (!nouveau_fence_wait(buf->fence_wr)) + return FALSE; + } else { + if (!buf->fence) + return TRUE; + if (!nouveau_fence_wait(buf->fence)) + return FALSE; + + nouveau_fence_ref(NULL, &buf->fence); + } + nouveau_fence_ref(NULL, &buf->fence_wr); + + return TRUE; +} + +static INLINE boolean +nouveau_buffer_busy(struct nv04_resource *buf, unsigned rw) +{ + if (rw == PIPE_TRANSFER_READ) + return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr)); + else + return (buf->fence && !nouveau_fence_signalled(buf->fence)); +} + +static void * +nouveau_buffer_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct nouveau_transfer *xfr = nouveau_transfer(transfer); + struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_bo *bo = buf->bo; + uint8_t *map; + int ret; + uint32_t offset = xfr->base.box.x; + uint32_t flags; + + nouveau_buffer_adjust_score(pipe, buf, -250); + + if (buf->domain != NOUVEAU_BO_GART) + return buf->data + offset; + + if (buf->mm) + flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR; + else + flags = nouveau_screen_transfer_flags(xfr->base.usage); + + offset += buf->offset; + + ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags); + if (ret) + return NULL; + map = bo->map; + + /* Unmap right now. Since multiple buffers can share a single nouveau_bo, + * not doing so might make future maps fail or trigger "reloc while mapped" + * errors. For now, mappings to userspace are guaranteed to be persistent. + */ + nouveau_bo_unmap(bo); + + if (buf->mm) { + if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) { + if (nouveau_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE)) + return NULL; + } else + if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { + nouveau_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE); + } + } + return map; +} + + + +static void +nouveau_buffer_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct nv04_resource *res = nv04_resource(transfer->resource); + struct nouveau_bo *bo = res->bo; + unsigned offset = res->offset + transfer->box.x + box->x; + + /* not using non-snoop system memory yet, no need for cflush */ + if (1) + return; + + /* XXX: maybe need to upload for VRAM buffers here */ + + nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width); +} + +static void +nouveau_buffer_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + /* we've called nouveau_bo_unmap right after map */ +} + +const struct u_resource_vtbl nouveau_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + nouveau_buffer_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + nouveau_buffer_transfer_get, /* get_transfer */ + nouveau_buffer_transfer_destroy, /* transfer_destroy */ + nouveau_buffer_transfer_map, /* transfer_map */ + nouveau_buffer_transfer_flush_region, /* transfer_flush_region */ + nouveau_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + +struct pipe_resource * +nouveau_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *templ) +{ + struct nouveau_screen *screen = nouveau_screen(pscreen); + struct nv04_resource *buffer; + boolean ret; + + buffer = CALLOC_STRUCT(nv04_resource); + if (!buffer) + return NULL; + + buffer->base = *templ; + buffer->vtbl = &nouveau_buffer_vtbl; + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = pscreen; + + if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) + ret = nouveau_buffer_allocate(screen, buffer, 0); + else + ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); + + if (ret == FALSE) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + + +struct pipe_resource * +nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr, + unsigned bytes, unsigned bind) +{ + struct nv04_resource *buffer; + + buffer = CALLOC_STRUCT(nv04_resource); + if (!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->vtbl = &nouveau_buffer_vtbl; + buffer->base.screen = pscreen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; + buffer->base.usage = PIPE_USAGE_IMMUTABLE; + buffer->base.bind = bind; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + + buffer->data = ptr; + buffer->status = NOUVEAU_BUFFER_STATUS_USER_MEMORY; + + return &buffer->base; +} + +/* Like download, but for GART buffers. Merge ? */ +static INLINE boolean +nouveau_buffer_data_fetch(struct nv04_resource *buf, struct nouveau_bo *bo, + unsigned offset, unsigned size) +{ + if (!buf->data) { + buf->data = MALLOC(size); + if (!buf->data) + return FALSE; + } + if (nouveau_bo_map_range(bo, offset, size, NOUVEAU_BO_RD)) + return FALSE; + memcpy(buf->data, bo->map, size); + nouveau_bo_unmap(bo); + + return TRUE; +} + +/* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */ +boolean +nouveau_buffer_migrate(struct pipe_context *pipe, + struct nv04_resource *buf, const unsigned new_domain) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_bo *bo; + const unsigned old_domain = buf->domain; + unsigned size = buf->base.width0; + unsigned offset; + int ret; + + assert(new_domain != old_domain); + + if (new_domain == NOUVEAU_BO_GART && old_domain == 0) { + if (!nouveau_buffer_allocate(screen, buf, new_domain)) + return FALSE; + ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR | + NOUVEAU_BO_NOSYNC); + if (ret) + return ret; + memcpy(buf->bo->map, buf->data, size); + nouveau_bo_unmap(buf->bo); + FREE(buf->data); + } else + if (old_domain != 0 && new_domain != 0) { + struct nouveau_mm_allocation *mm = buf->mm; + + if (new_domain == NOUVEAU_BO_VRAM) { + /* keep a system memory copy of our data in case we hit a fallback */ + if (!nouveau_buffer_data_fetch(buf, buf->bo, buf->offset, size)) + return FALSE; + debug_printf("migrating %u KiB to VRAM\n", size / 1024); + } + + offset = buf->offset; + bo = buf->bo; + buf->bo = NULL; + buf->mm = NULL; + nouveau_buffer_allocate(screen, buf, new_domain); + + screen->copy_data(pipe, buf->bo, buf->offset, new_domain, + bo, offset, old_domain, buf->base.width0); + + nouveau_bo_ref(NULL, &bo); + if (mm) + release_allocation(&mm, screen->fence.current); + } else + if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { + if (!nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) + return FALSE; + if (!nouveau_buffer_upload(pipe, buf, 0, buf->base.width0)) + return FALSE; + } else + return FALSE; + + assert(buf->domain == new_domain); + return TRUE; +} + +/* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART. + * We'd like to only allocate @size bytes here, but then we'd have to rebase + * the vertex indices ... + */ +boolean +nouveau_user_buffer_upload(struct nv04_resource *buf, + unsigned base, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(buf->base.screen); + int ret; + + assert(buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY); + + buf->base.width0 = base + size; + if (!nouveau_buffer_reallocate(screen, buf, NOUVEAU_BO_GART)) + return FALSE; + + ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size, + NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); + if (ret) + return FALSE; + memcpy(buf->bo->map, buf->data + base, size); + nouveau_bo_unmap(buf->bo); + + return TRUE; +} -- cgit v1.2.3 From be68782d9aebf6f6575bb8cc9cfc66b7bad79644 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 13:09:41 +1000 Subject: nv50: sync textures with render targets ourselves Port of the nvc0 commit doing the same. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 6 +++--- src/gallium/drivers/nouveau/nouveau_buffer.h | 5 +++-- src/gallium/drivers/nv50/nv50_3d.xml.h | 2 +- src/gallium/drivers/nv50/nv50_screen.h | 5 +++++ src/gallium/drivers/nv50/nv50_state_validate.c | 16 ++++++++++++++++ src/gallium/drivers/nv50/nv50_tex.c | 8 ++++++++ src/gallium/drivers/nv50/nv50_winsys.h | 2 +- 7 files changed, 37 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c') diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 4f4b24fdd2..efb16824e4 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -112,7 +112,7 @@ nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, memcpy(buf->data + start, bounce->map, size); nouveau_bo_unmap(bounce); - buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; nouveau_bo_ref(NULL, &bounce); if (mm) @@ -152,7 +152,7 @@ nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, release_allocation(&mm, screen->fence.current); if (start == 0 && size == buf->base.width0) - buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; return TRUE; } @@ -174,7 +174,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, if (buf->domain == NOUVEAU_BO_VRAM) { if (usage & PIPE_TRANSFER_READ) { - if (buf->status & NOUVEAU_BUFFER_STATUS_DIRTY) + if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) nouveau_buffer_download(pipe, buf, 0, buf->base.width0); } } diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h index d75bc4e0c3..c3e0c2cf92 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.h +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -17,7 +17,8 @@ struct nouveau_bo; * USER_MEMORY: resource->data is a pointer to client memory and may change * between GL calls */ -#define NOUVEAU_BUFFER_STATUS_DIRTY (1 << 0) +#define NOUVEAU_BUFFER_STATUS_GPU_READING (1 << 0) +#define NOUVEAU_BUFFER_STATUS_GPU_WRITING (1 << 1) #define NOUVEAU_BUFFER_STATUS_USER_MEMORY (1 << 7) /* Resources, if mapped into the GPU's address space, are guaranteed to @@ -84,7 +85,7 @@ nouveau_resource_map_offset(struct pipe_context *pipe, nouveau_buffer_adjust_score(pipe, res, -250); if ((res->domain == NOUVEAU_BO_VRAM) && - (res->status & NOUVEAU_BUFFER_STATUS_DIRTY)) + (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)) nouveau_buffer_download(pipe, res, 0, res->base.width0); if ((res->domain != NOUVEAU_BO_GART) || diff --git a/src/gallium/drivers/nv50/nv50_3d.xml.h b/src/gallium/drivers/nv50/nv50_3d.xml.h index eb05bd4095..9bb3211728 100644 --- a/src/gallium/drivers/nv50/nv50_3d.xml.h +++ b/src/gallium/drivers/nv50/nv50_3d.xml.h @@ -74,7 +74,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +#define NV50_3D_SERIALIZE 0x00000110 #define NV50_3D_DMA_NOTIFY 0x00000180 diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index eb9743a05d..3886d8068c 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -93,6 +93,11 @@ nv50_resource_validate(struct nv04_resource *res, uint32_t flags) if (likely(res->bo)) { nouveau_bo_validate(screen->base.channel, res->bo, flags); + if (flags & NOUVEAU_BO_WR) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + if (flags & NOUVEAU_BO_RD) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_resource_fence(res, flags); } } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index a8f48b2a28..c97927624e 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -8,6 +8,7 @@ nv50_validate_fb(struct nv50_context *nv50) struct nouveau_channel *chan = nv50->screen->base.channel; struct pipe_framebuffer_state *fb = &nv50->framebuffer; unsigned i; + boolean serialize = FALSE; nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME); @@ -37,6 +38,11 @@ nv50_validate_fb(struct nv50_context *nv50) BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); OUT_RING (chan, sf->depth); + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) + serialize = TRUE; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); } @@ -62,6 +68,11 @@ nv50_validate_fb(struct nv50_context *nv50) OUT_RING (chan, sf->height); OUT_RING (chan, (unk << 16) | sf->depth); + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) + serialize = TRUE; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); } else { @@ -72,6 +83,11 @@ nv50_validate_fb(struct nv50_context *nv50) BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); OUT_RING (chan, fb->width << 16); OUT_RING (chan, fb->height << 16); + + if (serialize) { + BEGIN_RING(chan, RING_3D(SERIALIZE), 1); + OUT_RING (chan, 0); + } } static void diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index eaee0a1107..a76139ad37 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -212,9 +212,17 @@ nv50_validate_tic(struct nv50_context *nv50, int s) OUT_RINGp (chan, &tic->tic[3], 5); need_flush = TRUE; + } else + if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { + BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); + OUT_RING (chan, 0x20); //(tic->id << 4) | 1); } + nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); + res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h index 35e79210a6..afa2a00c7a 100644 --- a/src/gallium/drivers/nv50/nv50_winsys.h +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -81,7 +81,7 @@ OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { if (flags & NOUVEAU_BO_WR) - res->status |= NOUVEAU_BUFFER_STATUS_DIRTY; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); } -- cgit v1.2.3 From 1ba8e9510812f155359d380bda6876cdee5ba21e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 15:28:26 +1000 Subject: nouveau: ensure vbo_dirty is set when buffer write transfer complete This introduces a shared nouveau_context struct to track such things. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 47 +++++------ src/gallium/drivers/nouveau/nouveau_buffer.h | 9 +- src/gallium/drivers/nouveau/nouveau_context.h | 26 ++++++ src/gallium/drivers/nouveau/nouveau_screen.h | 7 -- src/gallium/drivers/nv50/nv50_context.c | 26 +++--- src/gallium/drivers/nv50/nv50_context.h | 8 +- src/gallium/drivers/nv50/nv50_push.c | 4 +- src/gallium/drivers/nv50/nv50_query.c | 14 ++-- src/gallium/drivers/nv50/nv50_screen.c | 2 - src/gallium/drivers/nv50/nv50_shader_state.c | 4 +- src/gallium/drivers/nv50/nv50_state.c | 100 +++++++++++----------- src/gallium/drivers/nv50/nv50_surface.c | 8 +- src/gallium/drivers/nv50/nv50_tex.c | 2 +- src/gallium/drivers/nv50/nv50_transfer.c | 10 +-- src/gallium/drivers/nv50/nv50_vbo.c | 18 ++-- src/gallium/drivers/nvc0/nvc0_context.c | 26 +++--- src/gallium/drivers/nvc0/nvc0_context.h | 9 +- src/gallium/drivers/nvc0/nvc0_push.c | 4 +- src/gallium/drivers/nvc0/nvc0_query.c | 14 ++-- src/gallium/drivers/nvc0/nvc0_screen.c | 2 - src/gallium/drivers/nvc0/nvc0_shader_state.c | 4 +- src/gallium/drivers/nvc0/nvc0_state.c | 116 +++++++++++++------------- src/gallium/drivers/nvc0/nvc0_surface.c | 8 +- src/gallium/drivers/nvc0/nvc0_tex.c | 2 +- src/gallium/drivers/nvc0/nvc0_transfer.c | 10 +-- src/gallium/drivers/nvc0/nvc0_vbo.c | 18 ++-- 26 files changed, 267 insertions(+), 231 deletions(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_context.h (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c') diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index efb16824e4..571fa0c608 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -4,6 +4,7 @@ #include "util/u_math.h" #include "nouveau_screen.h" +#include "nouveau_context.h" #include "nouveau_winsys.h" #include "nouveau_fence.h" #include "nouveau_buffer.h" @@ -90,22 +91,21 @@ nouveau_buffer_destroy(struct pipe_screen *pscreen, /* Maybe just migrate to GART right away if we actually need to do this. */ boolean -nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, +nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf, unsigned start, unsigned size) { - struct nouveau_screen *screen = nouveau_screen(pipe->screen); struct nouveau_mm_allocation *mm; struct nouveau_bo *bounce = NULL; uint32_t offset; assert(buf->domain == NOUVEAU_BO_VRAM); - mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; - screen->copy_data(pipe, bounce, offset, NOUVEAU_BO_GART, - buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size); + nv->copy_data(nv, bounce, offset, NOUVEAU_BO_GART, + buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size); if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD)) return FALSE; @@ -121,21 +121,20 @@ nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, } static boolean -nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, +nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf, unsigned start, unsigned size) { - struct nouveau_screen *screen = nouveau_screen(pipe->screen); struct nouveau_mm_allocation *mm; struct nouveau_bo *bounce = NULL; uint32_t offset; if (size <= 192) { - screen->push_data(pipe, buf->bo, buf->offset + start, buf->domain, - size, buf->data + start); + nv->push_data(nv, buf->bo, buf->offset + start, buf->domain, + size, buf->data + start); return TRUE; } - mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -144,12 +143,12 @@ nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, memcpy(bounce->map, buf->data + start, size); nouveau_bo_unmap(bounce); - screen->copy_data(pipe, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, - bounce, offset, NOUVEAU_BO_GART, size); + nv->copy_data(nv, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, + bounce, offset, NOUVEAU_BO_GART, size); nouveau_bo_ref(NULL, &bounce); if (mm) - release_allocation(&mm, screen->fence.current); + release_allocation(&mm, nv->screen->fence.current); if (start == 0 && size == buf->base.width0) buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; @@ -163,6 +162,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, const struct pipe_box *box) { struct nv04_resource *buf = nv04_resource(resource); + struct nouveau_context *nv = nouveau_context(pipe); struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_transfer); if (!xfr) return NULL; @@ -175,7 +175,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, if (buf->domain == NOUVEAU_BO_VRAM) { if (usage & PIPE_TRANSFER_READ) { if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) - nouveau_buffer_download(pipe, buf, 0, buf->base.width0); + nouveau_buffer_download(nv, buf, 0, buf->base.width0); } } @@ -188,20 +188,19 @@ nouveau_buffer_transfer_destroy(struct pipe_context *pipe, { struct nv04_resource *buf = nv04_resource(transfer->resource); struct nouveau_transfer *xfr = nouveau_transfer(transfer); + struct nouveau_context *nv = nouveau_context(pipe); if (xfr->base.usage & PIPE_TRANSFER_WRITE) { /* writing is worse */ - nouveau_buffer_adjust_score(pipe, buf, -5000); + nouveau_buffer_adjust_score(nv, buf, -5000); if (buf->domain == NOUVEAU_BO_VRAM) { - nouveau_buffer_upload(pipe, buf, transfer->box.x, transfer->box.width); + nouveau_buffer_upload(nv, buf, transfer->box.x, transfer->box.width); } -#if 0 if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))) nouveau_context(pipe)->vbo_dirty = TRUE; -#endif } FREE(xfr); @@ -249,7 +248,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, uint32_t offset = xfr->base.box.x; uint32_t flags; - nouveau_buffer_adjust_score(pipe, buf, -250); + nouveau_buffer_adjust_score(nouveau_context(pipe), buf, -250); if (buf->domain != NOUVEAU_BO_GART) return buf->data + offset; @@ -403,10 +402,10 @@ nouveau_buffer_data_fetch(struct nv04_resource *buf, struct nouveau_bo *bo, /* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */ boolean -nouveau_buffer_migrate(struct pipe_context *pipe, +nouveau_buffer_migrate(struct nouveau_context *nv, struct nv04_resource *buf, const unsigned new_domain) { - struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_screen *screen = nv->screen; struct nouveau_bo *bo; const unsigned old_domain = buf->domain; unsigned size = buf->base.width0; @@ -442,8 +441,8 @@ nouveau_buffer_migrate(struct pipe_context *pipe, buf->mm = NULL; nouveau_buffer_allocate(screen, buf, new_domain); - screen->copy_data(pipe, buf->bo, buf->offset, new_domain, - bo, offset, old_domain, buf->base.width0); + nv->copy_data(nv, buf->bo, buf->offset, new_domain, + bo, offset, old_domain, buf->base.width0); nouveau_bo_ref(NULL, &bo); if (mm) @@ -452,7 +451,7 @@ nouveau_buffer_migrate(struct pipe_context *pipe, if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { if (!nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) return FALSE; - if (!nouveau_buffer_upload(pipe, buf, 0, buf->base.width0)) + if (!nouveau_buffer_upload(nv, buf, 0, buf->base.width0)) return FALSE; } else return FALSE; diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h index c3e0c2cf92..46e3554bdf 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.h +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -5,6 +5,7 @@ #include "util/u_double_list.h" struct pipe_resource; +struct nouveau_context; struct nouveau_bo; #define NOUVEAU_BUFFER_SCORE_MIN -25000 @@ -50,15 +51,15 @@ void nouveau_buffer_release_gpu_storage(struct nv04_resource *); boolean -nouveau_buffer_download(struct pipe_context *, struct nv04_resource *, +nouveau_buffer_download(struct nouveau_context *, struct nv04_resource *, unsigned start, unsigned size); boolean -nouveau_buffer_migrate(struct pipe_context *, +nouveau_buffer_migrate(struct nouveau_context *, struct nv04_resource *, unsigned domain); static INLINE void -nouveau_buffer_adjust_score(struct pipe_context *pipe, +nouveau_buffer_adjust_score(struct nouveau_context *pipe, struct nv04_resource *res, int16_t score) { if (score < 0) { @@ -76,7 +77,7 @@ nouveau_buffer_adjust_score(struct pipe_context *pipe, /* XXX: wait for fence (atm only using this for vertex push) */ static INLINE void * -nouveau_resource_map_offset(struct pipe_context *pipe, +nouveau_resource_map_offset(struct nouveau_context *pipe, struct nv04_resource *res, uint32_t offset, uint32_t flags) { diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h new file mode 100644 index 0000000000..696e0d3f24 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -0,0 +1,26 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "pipe/p_context.h" + +struct nouveau_context { + struct pipe_context pipe; + struct nouveau_screen *screen; + + boolean vbo_dirty; + + void (*copy_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + struct nouveau_bo *src, unsigned, unsigned, unsigned); + void (*push_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + unsigned, void *); +}; + +static INLINE struct nouveau_context * +nouveau_context(struct pipe_context *pipe) +{ + return (struct nouveau_context *)pipe; +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index c64b7b16ad..580b4da6b4 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -29,13 +29,6 @@ struct nouveau_screen { struct nouveau_mman *mm_VRAM; struct nouveau_mman *mm_GART; - void (*copy_data)(struct pipe_context *, - struct nouveau_bo *dst, unsigned, unsigned, - struct nouveau_bo *src, unsigned, unsigned, - unsigned); - void (*push_data)(struct pipe_context *, - struct nouveau_bo *dst, unsigned, unsigned, - unsigned, void *); }; static INLINE struct nouveau_screen * diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 03a5c3d2d9..912367b839 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -84,22 +84,28 @@ nv50_create(struct pipe_screen *pscreen, void *priv) struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nv50_screen *screen = nv50_screen(pscreen); struct nv50_context *nv50; + struct pipe_context *pipe; nv50 = CALLOC_STRUCT(nv50_context); if (!nv50) return NULL; + pipe = &nv50->base.pipe; + nv50->screen = screen; + nv50->base.screen = &screen->base; + nv50->base.copy_data = nv50_m2mf_copy_linear; + nv50->base.push_data = nv50_sifc_linear_u8; - nv50->pipe.winsys = pipe_winsys; - nv50->pipe.screen = pscreen; - nv50->pipe.priv = priv; + pipe->winsys = pipe_winsys; + pipe->screen = pscreen; + pipe->priv = priv; - nv50->pipe.destroy = nv50_destroy; + pipe->destroy = nv50_destroy; - nv50->pipe.draw_vbo = nv50_draw_vbo; - nv50->pipe.clear = nv50_clear; + pipe->draw_vbo = nv50_draw_vbo; + pipe->clear = nv50_clear; - nv50->pipe.flush = nv50_flush; + pipe->flush = nv50_flush; if (!screen->cur_ctx) screen->cur_ctx = nv50; @@ -109,13 +115,13 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50_init_query_functions(nv50); nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); - nv50_init_resource_functions(&nv50->pipe); + nv50_init_resource_functions(pipe); - nv50->draw = draw_create(&nv50->pipe); + nv50->draw = draw_create(pipe); assert(nv50->draw); draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); - return &nv50->pipe; + return pipe; } struct resident { diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 55d996da27..e6079a621a 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -19,6 +19,7 @@ #include "nv50_program.h" #include "nv50_resource.h" +#include "nouveau/nouveau_context.h" #include "nouveau/nv_object.xml.h" #include "nouveau/nv_m2mf.xml.h" #include "nv50_3ddefs.xml.h" @@ -67,7 +68,7 @@ #define NV50_CB_AUX 127 struct nv50_context { - struct pipe_context pipe; + struct nouveau_context base; struct nv50_screen *screen; @@ -122,7 +123,6 @@ struct nv50_context { unsigned sample_mask; - boolean vbo_dirty; boolean vbo_push_hint; struct draw_context *draw; @@ -204,11 +204,11 @@ nv50_create_sampler_view(struct pipe_context *, /* nv50_transfer.c */ void -nv50_sifc_linear_u8(struct pipe_context *pipe, +nv50_sifc_linear_u8(struct nouveau_context *pipe, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nv50_m2mf_copy_linear(struct pipe_context *pipe, +nv50_m2mf_copy_linear(struct nouveau_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 07034bdcf6..71b5995a4f 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -229,7 +229,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; struct nv04_resource *res = nv04_resource(vb->buffer); - data = nouveau_resource_map_offset(&nv50->pipe, res, + data = nouveau_resource_map_offset(&nv50->base, res, vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i)))) @@ -239,7 +239,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nouveau_resource_map_offset(&nv50->pipe, + ctx.idxbuf = nouveau_resource_map_offset(&nv50->base, nv04_resource(nv50->idxbuf.buffer), nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 2e65c54e54..2dce94a477 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -326,10 +326,12 @@ nv50_render_condition(struct pipe_context *pipe, void nv50_init_query_functions(struct nv50_context *nv50) { - nv50->pipe.create_query = nv50_query_create; - nv50->pipe.destroy_query = nv50_query_destroy; - nv50->pipe.begin_query = nv50_query_begin; - nv50->pipe.end_query = nv50_query_end; - nv50->pipe.get_query_result = nv50_query_result; - nv50->pipe.render_condition = nv50_render_condition; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->create_query = nv50_query_create; + pipe->destroy_query = nv50_query_destroy; + pipe->begin_query = nv50_query_begin; + pipe->end_query = nv50_query_end; + pipe->get_query_result = nv50_query_result; + pipe->render_condition = nv50_render_condition; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 13c03b1a7e..f2b03e8156 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -310,8 +310,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART; - screen->base.copy_data = nv50_m2mf_copy_linear; - screen->base.push_data = nv50_sifc_linear_u8; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 2d7572820f..7d4b12bde1 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -76,7 +76,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) assert(0); if (!nouveau_resource_mapped_by_gpu(&res->base)) { - nouveau_buffer_migrate(&nv50->pipe, res, NOUVEAU_BO_VRAM); + nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM); BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1); OUT_RING (chan, 0); @@ -149,7 +149,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) return FALSE; prog->code_base = prog->res->start; - nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->code, + nv50_sifc_linear_u8(&nv50->base, nv50->screen->code, (prog->type << 16) + prog->code_base, NOUVEAU_BO_VRAM, prog->code_size, prog->code); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 6b1106341c..17f272bb3b 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -793,55 +793,57 @@ nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso) void nv50_init_state_functions(struct nv50_context *nv50) { - nv50->pipe.create_blend_state = nv50_blend_state_create; - nv50->pipe.bind_blend_state = nv50_blend_state_bind; - nv50->pipe.delete_blend_state = nv50_blend_state_delete; - - nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create; - nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind; - nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete; - - nv50->pipe.create_depth_stencil_alpha_state = nv50_zsa_state_create; - nv50->pipe.bind_depth_stencil_alpha_state = nv50_zsa_state_bind; - nv50->pipe.delete_depth_stencil_alpha_state = nv50_zsa_state_delete; - - nv50->pipe.create_sampler_state = nv50_sampler_state_create; - nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; - nv50->pipe.bind_vertex_sampler_states = nv50_vp_sampler_states_bind; - nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_states_bind; - nv50->pipe.bind_geometry_sampler_states = nv50_gp_sampler_states_bind; - - nv50->pipe.create_sampler_view = nv50_create_sampler_view; - nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy; - nv50->pipe.set_vertex_sampler_views = nv50_vp_set_sampler_views; - nv50->pipe.set_fragment_sampler_views = nv50_fp_set_sampler_views; - nv50->pipe.set_geometry_sampler_views = nv50_gp_set_sampler_views; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->create_blend_state = nv50_blend_state_create; + pipe->bind_blend_state = nv50_blend_state_bind; + pipe->delete_blend_state = nv50_blend_state_delete; + + pipe->create_rasterizer_state = nv50_rasterizer_state_create; + pipe->bind_rasterizer_state = nv50_rasterizer_state_bind; + pipe->delete_rasterizer_state = nv50_rasterizer_state_delete; + + pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create; + pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind; + pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete; + + pipe->create_sampler_state = nv50_sampler_state_create; + pipe->delete_sampler_state = nv50_sampler_state_delete; + pipe->bind_vertex_sampler_states = nv50_vp_sampler_states_bind; + pipe->bind_fragment_sampler_states = nv50_fp_sampler_states_bind; + pipe->bind_geometry_sampler_states = nv50_gp_sampler_states_bind; + + pipe->create_sampler_view = nv50_create_sampler_view; + pipe->sampler_view_destroy = nv50_sampler_view_destroy; + pipe->set_vertex_sampler_views = nv50_vp_set_sampler_views; + pipe->set_fragment_sampler_views = nv50_fp_set_sampler_views; + pipe->set_geometry_sampler_views = nv50_gp_set_sampler_views; - nv50->pipe.create_vs_state = nv50_vp_state_create; - nv50->pipe.create_fs_state = nv50_fp_state_create; - nv50->pipe.create_gs_state = nv50_gp_state_create; - nv50->pipe.bind_vs_state = nv50_vp_state_bind; - nv50->pipe.bind_fs_state = nv50_fp_state_bind; - nv50->pipe.bind_gs_state = nv50_gp_state_bind; - nv50->pipe.delete_vs_state = nv50_sp_state_delete; - nv50->pipe.delete_fs_state = nv50_sp_state_delete; - nv50->pipe.delete_gs_state = nv50_sp_state_delete; - - nv50->pipe.set_blend_color = nv50_set_blend_color; - nv50->pipe.set_stencil_ref = nv50_set_stencil_ref; - nv50->pipe.set_clip_state = nv50_set_clip_state; - nv50->pipe.set_sample_mask = nv50_set_sample_mask; - nv50->pipe.set_constant_buffer = nv50_set_constant_buffer; - nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state; - nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple; - nv50->pipe.set_scissor_state = nv50_set_scissor_state; - nv50->pipe.set_viewport_state = nv50_set_viewport_state; - - nv50->pipe.create_vertex_elements_state = nv50_vertex_state_create; - nv50->pipe.delete_vertex_elements_state = nv50_vertex_state_delete; - nv50->pipe.bind_vertex_elements_state = nv50_vertex_state_bind; - - nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; - nv50->pipe.set_index_buffer = nv50_set_index_buffer; + pipe->create_vs_state = nv50_vp_state_create; + pipe->create_fs_state = nv50_fp_state_create; + pipe->create_gs_state = nv50_gp_state_create; + pipe->bind_vs_state = nv50_vp_state_bind; + pipe->bind_fs_state = nv50_fp_state_bind; + pipe->bind_gs_state = nv50_gp_state_bind; + pipe->delete_vs_state = nv50_sp_state_delete; + pipe->delete_fs_state = nv50_sp_state_delete; + pipe->delete_gs_state = nv50_sp_state_delete; + + pipe->set_blend_color = nv50_set_blend_color; + pipe->set_stencil_ref = nv50_set_stencil_ref; + pipe->set_clip_state = nv50_set_clip_state; + pipe->set_sample_mask = nv50_set_sample_mask; + pipe->set_constant_buffer = nv50_set_constant_buffer; + pipe->set_framebuffer_state = nv50_set_framebuffer_state; + pipe->set_polygon_stipple = nv50_set_polygon_stipple; + pipe->set_scissor_state = nv50_set_scissor_state; + pipe->set_viewport_state = nv50_set_viewport_state; + + pipe->create_vertex_elements_state = nv50_vertex_state_create; + pipe->delete_vertex_elements_state = nv50_vertex_state_delete; + pipe->bind_vertex_elements_state = nv50_vertex_state_bind; + + pipe->set_vertex_buffers = nv50_set_vertex_buffers; + pipe->set_index_buffer = nv50_set_index_buffer; } diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index b1f54f623a..dc9e2880f0 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -371,9 +371,11 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.resource_copy_region = nv50_resource_copy_region; - nv50->pipe.clear_render_target = nv50_clear_render_target; - nv50->pipe.clear_depth_stencil = nv50_clear_depth_stencil; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->resource_copy_region = nv50_resource_copy_region; + pipe->clear_render_target = nv50_clear_render_target; + pipe->clear_depth_stencil = nv50_clear_depth_stencil; } diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index a76139ad37..4456553a86 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -269,7 +269,7 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) if (tsc->id < 0) { tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc); - nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->txc, + nv50_sifc_linear_u8(&nv50->base, nv50->screen->txc, 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, 32, tsc->tsc); need_flush = TRUE; diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index d80a535490..7486977459 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -102,12 +102,11 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nv50_sifc_linear_u8(struct pipe_context *pipe, +nv50_sifc_linear_u8(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; unsigned xcoord = offset & 0xff; @@ -159,13 +158,12 @@ nv50_sifc_linear_u8(struct pipe_context *pipe, } void -nv50_m2mf_copy_linear(struct pipe_context *pipe, +nv50_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); OUT_RING (chan, 1); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 1f0d34ed79..e94a2b6fa3 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -131,7 +131,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, float v[4]; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nouveau_resource_map_offset(&nv50->pipe, res, vb->buffer_offset + + data = nouveau_resource_map_offset(&nv50->base, res, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_RD); util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); @@ -215,13 +215,13 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50) nv50_vbuf_range(nv50, i, &base, &size); nouveau_user_buffer_upload(buf, base, size); } else { - nouveau_buffer_migrate(&nv50->pipe, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART); } - nv50->vbo_dirty = TRUE; + nv50->base.vbo_dirty = TRUE; } } nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nouveau_buffer_adjust_score(&nv50->pipe, buf, 1); + nouveau_buffer_adjust_score(&nv50->base, buf, 1); } } @@ -262,7 +262,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50) OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } - nv50->vbo_dirty = TRUE; + nv50->base.vbo_dirty = TRUE; } static INLINE void @@ -540,7 +540,7 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); unsigned offset = res->offset + nv50->idxbuf.offset; - nouveau_buffer_adjust_score(&nv50->pipe, res, 1); + nouveau_buffer_adjust_score(&nv50->base, res, 1); while (instance_count--) { BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); @@ -597,7 +597,7 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nouveau_resource_map_offset(&nv50->pipe, + data = nouveau_resource_map_offset(&nv50->base, nv04_resource(nv50->idxbuf.buffer), nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!data) @@ -669,10 +669,10 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) OUT_RING (chan, info->start_instance); } - if (nv50->vbo_dirty) { + if (nv50->base.vbo_dirty) { BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); - nv50->vbo_dirty = FALSE; + nv50->base.vbo_dirty = FALSE; } if (!info->indexed) { diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index 4979aab51c..d5dcf1fb02 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -84,22 +84,28 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nvc0_screen *screen = nvc0_screen(pscreen); struct nvc0_context *nvc0; + struct pipe_context *pipe; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; + pipe = &nvc0->base.pipe; + nvc0->screen = screen; + nvc0->base.screen = &screen->base; + nvc0->base.copy_data = nvc0_m2mf_copy_linear; + nvc0->base.push_data = nvc0_m2mf_push_linear; - nvc0->pipe.winsys = pipe_winsys; - nvc0->pipe.screen = pscreen; - nvc0->pipe.priv = priv; + pipe->winsys = pipe_winsys; + pipe->screen = pscreen; + pipe->priv = priv; - nvc0->pipe.destroy = nvc0_destroy; + pipe->destroy = nvc0_destroy; - nvc0->pipe.draw_vbo = nvc0_draw_vbo; - nvc0->pipe.clear = nvc0_clear; + pipe->draw_vbo = nvc0_draw_vbo; + pipe->clear = nvc0_clear; - nvc0->pipe.flush = nvc0_flush; + pipe->flush = nvc0_flush; if (!screen->cur_ctx) screen->cur_ctx = nvc0; @@ -109,13 +115,13 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); nvc0_init_state_functions(nvc0); - nvc0_init_resource_functions(&nvc0->pipe); + nvc0_init_resource_functions(pipe); - nvc0->draw = draw_create(&nvc0->pipe); + nvc0->draw = draw_create(pipe); assert(nvc0->draw); draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0)); - return &nvc0->pipe; + return pipe; } struct resident { diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index d779777ed3..114e664fc5 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -19,6 +19,8 @@ #include "nvc0_program.h" #include "nvc0_resource.h" +#include "nouveau/nouveau_context.h" + #include "nvc0_3ddefs.xml.h" #include "nvc0_3d.xml.h" #include "nvc0_2d.xml.h" @@ -64,7 +66,7 @@ #define NVC0_BUFCTX_COUNT 4 struct nvc0_context { - struct pipe_context pipe; + struct nouveau_context base; struct nvc0_screen *screen; @@ -123,7 +125,6 @@ struct nvc0_context { unsigned sample_mask; - boolean vbo_dirty; boolean vbo_push_hint; struct nvc0_transform_feedback_state *tfb; @@ -211,11 +212,11 @@ nvc0_create_sampler_view(struct pipe_context *, /* nvc0_transfer.c */ void -nvc0_m2mf_push_linear(struct pipe_context *pipe, +nvc0_m2mf_push_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nvc0_m2mf_copy_linear(struct pipe_context *pipe, +nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index 84533f0443..68544c90d2 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -229,7 +229,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i]; struct nv04_resource *res = nv04_resource(vb->buffer); - data = nouveau_resource_map_offset(&nvc0->pipe, res, + data = nouveau_resource_map_offset(&nvc0->base, res, vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nvc0->vertex->instance_bufs & (1 << i)))) @@ -239,7 +239,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nouveau_resource_map_offset(&nvc0->pipe, + ctx.idxbuf = nouveau_resource_map_offset(&nvc0->base, nv04_resource(nvc0->idxbuf.buffer), nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c index 338359bdfd..ead015b6b8 100644 --- a/src/gallium/drivers/nvc0/nvc0_query.c +++ b/src/gallium/drivers/nvc0/nvc0_query.c @@ -330,10 +330,12 @@ nvc0_render_condition(struct pipe_context *pipe, void nvc0_init_query_functions(struct nvc0_context *nvc0) { - nvc0->pipe.create_query = nvc0_query_create; - nvc0->pipe.destroy_query = nvc0_query_destroy; - nvc0->pipe.begin_query = nvc0_query_begin; - nvc0->pipe.end_query = nvc0_query_end; - nvc0->pipe.get_query_result = nvc0_query_result; - nvc0->pipe.render_condition = nvc0_render_condition; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->create_query = nvc0_query_create; + pipe->destroy_query = nvc0_query_destroy; + pipe->begin_query = nvc0_query_begin; + pipe->end_query = nvc0_query_end; + pipe->get_query_result = nvc0_query_result; + pipe->render_condition = nvc0_render_condition; } diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 82209c58c2..b84a1bee8d 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -377,8 +377,6 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; screen->base.index_buffer_flags = 0; - screen->base.copy_data = nvc0_m2mf_copy_linear; - screen->base.push_data = nvc0_m2mf_push_linear; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 765f1dae57..79b5f3d81c 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -59,9 +59,9 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) prog->code_base = prog->res->start; - nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->text, prog->code_base, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base, NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr); - nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->text, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base + NVC0_SHADER_HEADER_SIZE, NOUVEAU_BO_VRAM, prog->code_size, prog->code); diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 36c751e251..ee4680efec 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -876,62 +876,64 @@ nvc0_set_transform_feedback_buffers(struct pipe_context *pipe, void nvc0_init_state_functions(struct nvc0_context *nvc0) { - nvc0->pipe.create_blend_state = nvc0_blend_state_create; - nvc0->pipe.bind_blend_state = nvc0_blend_state_bind; - nvc0->pipe.delete_blend_state = nvc0_blend_state_delete; - - nvc0->pipe.create_rasterizer_state = nvc0_rasterizer_state_create; - nvc0->pipe.bind_rasterizer_state = nvc0_rasterizer_state_bind; - nvc0->pipe.delete_rasterizer_state = nvc0_rasterizer_state_delete; - - nvc0->pipe.create_depth_stencil_alpha_state = nvc0_zsa_state_create; - nvc0->pipe.bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; - nvc0->pipe.delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; - - nvc0->pipe.create_sampler_state = nvc0_sampler_state_create; - nvc0->pipe.delete_sampler_state = nvc0_sampler_state_delete; - nvc0->pipe.bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; - nvc0->pipe.bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; - nvc0->pipe.bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; - - nvc0->pipe.create_sampler_view = nvc0_create_sampler_view; - nvc0->pipe.sampler_view_destroy = nvc0_sampler_view_destroy; - nvc0->pipe.set_vertex_sampler_views = nvc0_vp_set_sampler_views; - nvc0->pipe.set_fragment_sampler_views = nvc0_fp_set_sampler_views; - nvc0->pipe.set_geometry_sampler_views = nvc0_gp_set_sampler_views; - - nvc0->pipe.create_vs_state = nvc0_vp_state_create; - nvc0->pipe.create_fs_state = nvc0_fp_state_create; - nvc0->pipe.create_gs_state = nvc0_gp_state_create; - nvc0->pipe.bind_vs_state = nvc0_vp_state_bind; - nvc0->pipe.bind_fs_state = nvc0_fp_state_bind; - nvc0->pipe.bind_gs_state = nvc0_gp_state_bind; - nvc0->pipe.delete_vs_state = nvc0_sp_state_delete; - nvc0->pipe.delete_fs_state = nvc0_sp_state_delete; - nvc0->pipe.delete_gs_state = nvc0_sp_state_delete; - - nvc0->pipe.set_blend_color = nvc0_set_blend_color; - nvc0->pipe.set_stencil_ref = nvc0_set_stencil_ref; - nvc0->pipe.set_clip_state = nvc0_set_clip_state; - nvc0->pipe.set_sample_mask = nvc0_set_sample_mask; - nvc0->pipe.set_constant_buffer = nvc0_set_constant_buffer; - nvc0->pipe.set_framebuffer_state = nvc0_set_framebuffer_state; - nvc0->pipe.set_polygon_stipple = nvc0_set_polygon_stipple; - nvc0->pipe.set_scissor_state = nvc0_set_scissor_state; - nvc0->pipe.set_viewport_state = nvc0_set_viewport_state; - - nvc0->pipe.create_vertex_elements_state = nvc0_vertex_state_create; - nvc0->pipe.delete_vertex_elements_state = nvc0_vertex_state_delete; - nvc0->pipe.bind_vertex_elements_state = nvc0_vertex_state_bind; - - nvc0->pipe.set_vertex_buffers = nvc0_set_vertex_buffers; - nvc0->pipe.set_index_buffer = nvc0_set_index_buffer; - - nvc0->pipe.create_stream_output_state = nvc0_tfb_state_create; - nvc0->pipe.delete_stream_output_state = nvc0_tfb_state_delete; - nvc0->pipe.bind_stream_output_state = nvc0_tfb_state_bind; - nvc0->pipe.set_stream_output_buffers = nvc0_set_transform_feedback_buffers; - - nvc0->pipe.redefine_user_buffer = u_default_redefine_user_buffer; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->create_blend_state = nvc0_blend_state_create; + pipe->bind_blend_state = nvc0_blend_state_bind; + pipe->delete_blend_state = nvc0_blend_state_delete; + + pipe->create_rasterizer_state = nvc0_rasterizer_state_create; + pipe->bind_rasterizer_state = nvc0_rasterizer_state_bind; + pipe->delete_rasterizer_state = nvc0_rasterizer_state_delete; + + pipe->create_depth_stencil_alpha_state = nvc0_zsa_state_create; + pipe->bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; + pipe->delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; + + pipe->create_sampler_state = nvc0_sampler_state_create; + pipe->delete_sampler_state = nvc0_sampler_state_delete; + pipe->bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; + pipe->bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; + pipe->bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; + + pipe->create_sampler_view = nvc0_create_sampler_view; + pipe->sampler_view_destroy = nvc0_sampler_view_destroy; + pipe->set_vertex_sampler_views = nvc0_vp_set_sampler_views; + pipe->set_fragment_sampler_views = nvc0_fp_set_sampler_views; + pipe->set_geometry_sampler_views = nvc0_gp_set_sampler_views; + + pipe->create_vs_state = nvc0_vp_state_create; + pipe->create_fs_state = nvc0_fp_state_create; + pipe->create_gs_state = nvc0_gp_state_create; + pipe->bind_vs_state = nvc0_vp_state_bind; + pipe->bind_fs_state = nvc0_fp_state_bind; + pipe->bind_gs_state = nvc0_gp_state_bind; + pipe->delete_vs_state = nvc0_sp_state_delete; + pipe->delete_fs_state = nvc0_sp_state_delete; + pipe->delete_gs_state = nvc0_sp_state_delete; + + pipe->set_blend_color = nvc0_set_blend_color; + pipe->set_stencil_ref = nvc0_set_stencil_ref; + pipe->set_clip_state = nvc0_set_clip_state; + pipe->set_sample_mask = nvc0_set_sample_mask; + pipe->set_constant_buffer = nvc0_set_constant_buffer; + pipe->set_framebuffer_state = nvc0_set_framebuffer_state; + pipe->set_polygon_stipple = nvc0_set_polygon_stipple; + pipe->set_scissor_state = nvc0_set_scissor_state; + pipe->set_viewport_state = nvc0_set_viewport_state; + + pipe->create_vertex_elements_state = nvc0_vertex_state_create; + pipe->delete_vertex_elements_state = nvc0_vertex_state_delete; + pipe->bind_vertex_elements_state = nvc0_vertex_state_bind; + + pipe->set_vertex_buffers = nvc0_set_vertex_buffers; + pipe->set_index_buffer = nvc0_set_index_buffer; + + pipe->create_stream_output_state = nvc0_tfb_state_create; + pipe->delete_stream_output_state = nvc0_tfb_state_delete; + pipe->bind_stream_output_state = nvc0_tfb_state_bind; + pipe->set_stream_output_buffers = nvc0_set_transform_feedback_buffers; + + pipe->redefine_user_buffer = u_default_redefine_user_buffer; } diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 6f39bbbb17..a4b2b94812 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -367,9 +367,11 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, void nvc0_init_surface_functions(struct nvc0_context *nvc0) { - nvc0->pipe.resource_copy_region = nvc0_resource_copy_region; - nvc0->pipe.clear_render_target = nvc0_clear_render_target; - nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->resource_copy_region = nvc0_resource_copy_region; + pipe->clear_render_target = nvc0_clear_render_target; + pipe->clear_depth_stencil = nvc0_clear_depth_stencil; } diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index f651e54e1d..6822e597b3 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -252,7 +252,7 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) if (tsc->id < 0) { tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); - nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->txc, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc, 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, 32, tsc->tsc); need_flush = TRUE; diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index bbb24fa052..a38bdb8f0a 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -104,12 +104,11 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nvc0_m2mf_push_linear(struct pipe_context *pipe, +nvc0_m2mf_push_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { - struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; @@ -144,13 +143,12 @@ nvc0_m2mf_push_linear(struct pipe_context *pipe, } void -nvc0_m2mf_copy_linear(struct pipe_context *pipe, +nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; while (size) { unsigned bytes = MIN2(size, 1 << 17); diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 14bea675a1..e7e7ce7dc2 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -136,7 +136,7 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, int i; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nouveau_resource_map_offset(&nvc0->pipe, res, vb->buffer_offset + + data = nouveau_resource_map_offset(&nvc0->base, res, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_RD); util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); @@ -193,13 +193,13 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) nvc0_vbuf_range(nvc0, i, &base, &size); nouveau_user_buffer_upload(buf, base, size); } else { - nouveau_buffer_migrate(&nvc0->pipe, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART); } - nvc0->vbo_dirty = TRUE; + nvc0->base.vbo_dirty = TRUE; } } nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nouveau_buffer_adjust_score(&nvc0->pipe, buf, 1); + nouveau_buffer_adjust_score(&nvc0->base, buf, 1); } } @@ -240,7 +240,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } - nvc0->vbo_dirty = TRUE; + nvc0->base.vbo_dirty = TRUE; } static INLINE void @@ -518,7 +518,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, unsigned offset = nvc0->idxbuf.offset; unsigned limit = nvc0->idxbuf.buffer->width0 - 1; - nouveau_buffer_adjust_score(&nvc0->pipe, res, 1); + nouveau_buffer_adjust_score(&nvc0->base, res, 1); while (instance_count--) { MARK_RING (chan, 11, 4); @@ -539,7 +539,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nouveau_resource_map_offset(&nvc0->pipe, + data = nouveau_resource_map_offset(&nvc0->base, nv04_resource(nvc0->idxbuf.buffer), nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!data) @@ -610,10 +610,10 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) OUT_RING (chan, info->start_instance); } - if (nvc0->vbo_dirty) { + if (nvc0->base.vbo_dirty) { BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); - nvc0->vbo_dirty = FALSE; + nvc0->base.vbo_dirty = FALSE; } if (!info->indexed) { -- cgit v1.2.3 From 6b4e3e8941f41b6d15ac557e3d47bf4f1aa8b185 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Mar 2011 15:56:20 +1000 Subject: nouveau: allow pipe driver to define which buffers should start in sysmem PIPE_BIND_CONSTANT_BUFFER alone was OK for nv50/nvc0, but nv30 will need to be able to set others on certain chipsets. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 2 +- src/gallium/drivers/nouveau/nouveau_screen.h | 1 + src/gallium/drivers/nv50/nv50_screen.c | 5 ++--- src/gallium/drivers/nvc0/nvc0_screen.c | 5 ++--- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c') diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 571fa0c608..d0cc29104b 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -340,7 +340,7 @@ nouveau_buffer_create(struct pipe_screen *pscreen, pipe_reference_init(&buffer->base.reference, 1); buffer->base.screen = pscreen; - if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) + if ((buffer->base.bind & screen->sysmem_bindings) == screen->sysmem_bindings) ret = nouveau_buffer_allocate(screen, buffer, 0); else ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 580b4da6b4..c091abf278 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -16,6 +16,7 @@ struct nouveau_screen { * these almost always should be set to the same value */ unsigned vertex_buffer_flags; unsigned index_buffer_flags; + unsigned sysmem_bindings; struct { struct nouveau_fence *head; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2bc26e5750..3f148436e8 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -293,6 +293,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; + screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; + ret = nouveau_screen_init(&screen->base, dev); if (ret) FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); @@ -309,9 +311,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nv50_screen_init_resource_functions(pscreen); - screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = - NOUVEAU_BO_GART; - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); if (ret) diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index b84a1bee8d..923bb83e8a 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -358,6 +358,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; + screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; + ret = nouveau_screen_init(&screen->base, dev); if (ret) { nvc0_screen_destroy(pscreen); @@ -375,9 +377,6 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nvc0_screen_init_resource_functions(pscreen); - screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; - screen->base.index_buffer_flags = 0; - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); if (ret) -- cgit v1.2.3