mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 06:30:10 +01:00
nouveau: switch to libdrm_nouveau-2.0
This commit is contained in:
parent
3c7872f35f
commit
6d1cdec3ba
58 changed files with 3717 additions and 3436 deletions
|
|
@ -39,7 +39,7 @@ LIBDRM_REQUIRED=2.4.24
|
|||
LIBDRM_RADEON_REQUIRED=2.4.31
|
||||
LIBDRM_INTEL_REQUIRED=2.4.32
|
||||
LIBDRM_NVVIEUX_REQUIRED=2.4.33
|
||||
LIBDRM_NOUVEAU_REQUIRED=0.6
|
||||
LIBDRM_NOUVEAU_REQUIRED=2.4.33
|
||||
DRI2PROTO_REQUIRED=2.6
|
||||
GLPROTO_REQUIRED=1.4.14
|
||||
LIBDRM_XORG_REQUIRED=2.4.24
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@ C_SOURCES := \
|
|||
nouveau_fence.c \
|
||||
nouveau_mm.c \
|
||||
nouveau_buffer.c \
|
||||
nouveau_heap.c \
|
||||
nouveau_video.c
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ nouveau_buffer_allocate(struct nouveau_screen *screen,
|
|||
}
|
||||
}
|
||||
buf->domain = domain;
|
||||
if (buf->bo)
|
||||
buf->address = buf->bo->offset + buf->offset;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -112,10 +115,9 @@ nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf,
|
|||
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))
|
||||
if (nouveau_bo_map(bounce, NOUVEAU_BO_RD, nv->screen->client))
|
||||
return FALSE;
|
||||
memcpy(buf->data + start, bounce->map, size);
|
||||
nouveau_bo_unmap(bounce);
|
||||
memcpy(buf->data + start, (uint8_t *)bounce->map + offset, size);
|
||||
|
||||
buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
|
||||
|
|
@ -147,10 +149,8 @@ nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf,
|
|||
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);
|
||||
nouveau_bo_map(bounce, 0, nv->screen->client);
|
||||
memcpy((uint8_t *)bounce->map + offset, buf->data + start, size);
|
||||
|
||||
nv->copy_data(nv, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM,
|
||||
bounce, offset, NOUVEAU_BO_GART, size);
|
||||
|
|
@ -246,34 +246,27 @@ static void *
|
|||
nouveau_buffer_transfer_map(struct pipe_context *pipe,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct nouveau_context *nv = nouveau_context(pipe);
|
||||
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;
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (buf->domain != NOUVEAU_BO_GART)
|
||||
return buf->data + offset;
|
||||
|
||||
if (buf->mm)
|
||||
flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR;
|
||||
else
|
||||
if (!buf->mm)
|
||||
flags = nouveau_screen_transfer_flags(xfr->base.usage);
|
||||
|
||||
offset += buf->offset;
|
||||
|
||||
ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags);
|
||||
ret = nouveau_bo_map(buf->bo, flags, nv->screen->client);
|
||||
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);
|
||||
map = (uint8_t *)bo->map + offset;
|
||||
|
||||
if (buf->mm) {
|
||||
if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) {
|
||||
|
|
@ -294,6 +287,7 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe,
|
|||
struct pipe_transfer *transfer,
|
||||
const struct pipe_box *box)
|
||||
{
|
||||
#if 0
|
||||
struct nv04_resource *res = nv04_resource(transfer->resource);
|
||||
struct nouveau_bo *bo = res->bo;
|
||||
unsigned offset = res->offset + transfer->box.x + box->x;
|
||||
|
|
@ -303,17 +297,43 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe,
|
|||
return;
|
||||
|
||||
/* XXX: maybe need to upload for VRAM buffers here */
|
||||
|
||||
nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
/* we've called nouveau_bo_unmap right after map */
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
nouveau_resource_map_offset(struct nouveau_context *nv,
|
||||
struct nv04_resource *res, uint32_t offset,
|
||||
uint32_t flags)
|
||||
{
|
||||
if ((res->domain == NOUVEAU_BO_VRAM) &&
|
||||
(res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING))
|
||||
nouveau_buffer_download(nv, res, 0, res->base.width0);
|
||||
|
||||
if ((res->domain != NOUVEAU_BO_GART) ||
|
||||
(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY))
|
||||
return res->data + offset;
|
||||
|
||||
if (res->mm) {
|
||||
unsigned rw;
|
||||
rw = (flags & NOUVEAU_BO_WR) ? PIPE_TRANSFER_WRITE : PIPE_TRANSFER_READ;
|
||||
nouveau_buffer_sync(res, rw);
|
||||
if (nouveau_bo_map(res->bo, 0, NULL))
|
||||
return NULL;
|
||||
} else {
|
||||
if (nouveau_bo_map(res->bo, flags, nv->screen->client))
|
||||
return NULL;
|
||||
}
|
||||
return (uint8_t *)res->bo->map + res->offset + offset;
|
||||
}
|
||||
|
||||
|
||||
const struct u_resource_vtbl nouveau_buffer_vtbl =
|
||||
{
|
||||
u_default_resource_get_handle, /* get_handle */
|
||||
|
|
@ -387,18 +407,17 @@ nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr,
|
|||
|
||||
/* 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)
|
||||
nouveau_buffer_data_fetch(struct nouveau_context *nv, 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))
|
||||
if (nouveau_bo_map(bo, NOUVEAU_BO_RD, nv->screen->client))
|
||||
return FALSE;
|
||||
memcpy(buf->data, bo->map, size);
|
||||
nouveau_bo_unmap(bo);
|
||||
memcpy(buf->data, (uint8_t *)bo->map + offset, size);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -420,12 +439,10 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
|
|||
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);
|
||||
ret = nouveau_bo_map(buf->bo, 0, nv->screen->client);
|
||||
if (ret)
|
||||
return ret;
|
||||
memcpy(buf->bo->map, buf->data, size);
|
||||
nouveau_bo_unmap(buf->bo);
|
||||
memcpy((uint8_t *)buf->bo->map + buf->offset, buf->data, size);
|
||||
FREE(buf->data);
|
||||
} else
|
||||
if (old_domain != 0 && new_domain != 0) {
|
||||
|
|
@ -433,7 +450,7 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
|
|||
|
||||
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))
|
||||
if (!nouveau_buffer_data_fetch(nv, buf, buf->bo, buf->offset, size))
|
||||
return FALSE;
|
||||
if (nouveau_mesa_debug)
|
||||
debug_printf("migrating %u KiB to VRAM\n", size / 1024);
|
||||
|
|
@ -469,7 +486,8 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
|
|||
* the vertex indices ...
|
||||
*/
|
||||
boolean
|
||||
nouveau_user_buffer_upload(struct nv04_resource *buf,
|
||||
nouveau_user_buffer_upload(struct nouveau_context *nv,
|
||||
struct nv04_resource *buf,
|
||||
unsigned base, unsigned size)
|
||||
{
|
||||
struct nouveau_screen *screen = nouveau_screen(buf->base.screen);
|
||||
|
|
@ -481,12 +499,10 @@ nouveau_user_buffer_upload(struct nv04_resource *buf,
|
|||
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);
|
||||
ret = nouveau_bo_map(buf->bo, 0, nv->screen->client);
|
||||
if (ret)
|
||||
return FALSE;
|
||||
memcpy(buf->bo->map, buf->data + base, size);
|
||||
nouveau_bo_unmap(buf->bo);
|
||||
memcpy((uint8_t *)buf->bo->map + buf->offset + base, buf->data + base, size);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ struct nv04_resource {
|
|||
struct pipe_resource base;
|
||||
const struct u_resource_vtbl *vtbl;
|
||||
|
||||
uint64_t address; /* virtual address (nv50+) */
|
||||
|
||||
uint8_t *data;
|
||||
struct nouveau_bo *bo;
|
||||
uint32_t offset;
|
||||
|
|
@ -52,33 +54,9 @@ boolean
|
|||
nouveau_buffer_migrate(struct nouveau_context *,
|
||||
struct nv04_resource *, unsigned domain);
|
||||
|
||||
/* XXX: wait for fence (atm only using this for vertex push) */
|
||||
static INLINE void *
|
||||
nouveau_resource_map_offset(struct nouveau_context *pipe,
|
||||
struct nv04_resource *res, uint32_t offset,
|
||||
uint32_t flags)
|
||||
{
|
||||
void *map;
|
||||
|
||||
if ((res->domain == NOUVEAU_BO_VRAM) &&
|
||||
(res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING))
|
||||
nouveau_buffer_download(pipe, res, 0, res->base.width0);
|
||||
|
||||
if ((res->domain != NOUVEAU_BO_GART) ||
|
||||
(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY))
|
||||
return res->data + offset;
|
||||
|
||||
if (res->mm)
|
||||
flags |= NOUVEAU_BO_NOSYNC;
|
||||
|
||||
if (nouveau_bo_map_range(res->bo, res->offset + offset,
|
||||
res->base.width0, flags))
|
||||
return NULL;
|
||||
|
||||
map = res->bo->map;
|
||||
nouveau_bo_unmap(res->bo);
|
||||
return map;
|
||||
}
|
||||
void *
|
||||
nouveau_resource_map_offset(struct nouveau_context *, struct nv04_resource *,
|
||||
uint32_t offset, uint32_t flags);
|
||||
|
||||
static INLINE void
|
||||
nouveau_resource_unmap(struct nv04_resource *res)
|
||||
|
|
@ -108,7 +86,7 @@ nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr,
|
|||
unsigned bytes, unsigned usage);
|
||||
|
||||
boolean
|
||||
nouveau_user_buffer_upload(struct nv04_resource *, unsigned base,
|
||||
unsigned size);
|
||||
nouveau_user_buffer_upload(struct nouveau_context *, struct nv04_resource *,
|
||||
unsigned base, unsigned size);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,10 +3,14 @@
|
|||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
struct nouveau_pushbuf;
|
||||
|
||||
struct nouveau_context {
|
||||
struct pipe_context pipe;
|
||||
struct nouveau_screen *screen;
|
||||
|
||||
struct nouveau_pushbuf *pushbuf;
|
||||
|
||||
boolean vbo_dirty;
|
||||
boolean cb_dirty;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@
|
|||
#include "util/u_double_list.h"
|
||||
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_winsys.h"
|
||||
#include "nouveau_fence.h"
|
||||
|
||||
#include "nouveau/nouveau_pushbuf.h"
|
||||
|
||||
#ifdef PIPE_OS_UNIX
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
|
@ -197,7 +196,7 @@ nouveau_fence_wait(struct nouveau_fence *fence)
|
|||
nouveau_fence_new(screen, &screen->fence.current, FALSE);
|
||||
}
|
||||
if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
|
||||
FIRE_RING(screen->channel);
|
||||
nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel);
|
||||
|
||||
do {
|
||||
nouveau_fence_update(screen, FALSE);
|
||||
|
|
|
|||
123
src/gallium/drivers/nouveau/nouveau_heap.c
Normal file
123
src/gallium/drivers/nouveau/nouveau_heap.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright 2007 Nouveau Project
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "nouveau_heap.h"
|
||||
|
||||
int
|
||||
nouveau_heap_init(struct nouveau_heap **heap,
|
||||
unsigned start, unsigned size)
|
||||
{
|
||||
struct nouveau_heap *r;
|
||||
|
||||
r = calloc(1, sizeof(struct nouveau_heap));
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
r->start = start;
|
||||
r->size = size;
|
||||
*heap = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_heap_destroy(struct nouveau_heap **heap)
|
||||
{
|
||||
if (!*heap)
|
||||
return;
|
||||
free(*heap);
|
||||
*heap = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv,
|
||||
struct nouveau_heap **res)
|
||||
{
|
||||
struct nouveau_heap *r;
|
||||
|
||||
if (!heap || !size || !res || *res)
|
||||
return 1;
|
||||
|
||||
while (heap) {
|
||||
if (!heap->in_use && heap->size >= size) {
|
||||
r = calloc(1, sizeof(struct nouveau_heap));
|
||||
if (!r)
|
||||
return 1;
|
||||
|
||||
r->start = (heap->start + heap->size) - size;
|
||||
r->size = size;
|
||||
r->in_use = 1;
|
||||
r->priv = priv;
|
||||
|
||||
heap->size -= size;
|
||||
|
||||
r->next = heap->next;
|
||||
if (heap->next)
|
||||
heap->next->prev = r;
|
||||
r->prev = heap;
|
||||
heap->next = r;
|
||||
|
||||
*res = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
heap = heap->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_heap_free(struct nouveau_heap **res)
|
||||
{
|
||||
struct nouveau_heap *r;
|
||||
|
||||
if (!res || !*res)
|
||||
return;
|
||||
r = *res;
|
||||
*res = NULL;
|
||||
|
||||
r->in_use = 0;
|
||||
|
||||
if (r->next && !r->next->in_use) {
|
||||
struct nouveau_heap *new = r->next;
|
||||
|
||||
new->prev = r->prev;
|
||||
if (r->prev)
|
||||
r->prev->next = new;
|
||||
new->size += r->size;
|
||||
new->start = r->start;
|
||||
|
||||
free(r);
|
||||
r = new;
|
||||
}
|
||||
|
||||
if (r->prev && !r->prev->in_use) {
|
||||
r->prev->next = r->next;
|
||||
if (r->next)
|
||||
r->next->prev = r->prev;
|
||||
r->prev->size += r->size;
|
||||
free(r);
|
||||
}
|
||||
}
|
||||
52
src/gallium/drivers/nouveau/nouveau_heap.h
Normal file
52
src/gallium/drivers/nouveau/nouveau_heap.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2007 Nouveau Project
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __NOUVEAU_HEAP_H__
|
||||
#define __NOUVEAU_HEAP_H__
|
||||
|
||||
struct nouveau_heap {
|
||||
struct nouveau_heap *prev;
|
||||
struct nouveau_heap *next;
|
||||
|
||||
void *priv;
|
||||
|
||||
unsigned start;
|
||||
unsigned size;
|
||||
|
||||
int in_use;
|
||||
};
|
||||
|
||||
int
|
||||
nouveau_heap_init(struct nouveau_heap **heap, unsigned start,
|
||||
unsigned size);
|
||||
|
||||
void
|
||||
nouveau_heap_destroy(struct nouveau_heap **heap);
|
||||
|
||||
int
|
||||
nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv,
|
||||
struct nouveau_heap **);
|
||||
|
||||
void
|
||||
nouveau_heap_free(struct nouveau_heap **);
|
||||
|
||||
#endif
|
||||
|
|
@ -5,11 +5,10 @@
|
|||
#include "util/u_memory.h"
|
||||
#include "util/u_double_list.h"
|
||||
|
||||
#include "nouveau_winsys.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_mm.h"
|
||||
|
||||
#include "nouveau/nouveau_bo.h"
|
||||
|
||||
#define MM_MIN_ORDER 7
|
||||
#define MM_MAX_ORDER 20
|
||||
|
||||
|
|
@ -28,8 +27,8 @@ struct mm_bucket {
|
|||
struct nouveau_mman {
|
||||
struct nouveau_device *dev;
|
||||
struct mm_bucket bucket[MM_NUM_BUCKETS];
|
||||
uint32_t storage_type;
|
||||
uint32_t domain;
|
||||
union nouveau_bo_config config;
|
||||
uint64_t allocated;
|
||||
};
|
||||
|
||||
|
|
@ -128,8 +127,9 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order)
|
|||
memset(&slab->bits[0], ~0, words * 4);
|
||||
|
||||
slab->bo = NULL;
|
||||
ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size,
|
||||
0, cache->storage_type, &slab->bo);
|
||||
|
||||
ret = nouveau_bo_new(cache->dev, cache->domain, 0, size, &cache->config,
|
||||
&slab->bo);
|
||||
if (ret) {
|
||||
FREE(slab);
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
|
@ -155,7 +155,7 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order)
|
|||
/* @return token to identify slab or NULL if we just allocated a new bo */
|
||||
struct nouveau_mm_allocation *
|
||||
nouveau_mm_allocate(struct nouveau_mman *cache,
|
||||
uint32_t size, struct nouveau_bo **bo, uint32_t *offset)
|
||||
uint32_t size, struct nouveau_bo **bo, uint32_t *offset)
|
||||
{
|
||||
struct mm_bucket *bucket;
|
||||
struct mm_slab *slab;
|
||||
|
|
@ -164,10 +164,11 @@ nouveau_mm_allocate(struct nouveau_mman *cache,
|
|||
|
||||
bucket = mm_bucket_by_size(cache, size);
|
||||
if (!bucket) {
|
||||
ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size,
|
||||
0, cache->storage_type, bo);
|
||||
ret = nouveau_bo_new(cache->dev, cache->domain, 0, size, &cache->config,
|
||||
bo);
|
||||
if (ret)
|
||||
debug_printf("bo_new(%x, %x): %i\n", size, cache->storage_type, ret);
|
||||
debug_printf("bo_new(%x, %x): %i\n",
|
||||
size, cache->config.nv50.memtype, ret);
|
||||
|
||||
*offset = 0;
|
||||
return NULL;
|
||||
|
|
@ -233,7 +234,7 @@ nouveau_mm_free_work(void *data)
|
|||
|
||||
struct nouveau_mman *
|
||||
nouveau_mm_create(struct nouveau_device *dev, uint32_t domain,
|
||||
uint32_t storage_type)
|
||||
union nouveau_bo_config *config)
|
||||
{
|
||||
struct nouveau_mman *cache = MALLOC_STRUCT(nouveau_mman);
|
||||
int i;
|
||||
|
|
@ -243,7 +244,7 @@ nouveau_mm_create(struct nouveau_device *dev, uint32_t domain,
|
|||
|
||||
cache->dev = dev;
|
||||
cache->domain = domain;
|
||||
cache->storage_type = storage_type;
|
||||
cache->config = *config;
|
||||
cache->allocated = 0;
|
||||
|
||||
for (i = 0; i < MM_NUM_BUCKETS; ++i) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __NOUVEAU_MM_H__
|
||||
#define __NOUVEAU_MM_H__
|
||||
|
||||
union nouveau_bo_config;
|
||||
struct nouveau_mman;
|
||||
|
||||
/* Since a resource can be migrated, we need to decouple allocations from
|
||||
|
|
@ -14,7 +15,7 @@ struct nouveau_mm_allocation {
|
|||
|
||||
extern struct nouveau_mman *
|
||||
nouveau_mm_create(struct nouveau_device *, uint32_t domain,
|
||||
uint32_t storage_type);
|
||||
union nouveau_bo_config *);
|
||||
|
||||
extern void
|
||||
nouveau_mm_destroy(struct nouveau_mman *);
|
||||
|
|
|
|||
|
|
@ -12,17 +12,15 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nouveau/nouveau_bo.h"
|
||||
#include "nouveau/nouveau_mm.h"
|
||||
#include "nouveau_winsys.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_fence.h"
|
||||
#include "nouveau_mm.h"
|
||||
#include "nouveau_buffer.h"
|
||||
|
||||
/* XXX this should go away */
|
||||
#include "state_tracker/drm_driver.h"
|
||||
|
||||
#include "nouveau_drmif.h"
|
||||
|
||||
int nouveau_mesa_debug = 0;
|
||||
|
||||
static const char *
|
||||
|
|
@ -41,102 +39,6 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen)
|
|||
return "nouveau";
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct nouveau_bo *
|
||||
nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
|
||||
unsigned usage, unsigned bind, unsigned size)
|
||||
{
|
||||
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
|
||||
struct nouveau_bo *bo = NULL;
|
||||
uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
|
||||
int ret;
|
||||
|
||||
if (bind & PIPE_BIND_VERTEX_BUFFER)
|
||||
flags |= nouveau_screen(pscreen)->vertex_buffer_flags;
|
||||
else if (bind & PIPE_BIND_INDEX_BUFFER)
|
||||
flags |= nouveau_screen(pscreen)->index_buffer_flags;
|
||||
|
||||
if (bind & (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DEPTH_STENCIL |
|
||||
PIPE_BIND_SCANOUT |
|
||||
PIPE_BIND_DISPLAY_TARGET |
|
||||
PIPE_BIND_SAMPLER_VIEW))
|
||||
{
|
||||
/* TODO: this may be incorrect or suboptimal */
|
||||
if (!(bind & PIPE_BIND_SCANOUT))
|
||||
flags |= NOUVEAU_BO_GART;
|
||||
if (usage != PIPE_USAGE_DYNAMIC)
|
||||
flags |= NOUVEAU_BO_VRAM;
|
||||
|
||||
if (dev->chipset == 0x50 || dev->chipset >= 0x80) {
|
||||
if (bind & PIPE_BIND_DEPTH_STENCIL)
|
||||
tile_flags = 0x2800;
|
||||
else
|
||||
tile_flags = 0x7000;
|
||||
}
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, flags, alignment, size,
|
||||
tile_mode, tile_flags, &bo);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
||||
void *
|
||||
nouveau_screen_bo_map(struct pipe_screen *pscreen,
|
||||
struct nouveau_bo *bo,
|
||||
unsigned map_flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bo_map(bo, map_flags);
|
||||
if (ret) {
|
||||
debug_printf("map failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bo->map;
|
||||
}
|
||||
|
||||
void *
|
||||
nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
|
||||
unsigned offset, unsigned length, unsigned flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bo_map_range(bo, offset, length, flags);
|
||||
if (ret) {
|
||||
nouveau_bo_unmap(bo);
|
||||
if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
|
||||
debug_printf("map_range failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (char *)bo->map - offset; /* why gallium? why? */
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
|
||||
unsigned offset, unsigned length)
|
||||
{
|
||||
nouveau_bo_map_flush(bo, offset, length);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo)
|
||||
{
|
||||
nouveau_bo_unmap(bo);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo)
|
||||
{
|
||||
nouveau_bo_ref(NULL, &bo);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_screen_fence_ref(struct pipe_screen *pscreen,
|
||||
struct pipe_fence_handle **ptr,
|
||||
|
|
@ -157,7 +59,7 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
|
|||
struct pipe_fence_handle *pfence,
|
||||
uint64_t timeout)
|
||||
{
|
||||
return nouveau_fence_wait(nouveau_fence(pfence));
|
||||
return nouveau_fence_wait(nouveau_fence(pfence));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -170,7 +72,7 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
|
|||
struct nouveau_bo *bo = 0;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo);
|
||||
ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
|
||||
if (ret) {
|
||||
debug_printf("%s: ref name 0x%08x failed with %d\n",
|
||||
__FUNCTION__, whandle->handle, ret);
|
||||
|
|
@ -191,7 +93,7 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
|
|||
whandle->stride = stride;
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
|
||||
return nouveau_bo_handle_get(bo, &whandle->handle) == 0;
|
||||
return nouveau_bo_name_get(bo, &whandle->handle) == 0;
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
|
||||
whandle->handle = bo->handle;
|
||||
return TRUE;
|
||||
|
|
@ -204,18 +106,39 @@ int
|
|||
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
|
||||
{
|
||||
struct pipe_screen *pscreen = &screen->base;
|
||||
int ret;
|
||||
struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
|
||||
struct nvc0_fifo nvc0_data = { };
|
||||
int size, ret;
|
||||
void *data;
|
||||
union nouveau_bo_config mm_config;
|
||||
|
||||
char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
|
||||
if (nv_dbg)
|
||||
nouveau_mesa_debug = atoi(nv_dbg);
|
||||
|
||||
ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
|
||||
512*1024, &screen->channel);
|
||||
if (dev->chipset < 0xc0) {
|
||||
data = &nv04_data;
|
||||
size = sizeof(nv04_data);
|
||||
} else {
|
||||
data = &nvc0_data;
|
||||
size = sizeof(nvc0_data);
|
||||
}
|
||||
|
||||
ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
|
||||
data, size, &screen->channel);
|
||||
if (ret)
|
||||
return ret;
|
||||
screen->device = dev;
|
||||
|
||||
ret = nouveau_client_new(screen->device, &screen->client);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = nouveau_pushbuf_new(screen->client, screen->channel,
|
||||
4, 512 * 1024, 1,
|
||||
&screen->pushbuf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pscreen->get_name = nouveau_screen_get_name;
|
||||
pscreen->get_vendor = nouveau_screen_get_vendor;
|
||||
|
||||
|
|
@ -225,10 +148,12 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
|
|||
|
||||
util_format_s3tc_init();
|
||||
|
||||
memset(&mm_config, 0, sizeof(mm_config));
|
||||
|
||||
screen->mm_GART = nouveau_mm_create(dev,
|
||||
NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
|
||||
0x000);
|
||||
screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
|
||||
&mm_config);
|
||||
screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -238,8 +163,10 @@ nouveau_screen_fini(struct nouveau_screen *screen)
|
|||
nouveau_mm_destroy(screen->mm_GART);
|
||||
nouveau_mm_destroy(screen->mm_VRAM);
|
||||
|
||||
nouveau_channel_free(&screen->channel);
|
||||
nouveau_pushbuf_del(&screen->pushbuf);
|
||||
|
||||
nouveau_device_close(&screen->device);
|
||||
nouveau_client_del(&screen->client);
|
||||
nouveau_object_del(&screen->channel);
|
||||
|
||||
nouveau_device_del(&screen->device);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "pipe/p_screen.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
typedef uint32_t u32;
|
||||
|
||||
extern int nouveau_mesa_debug;
|
||||
|
|
@ -12,12 +13,10 @@ struct nouveau_bo;
|
|||
struct nouveau_screen {
|
||||
struct pipe_screen base;
|
||||
struct nouveau_device *device;
|
||||
struct nouveau_channel *channel;
|
||||
struct nouveau_object *channel;
|
||||
struct nouveau_client *client;
|
||||
struct nouveau_pushbuf *pushbuf;
|
||||
|
||||
/* note that OpenGL doesn't distinguish between these, so
|
||||
* these almost always should be set to the same value */
|
||||
unsigned vertex_buffer_flags;
|
||||
unsigned index_buffer_flags;
|
||||
unsigned sysmem_bindings;
|
||||
|
||||
struct {
|
||||
|
|
@ -40,30 +39,6 @@ nouveau_screen(struct pipe_screen *pscreen)
|
|||
return (struct nouveau_screen *)pscreen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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 bind, unsigned size);
|
||||
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,
|
||||
|
|
@ -80,19 +55,4 @@ void nouveau_screen_fini(struct nouveau_screen *);
|
|||
|
||||
void nouveau_screen_init_vdec(struct nouveau_screen *);
|
||||
|
||||
|
||||
#ifndef NOUVEAU_NVC0
|
||||
static INLINE unsigned
|
||||
RING_3D(unsigned mthd, unsigned size)
|
||||
{
|
||||
return (7 << 13) | (size << 18) | mthd;
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
RING_3D_NI(unsigned mthd, unsigned size)
|
||||
{
|
||||
return 0x40000000 | (7 << 13) | (size << 18) | mthd;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,8 +20,13 @@ struct nouveau_statebuf_builder
|
|||
#define sb_data(sb, v) *(sb).p++ = (v)
|
||||
#endif
|
||||
|
||||
#define sb_method(sb, v, n) sb_data(sb, RING_3D(v, n));
|
||||
static INLINE uint32_t sb_header(unsigned subc, unsigned mthd, unsigned size)
|
||||
{
|
||||
return (size << 18) | (subc << 13) | mthd;
|
||||
}
|
||||
|
||||
#define sb_method(sb, v, n) sb_data(sb, sb_header(SUBC_3D(v), n));
|
||||
|
||||
#define sb_len(sb, var) ((sb).p - (var))
|
||||
#define sb_emit(chan, sb_buf, sb_len) do {WAIT_RING((chan), (sb_len)); OUT_RINGp((chan), (sb_buf), (sb_len)); } while(0)
|
||||
#define sb_emit(push, sb_buf, sb_len) do {PUSH_SPACE((push), (sb_len)); PUSH_DATAp((push), (sb_buf), (sb_len)); } while(0)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,27 +27,23 @@
|
|||
#include "nouveau_context.h"
|
||||
#include "nouveau_video.h"
|
||||
|
||||
#include "nouveau/nouveau_bo.h"
|
||||
#include "nouveau/nouveau_buffer.h"
|
||||
#include "util/u_video.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_sampler.h"
|
||||
#include "nouveau/nouveau_device.h"
|
||||
#include "nouveau_winsys.h"
|
||||
|
||||
static int
|
||||
nouveau_vpe_init(struct nouveau_decoder *dec) {
|
||||
int ret;
|
||||
if (dec->cmds)
|
||||
return 0;
|
||||
ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR);
|
||||
ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR, dec->client);
|
||||
if (ret) {
|
||||
debug_printf("Mapping cmd bo: %s\n", strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR);
|
||||
ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR, dec->client);
|
||||
if (ret) {
|
||||
nouveau_bo_unmap(dec->cmd_bo);
|
||||
debug_printf("Mapping data bo: %s\n", strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -58,39 +54,45 @@ nouveau_vpe_init(struct nouveau_decoder *dec) {
|
|||
|
||||
static void
|
||||
nouveau_vpe_synch(struct nouveau_decoder *dec) {
|
||||
struct nouveau_channel *chan = dec->screen->channel;
|
||||
struct nouveau_pushbuf *push = dec->push;
|
||||
#if 0
|
||||
if (dec->fence_map) {
|
||||
BEGIN_RING(chan, dec->mpeg, NV84_MPEG_QUERY_COUNTER, 1);
|
||||
OUT_RING(chan, ++dec->fence_seq);
|
||||
FIRE_RING(chan);
|
||||
BEGIN_NV04(push, NV84_MPEG(QUERY_COUNTER), 1);
|
||||
PUSH_DATA (push, ++dec->fence_seq);
|
||||
PUSH_KICK (push);
|
||||
while (dec->fence_map[0] != dec->fence_seq)
|
||||
usleep(1000);
|
||||
} else
|
||||
#endif
|
||||
FIRE_RING(chan);
|
||||
PUSH_KICK(push);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_vpe_fini(struct nouveau_decoder *dec) {
|
||||
struct nouveau_channel *chan = dec->screen->channel;
|
||||
struct nouveau_pushbuf *push = dec->push;
|
||||
if (!dec->cmds)
|
||||
return;
|
||||
|
||||
nouveau_bo_unmap(dec->data_bo);
|
||||
nouveau_bo_unmap(dec->cmd_bo);
|
||||
nouveau_pushbuf_space(push, 8, 2, 0);
|
||||
nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_CMD);
|
||||
|
||||
MARK_RING(chan, 8, 2);
|
||||
BEGIN_RING(chan, dec->mpeg, NV31_MPEG_CMD_OFFSET, 2);
|
||||
OUT_RELOCl(chan, dec->cmd_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART);
|
||||
OUT_RING(chan, dec->ofs * 4);
|
||||
#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_CMD, NOUVEAU_BO_RD
|
||||
|
||||
BEGIN_RING(chan, dec->mpeg, NV31_MPEG_DATA_OFFSET, 2);
|
||||
OUT_RELOCl(chan, dec->data_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART);
|
||||
OUT_RING(chan, dec->data_pos * 4);
|
||||
BEGIN_NV04(push, NV31_MPEG(CMD_OFFSET), 2);
|
||||
PUSH_MTHDl(push, NV31_MPEG(CMD_OFFSET), dec->cmd_bo, 0, BCTX_ARGS);
|
||||
PUSH_DATA (push, dec->ofs * 4);
|
||||
|
||||
BEGIN_RING(chan, dec->mpeg, NV31_MPEG_EXEC, 1);
|
||||
OUT_RING(chan, 1);
|
||||
BEGIN_NV04(push, NV31_MPEG(DATA_OFFSET), 2);
|
||||
PUSH_MTHDl(push, NV31_MPEG(DATA_OFFSET), dec->data_bo, 0, BCTX_ARGS);
|
||||
PUSH_DATA (push, dec->data_pos * 4);
|
||||
|
||||
#undef BCTX_ARGS
|
||||
|
||||
if (unlikely(nouveau_pushbuf_validate(dec->push)))
|
||||
return;
|
||||
|
||||
BEGIN_NV04(push, NV31_MPEG(EXEC), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
nouveau_vpe_synch(dec);
|
||||
dec->ofs = dec->data_pos = dec->num_surfaces = 0;
|
||||
|
|
@ -384,9 +386,10 @@ nouveau_decoder_surface_index(struct nouveau_decoder *dec,
|
|||
struct pipe_video_buffer *buffer)
|
||||
{
|
||||
struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
|
||||
struct nouveau_channel *chan = dec->screen->channel;
|
||||
struct nouveau_bo *bo_y = ((struct nv04_resource *)buf->resources[0])->bo;
|
||||
struct nouveau_bo *bo_c = ((struct nv04_resource *)buf->resources[1])->bo;
|
||||
struct nouveau_pushbuf *push = dec->push;
|
||||
struct nouveau_bo *bo_y = nv04_resource(buf->resources[0])->bo;
|
||||
struct nouveau_bo *bo_c = nv04_resource(buf->resources[1])->bo;
|
||||
|
||||
unsigned i;
|
||||
|
||||
if (!buf)
|
||||
|
|
@ -399,10 +402,14 @@ nouveau_decoder_surface_index(struct nouveau_decoder *dec,
|
|||
dec->surfaces[i] = buf;
|
||||
dec->num_surfaces++;
|
||||
|
||||
MARK_RING(chan, 3, 2);
|
||||
BEGIN_RING(chan, dec->mpeg, NV31_MPEG_IMAGE_Y_OFFSET(i), 2);
|
||||
OUT_RELOCl(chan, bo_y, 0, NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo_c, 0, NOUVEAU_BO_RDWR);
|
||||
nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_IMG(i));
|
||||
|
||||
#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_IMG(i), NOUVEAU_BO_RDWR
|
||||
BEGIN_NV04(push, NV31_MPEG(IMAGE_Y_OFFSET(i)), 2);
|
||||
PUSH_MTHDl(push, NV31_MPEG(IMAGE_Y_OFFSET(i)), bo_y, 0, BCTX_ARGS);
|
||||
PUSH_MTHDl(push, NV31_MPEG(IMAGE_C_OFFSET(i)), bo_c, 0, BCTX_ARGS);
|
||||
#undef BCTX_ARGS
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -475,18 +482,24 @@ nouveau_decoder_destroy(struct pipe_video_decoder *decoder)
|
|||
{
|
||||
struct nouveau_decoder *dec = (struct nouveau_decoder*)decoder;
|
||||
|
||||
if (dec->cmds) {
|
||||
nouveau_bo_unmap(dec->data_bo);
|
||||
nouveau_bo_unmap(dec->cmd_bo);
|
||||
}
|
||||
|
||||
if (dec->data_bo)
|
||||
nouveau_bo_ref(NULL, &dec->data_bo);
|
||||
if (dec->cmd_bo)
|
||||
nouveau_bo_ref(NULL, &dec->cmd_bo);
|
||||
if (dec->fence_bo)
|
||||
nouveau_bo_ref(NULL, &dec->fence_bo);
|
||||
nouveau_grobj_free(&dec->mpeg);
|
||||
|
||||
nouveau_object_del(&dec->mpeg);
|
||||
|
||||
if (dec->bufctx)
|
||||
nouveau_bufctx_del(&dec->bufctx);
|
||||
if (dec->push)
|
||||
nouveau_pushbuf_del(&dec->push);
|
||||
if (dec->client)
|
||||
nouveau_client_del(&dec->client);
|
||||
if (dec->chan)
|
||||
nouveau_object_del(&dec->chan);
|
||||
|
||||
FREE(dec);
|
||||
}
|
||||
|
||||
|
|
@ -499,9 +512,10 @@ nouveau_create_decoder(struct pipe_context *context,
|
|||
unsigned width, unsigned height,
|
||||
unsigned max_references, bool expect_chunked_decode)
|
||||
{
|
||||
struct nouveau_channel *chan = screen->channel;
|
||||
struct nouveau_grobj *mpeg = NULL;
|
||||
struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
|
||||
struct nouveau_object *mpeg = NULL;
|
||||
struct nouveau_decoder *dec;
|
||||
struct nouveau_pushbuf *push;
|
||||
int ret;
|
||||
bool is8274 = screen->device->chipset > 0x80;
|
||||
|
||||
|
|
@ -515,23 +529,40 @@ nouveau_create_decoder(struct pipe_context *context,
|
|||
if (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0)
|
||||
goto vl;
|
||||
|
||||
dec = CALLOC_STRUCT(nouveau_decoder);
|
||||
if (!dec)
|
||||
return NULL;
|
||||
|
||||
ret = nouveau_object_new(&screen->device->object, 0,
|
||||
NOUVEAU_FIFO_CHANNEL_CLASS,
|
||||
&nv04_data, sizeof(nv04_data), &dec->chan);
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = nouveau_client_new(screen->device, &dec->client);
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = nouveau_pushbuf_new(dec->client, dec->chan, 2, 4096, 1, &dec->push);
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = nouveau_bufctx_new(dec->client, NV31_VIDEO_BIND_COUNT, &dec->bufctx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
push = dec->push;
|
||||
|
||||
width = align(width, 64);
|
||||
height = align(height, 64);
|
||||
|
||||
if (is8274)
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x8274, &mpeg);
|
||||
ret = nouveau_object_new(dec->chan, 0xbeef8274, NV84_MPEG_CLASS, NULL, 0,
|
||||
&mpeg);
|
||||
else
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x3174, &mpeg);
|
||||
ret = nouveau_object_new(dec->chan, 0xbeef3174, NV31_MPEG_CLASS, NULL, 0,
|
||||
&mpeg);
|
||||
if (ret < 0) {
|
||||
debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dec = CALLOC_STRUCT(nouveau_decoder);
|
||||
if (!dec) {
|
||||
nouveau_grobj_free(&mpeg);
|
||||
goto fail;
|
||||
}
|
||||
dec->mpeg = mpeg;
|
||||
dec->base.context = context;
|
||||
dec->base.profile = profile;
|
||||
|
|
@ -543,61 +574,67 @@ nouveau_create_decoder(struct pipe_context *context,
|
|||
dec->base.destroy = nouveau_decoder_destroy;
|
||||
dec->base.begin_frame = nouveau_decoder_begin_frame;
|
||||
dec->base.decode_macroblock = nouveau_decoder_decode_macroblock;
|
||||
dec->base.begin_frame = nouveau_decoder_end_frame;
|
||||
dec->base.end_frame = nouveau_decoder_end_frame;
|
||||
dec->base.flush = nouveau_decoder_flush;
|
||||
dec->screen = screen;
|
||||
|
||||
ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, 1024 * 1024, &dec->cmd_bo);
|
||||
ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
|
||||
0, 1024 * 1024, NULL, &dec->cmd_bo);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, width * height * 6, &dec->data_bo);
|
||||
ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
|
||||
0, width * height * 6, NULL, &dec->data_bo);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP, 0, 4096,
|
||||
&dec->fence_bo);
|
||||
/* we don't need the fence, the kernel sync's for us */
|
||||
#if 0
|
||||
ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
|
||||
0, 4096, NULL, &dec->fence_bo);
|
||||
if (ret)
|
||||
goto fail;
|
||||
nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR);
|
||||
nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, NULL);
|
||||
dec->fence_map = dec->fence_bo->map;
|
||||
nouveau_bo_unmap(dec->fence_bo);
|
||||
dec->fence_map[0] = 0;
|
||||
#endif
|
||||
|
||||
if (is8274)
|
||||
MARK_RING(chan, 25, 3);
|
||||
else
|
||||
MARK_RING(chan, 20, 2);
|
||||
nouveau_pushbuf_bufctx(dec->push, dec->bufctx);
|
||||
nouveau_pushbuf_space(push, 32, 4, 0);
|
||||
|
||||
BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_CMD, 1);
|
||||
OUT_RING(chan, chan->vram->handle);
|
||||
BEGIN_NV04(push, SUBC_MPEG(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, dec->mpeg->handle);
|
||||
|
||||
BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_DATA, 1);
|
||||
OUT_RING(chan, chan->vram->handle);
|
||||
BEGIN_NV04(push, NV31_MPEG(DMA_CMD), 1);
|
||||
PUSH_DATA (push, nv04_data.gart);
|
||||
|
||||
BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_IMAGE, 1);
|
||||
OUT_RING(chan, chan->vram->handle);
|
||||
BEGIN_NV04(push, NV31_MPEG(DMA_DATA), 1);
|
||||
PUSH_DATA (push, nv04_data.gart);
|
||||
|
||||
BEGIN_RING(chan, mpeg, NV31_MPEG_PITCH, 2);
|
||||
OUT_RING(chan, width | NV31_MPEG_PITCH_UNK);
|
||||
OUT_RING(chan, (height << NV31_MPEG_SIZE_H__SHIFT) | width);
|
||||
BEGIN_NV04(push, NV31_MPEG(DMA_IMAGE), 1);
|
||||
PUSH_DATA (push, nv04_data.vram);
|
||||
|
||||
BEGIN_RING(chan, mpeg, NV31_MPEG_FORMAT, 2);
|
||||
OUT_RING(chan, 0);
|
||||
BEGIN_NV04(push, NV31_MPEG(PITCH), 2);
|
||||
PUSH_DATA (push, width | NV31_MPEG_PITCH_UNK);
|
||||
PUSH_DATA (push, (height << NV31_MPEG_SIZE_H__SHIFT) | width);
|
||||
|
||||
BEGIN_NV04(push, NV31_MPEG(FORMAT), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
switch (entrypoint) {
|
||||
case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: OUT_RING(chan, 0x100); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_IDCT: OUT_RING(chan, 1); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_MC: OUT_RING(chan, 0); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: PUSH_DATA (push, 0x100); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_IDCT: PUSH_DATA (push, 1); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_MC: PUSH_DATA (push, 0); break;
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
if (is8274) {
|
||||
BEGIN_RING(chan, mpeg, NV84_MPEG_DMA_QUERY, 1);
|
||||
OUT_RING(chan, chan->vram->handle);
|
||||
|
||||
BEGIN_RING(chan, mpeg, NV84_MPEG_QUERY_OFFSET, 2);
|
||||
OUT_RELOCl(chan, dec->fence_bo, 0, NOUVEAU_BO_WR|NOUVEAU_BO_GART);
|
||||
OUT_RING(chan, dec->fence_seq);
|
||||
BEGIN_NV04(push, NV84_MPEG(DMA_QUERY), 1);
|
||||
PUSH_DATA (push, nv04_data.vram);
|
||||
#if 0
|
||||
BEGIN_NV04(push, NV84_MPEG(QUERY_OFFSET), 2);
|
||||
PUSH_DATA (push, dec->fence_bo->offset);
|
||||
PUSH_DATA (push, dec->fence_seq);
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = nouveau_vpe_init(dec);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
#ifndef __NOUVEAU_VIDEO_H__
|
||||
#define __NOUVEAU_SCREEN_H__
|
||||
#define __NOUVEAU_VIDEO_H__
|
||||
|
||||
#include "nv17_mpeg.xml.h"
|
||||
#include "nv31_mpeg.xml.h"
|
||||
#include "nv_object.xml.h"
|
||||
|
||||
#include "nouveau_winsys.h"
|
||||
|
||||
struct nouveau_video_buffer {
|
||||
struct pipe_video_buffer base;
|
||||
|
|
@ -16,7 +19,11 @@ struct nouveau_video_buffer {
|
|||
struct nouveau_decoder {
|
||||
struct pipe_video_decoder base;
|
||||
struct nouveau_screen *screen;
|
||||
struct nouveau_grobj *mpeg;
|
||||
struct nouveau_pushbuf *push;
|
||||
struct nouveau_object *chan;
|
||||
struct nouveau_client *client;
|
||||
struct nouveau_bufctx *bufctx;
|
||||
struct nouveau_object *mpeg;
|
||||
struct nouveau_bo *cmd_bo, *data_bo, *fence_bo;
|
||||
|
||||
unsigned *fence_map;
|
||||
|
|
@ -34,9 +41,56 @@ struct nouveau_decoder {
|
|||
struct nouveau_video_buffer *surfaces[8];
|
||||
};
|
||||
|
||||
#define NV31_VIDEO_BIND_IMG(i) i
|
||||
#define NV31_VIDEO_BIND_CMD NV31_MPEG_IMAGE_Y_OFFSET__LEN
|
||||
#define NV31_VIDEO_BIND_COUNT (NV31_MPEG_IMAGE_Y_OFFSET__LEN + 1)
|
||||
|
||||
static INLINE void
|
||||
nouveau_vpe_write(struct nouveau_decoder *dec, unsigned data) {
|
||||
dec->cmds[dec->ofs++] = data;
|
||||
}
|
||||
|
||||
#define SUBC_MPEG(mthd) 1, mthd
|
||||
#define NV31_MPEG(mthd) SUBC_MPEG(NV31_MPEG_##mthd)
|
||||
#define NV84_MPEG(mthd) SUBC_MPEG(NV84_MPEG_##mthd)
|
||||
|
||||
static INLINE uint32_t
|
||||
NV04_FIFO_PKHDR(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0x00000000 | (size << 18) | (subc << 13) | mthd;
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
NV04_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0x40000000 | (size << 18) | (subc << 13) | mthd;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
PUSH_SPACE(push, size + 1);
|
||||
PUSH_DATA (push, NV04_FIFO_PKHDR(subc, mthd, size));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
PUSH_SPACE(push, size + 1);
|
||||
PUSH_DATA (push, NV04_FIFO_PKHDR_NI(subc, mthd, size));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd,
|
||||
struct nouveau_bo *bo, uint32_t offset,
|
||||
struct nouveau_bufctx *ctx, int bin, uint32_t rw)
|
||||
{
|
||||
nouveau_bufctx_mthd(ctx, bin, NV04_FIFO_PKHDR(subc, mthd, 1),
|
||||
bo, offset,
|
||||
NOUVEAU_BO_LOW | (bo->flags & NOUVEAU_BO_APER) | rw,
|
||||
0, 0);
|
||||
|
||||
PUSH_DATA(push, bo->offset + offset);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,19 +6,54 @@
|
|||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "nouveau/nouveau_bo.h"
|
||||
#include "nouveau/nouveau_channel.h"
|
||||
#include "nouveau/nouveau_device.h"
|
||||
#include "nouveau/nouveau_grobj.h"
|
||||
#include "nouveau/nouveau_notifier.h"
|
||||
#ifndef NOUVEAU_NVC0
|
||||
#include "nouveau/nv04_pushbuf.h"
|
||||
#endif
|
||||
#include <libdrm/nouveau.h>
|
||||
|
||||
#ifndef NV04_PFIFO_MAX_PACKET_LEN
|
||||
#define NV04_PFIFO_MAX_PACKET_LEN 2047
|
||||
#endif
|
||||
|
||||
static INLINE uint32_t
|
||||
PUSH_AVAIL(struct nouveau_pushbuf *push)
|
||||
{
|
||||
return push->end - push->cur;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
|
||||
{
|
||||
if (PUSH_AVAIL(push) < size)
|
||||
return nouveau_pushbuf_space(push, size, 0, 0) == 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
|
||||
{
|
||||
*push->cur++ = data;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size)
|
||||
{
|
||||
memcpy(push->cur, data, size * 4);
|
||||
push->cur += size;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
PUSH_DATAf(struct nouveau_pushbuf *push, float f)
|
||||
{
|
||||
union { float f; uint32_t i; } u;
|
||||
u.f = f;
|
||||
PUSH_DATA(push, u.i);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
PUSH_KICK(struct nouveau_pushbuf *push)
|
||||
{
|
||||
nouveau_pushbuf_kick(push, push->channel);
|
||||
}
|
||||
|
||||
|
||||
#define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
|
||||
#define NOUVEAU_RESOURCE_FLAG_DRV_PRIV (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
|
||||
|
||||
|
|
@ -27,16 +62,14 @@ nouveau_screen_transfer_flags(unsigned pipe)
|
|||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (pipe & PIPE_TRANSFER_READ)
|
||||
flags |= NOUVEAU_BO_RD;
|
||||
if (pipe & PIPE_TRANSFER_WRITE)
|
||||
flags |= NOUVEAU_BO_WR;
|
||||
if (pipe & PIPE_TRANSFER_DISCARD_RANGE)
|
||||
flags |= NOUVEAU_BO_INVAL;
|
||||
if (pipe & PIPE_TRANSFER_UNSYNCHRONIZED)
|
||||
flags |= NOUVEAU_BO_NOSYNC;
|
||||
else if (pipe & PIPE_TRANSFER_DONTBLOCK)
|
||||
flags |= NOUVEAU_BO_NOWAIT;
|
||||
if (!(pipe & PIPE_TRANSFER_UNSYNCHRONIZED)) {
|
||||
if (pipe & PIPE_TRANSFER_READ)
|
||||
flags |= NOUVEAU_BO_RD;
|
||||
if (pipe & PIPE_TRANSFER_WRITE)
|
||||
flags |= NOUVEAU_BO_WR;
|
||||
if (pipe & PIPE_TRANSFER_DONTBLOCK)
|
||||
flags |= NOUVEAU_BO_NOBLOCK;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef NV_M2MF_XML
|
||||
#define NV_M2MF_XML
|
||||
#ifndef RNNDB_NV_M2MF_XML
|
||||
#define RNNDB_NV_M2MF_XML
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
|
|
@ -8,13 +8,14 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
|
|||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- nv_m2mf.xml ( 2710 bytes, from 2010-08-05 19:38:53)
|
||||
- copyright.xml ( 6503 bytes, from 2010-04-10 23:15:50)
|
||||
- nv_object.xml ( 10424 bytes, from 2010-08-05 19:38:53)
|
||||
- nvchipsets.xml ( 2824 bytes, from 2010-08-05 19:38:53)
|
||||
- nv_defs.xml ( 4437 bytes, from 2010-08-05 19:38:53)
|
||||
- rnndb/nv_m2mf.xml ( 2696 bytes, from 2011-07-09 13:43:58)
|
||||
- ./rnndb/copyright.xml ( 6452 bytes, from 2011-07-09 13:43:58)
|
||||
- ./rnndb/nv_object.xml ( 12672 bytes, from 2011-07-17 12:14:32)
|
||||
- ./rnndb/nvchipsets.xml ( 3701 bytes, from 2012-04-06 13:21:15)
|
||||
- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-07-09 13:43:58)
|
||||
- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-07-09 13:43:58)
|
||||
|
||||
Copyright (C) 2006-2010 by the following authors:
|
||||
Copyright (C) 2006-2011 by the following authors:
|
||||
- Artur Huillet <arthur.huillet@free.fr> (ahuillet)
|
||||
- Ben Skeggs (darktama, darktama_)
|
||||
- B. R. <koala_br@users.sourceforge.net> (koala_br)
|
||||
|
|
@ -25,7 +26,7 @@ Copyright (C) 2006-2010 by the following authors:
|
|||
- Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
|
||||
- EdB <edb_@users.sf.net> (edb_)
|
||||
- Erik Waling <erikwailing@users.sf.net> (erikwaling)
|
||||
- Francisco Jerez <currojerez@riseup.net> (curro, curro_, currojerez)
|
||||
- Francisco Jerez <currojerez@riseup.net> (curro)
|
||||
- imirkin <imirkin@users.sf.net> (imirkin)
|
||||
- jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
|
||||
- Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
|
||||
|
|
@ -36,7 +37,7 @@ Copyright (C) 2006-2010 by the following authors:
|
|||
- Mark Carey <mark.carey@gmail.com> (careym)
|
||||
- Matthieu Castet <matthieu.castet@parrot.com> (mat-c)
|
||||
- nvidiaman <nvidiaman@users.sf.net> (nvidiaman)
|
||||
- Patrice Mandin <mandin.patrice@orange.fr> (pmandin, pmdata)
|
||||
- Patrice Mandin <patmandin@gmail.com> (pmandin, pmdata)
|
||||
- Pekka Paalanen <pq@iki.fi> (pq, ppaalanen)
|
||||
- Peter Popov <ironpeter@users.sf.net> (ironpeter)
|
||||
- Richard Hughes <hughsient@users.sf.net> (hughsient)
|
||||
|
|
@ -74,11 +75,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
|
||||
|
||||
#define NV04_M2MF_DMA_NOTIFY 0x00000180
|
||||
#define NV03_M2MF_DMA_NOTIFY 0x00000180
|
||||
|
||||
#define NV04_M2MF_DMA_BUFFER_IN 0x00000184
|
||||
#define NV03_M2MF_DMA_BUFFER_IN 0x00000184
|
||||
|
||||
#define NV04_M2MF_DMA_BUFFER_OUT 0x00000188
|
||||
#define NV03_M2MF_DMA_BUFFER_OUT 0x00000188
|
||||
|
||||
|
||||
#define NV50_M2MF_LINEAR_IN 0x00000200
|
||||
|
|
@ -121,35 +122,35 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NV50_M2MF_OFFSET_OUT_HIGH 0x0000023c
|
||||
|
||||
#define NV04_M2MF_OFFSET_IN 0x0000030c
|
||||
#define NV03_M2MF_OFFSET_IN 0x0000030c
|
||||
|
||||
#define NV04_M2MF_OFFSET_OUT 0x00000310
|
||||
#define NV03_M2MF_OFFSET_OUT 0x00000310
|
||||
|
||||
#define NV04_M2MF_PITCH_IN 0x00000314
|
||||
#define NV03_M2MF_PITCH_IN 0x00000314
|
||||
|
||||
#define NV04_M2MF_PITCH_OUT 0x00000318
|
||||
#define NV03_M2MF_PITCH_OUT 0x00000318
|
||||
|
||||
#define NV04_M2MF_LINE_LENGTH_IN 0x0000031c
|
||||
#define NV03_M2MF_LINE_LENGTH_IN 0x0000031c
|
||||
|
||||
#define NV04_M2MF_LINE_COUNT 0x00000320
|
||||
#define NV03_M2MF_LINE_COUNT 0x00000320
|
||||
|
||||
#define NV04_M2MF_FORMAT 0x00000324
|
||||
#define NV04_M2MF_FORMAT_INPUT_INC__MASK 0x000000ff
|
||||
#define NV04_M2MF_FORMAT_INPUT_INC__SHIFT 0
|
||||
#define NV04_M2MF_FORMAT_INPUT_INC_1 0x00000001
|
||||
#define NV04_M2MF_FORMAT_INPUT_INC_2 0x00000002
|
||||
#define NV04_M2MF_FORMAT_INPUT_INC_4 0x00000004
|
||||
#define NV03_M2MF_FORMAT 0x00000324
|
||||
#define NV03_M2MF_FORMAT_INPUT_INC__MASK 0x000000ff
|
||||
#define NV03_M2MF_FORMAT_INPUT_INC__SHIFT 0
|
||||
#define NV03_M2MF_FORMAT_INPUT_INC_1 0x00000001
|
||||
#define NV03_M2MF_FORMAT_INPUT_INC_2 0x00000002
|
||||
#define NV03_M2MF_FORMAT_INPUT_INC_4 0x00000004
|
||||
#define NV50_M2MF_FORMAT_INPUT_INC_8 0x00000008
|
||||
#define NV50_M2MF_FORMAT_INPUT_INC_16 0x00000010
|
||||
#define NV04_M2MF_FORMAT_OUTPUT_INC__MASK 0x0000ff00
|
||||
#define NV04_M2MF_FORMAT_OUTPUT_INC__SHIFT 8
|
||||
#define NV04_M2MF_FORMAT_OUTPUT_INC_1 0x00000100
|
||||
#define NV04_M2MF_FORMAT_OUTPUT_INC_2 0x00000200
|
||||
#define NV04_M2MF_FORMAT_OUTPUT_INC_4 0x00000400
|
||||
#define NV03_M2MF_FORMAT_OUTPUT_INC__MASK 0x0000ff00
|
||||
#define NV03_M2MF_FORMAT_OUTPUT_INC__SHIFT 8
|
||||
#define NV03_M2MF_FORMAT_OUTPUT_INC_1 0x00000100
|
||||
#define NV03_M2MF_FORMAT_OUTPUT_INC_2 0x00000200
|
||||
#define NV03_M2MF_FORMAT_OUTPUT_INC_4 0x00000400
|
||||
#define NV50_M2MF_FORMAT_OUTPUT_INC_8 0x00000800
|
||||
#define NV50_M2MF_FORMAT_OUTPUT_INC_16 0x00001000
|
||||
|
||||
#define NV04_M2MF_BUF_NOTIFY 0x00000328
|
||||
#define NV03_M2MF_BUF_NOTIFY 0x00000328
|
||||
|
||||
|
||||
#endif /* NV_M2MF_XML */
|
||||
#endif /* RNNDB_NV_M2MF_XML */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
#ifndef NV_OBJECT_XML
|
||||
#define NV_OBJECT_XML
|
||||
#ifndef RNNDB_NV_OBJECT_XML
|
||||
#define RNNDB_NV_OBJECT_XML
|
||||
|
||||
/* WARNING ABOUT NOT EDITING AUTOGENERATED FILE IGNORED, _CLASS SUFFIX HAS
|
||||
* BEEN ADDED TO ALL THE OBJECT CLASS DEFINITIONS TO AVOID CONFLICTS WITH
|
||||
* THE RING MACROS WE WANT TO USE
|
||||
*/
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
|
|
@ -8,12 +13,13 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
|
|||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- nv_object.xml ( 11547 bytes, from 2010-10-24 15:29:34)
|
||||
- copyright.xml ( 6498 bytes, from 2010-10-03 13:18:37)
|
||||
- nvchipsets.xml ( 2907 bytes, from 2010-10-15 16:28:21)
|
||||
- nv_defs.xml ( 4437 bytes, from 2010-07-06 07:43:58)
|
||||
- rnndb/nv_object.xml ( 12672 bytes, from 2011-07-17 12:14:32)
|
||||
- ./rnndb/copyright.xml ( 6452 bytes, from 2011-07-09 13:43:58)
|
||||
- ./rnndb/nvchipsets.xml ( 3701 bytes, from 2012-04-06 13:21:15)
|
||||
- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-07-09 13:43:58)
|
||||
- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-07-09 13:43:58)
|
||||
|
||||
Copyright (C) 2006-2010 by the following authors:
|
||||
Copyright (C) 2006-2011 by the following authors:
|
||||
- Artur Huillet <arthur.huillet@free.fr> (ahuillet)
|
||||
- Ben Skeggs (darktama, darktama_)
|
||||
- B. R. <koala_br@users.sourceforge.net> (koala_br)
|
||||
|
|
@ -24,7 +30,7 @@ Copyright (C) 2006-2010 by the following authors:
|
|||
- Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
|
||||
- EdB <edb_@users.sf.net> (edb_)
|
||||
- Erik Waling <erikwailing@users.sf.net> (erikwaling)
|
||||
- Francisco Jerez <currojerez@riseup.net> (curro, curro_, currojerez)
|
||||
- Francisco Jerez <currojerez@riseup.net> (curro)
|
||||
- imirkin <imirkin@users.sf.net> (imirkin)
|
||||
- jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
|
||||
- Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
|
||||
|
|
@ -72,114 +78,129 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
*/
|
||||
|
||||
|
||||
#define NV01_ROOT 0x00000001
|
||||
#define NV01_CONTEXT_DMA 0x00000002
|
||||
#define NV01_DEVICE 0x00000003
|
||||
#define NV01_TIMER 0x00000004
|
||||
#define NV01_NULL 0x00000030
|
||||
#define NV01_MEMORY_LOCAL_BANKED 0x0000003d
|
||||
#define NV01_MAPPING_SYSTEM 0x0000003e
|
||||
#define NV03_MEMORY_LOCAL_CURSOR 0x0000003f
|
||||
#define NV01_MEMORY_LOCAL_LINEAR 0x00000040
|
||||
#define NV01_MAPPING_LOCAL 0x00000041
|
||||
#define NV03_VIDEO_LUT_CURSOR_DAC 0x00000046
|
||||
#define NV03_CHANNEL_PIO 0x0000006a
|
||||
#define NV03_CHANNEL_DMA 0x0000006b
|
||||
#define NV10_VIDEO_DISPLAY 0x0000007c
|
||||
#define NV01_CONTEXT_BETA1 0x00000012
|
||||
#define NV04_BETA_SOLID 0x00000072
|
||||
#define NV01_CONTEXT_COLOR_KEY 0x00000017
|
||||
#define NV04_CONTEXT_COLOR_KEY 0x00000057
|
||||
#define NV01_CONTEXT_PATTERN 0x00000018
|
||||
#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019
|
||||
#define NV03_CONTEXT_ROP 0x00000043
|
||||
#define NV04_IMAGE_PATTERN 0x00000044
|
||||
#define NV01_RENDER_SOLID_LINE 0x0000001c
|
||||
#define NV04_RENDER_SOLID_LINE 0x0000005c
|
||||
#define NV30_RENDER_SOLID_LINE 0x0000035c
|
||||
#define NV40_RENDER_SOLID_LINE 0x0000305c
|
||||
#define NV01_RENDER_SOLID_TRIANGLE 0x0000001d
|
||||
#define NV04_RENDER_SOLID_TRIANGLE 0x0000005d
|
||||
#define NV01_RENDER_SOLID_RECTANGLE 0x0000001e
|
||||
#define NV04_RENDER_SOLID_RECTANGLE 0x0000005e
|
||||
#define NV01_IMAGE_BLIT 0x0000001f
|
||||
#define NV04_IMAGE_BLIT 0x0000005f
|
||||
#define NV11_IMAGE_BLIT 0x0000009f
|
||||
#define NV01_IMAGE_FROM_CPU 0x00000021
|
||||
#define NV04_IMAGE_FROM_CPU 0x00000061
|
||||
#define NV05_IMAGE_FROM_CPU 0x00000065
|
||||
#define NV10_IMAGE_FROM_CPU 0x0000008a
|
||||
#define NV30_IMAGE_FROM_CPU 0x0000038a
|
||||
#define NV40_IMAGE_FROM_CPU 0x0000308a
|
||||
#define NV03_STRETCHED_IMAGE_FROM_CPU 0x00000036
|
||||
#define NV04_STRETCHED_IMAGE_FROM_CPU 0x00000076
|
||||
#define NV05_STRETCHED_IMAGE_FROM_CPU 0x00000066
|
||||
#define NV30_STRETCHED_IMAGE_FROM_CPU 0x00000366
|
||||
#define NV40_STRETCHED_IMAGE_FROM_CPU 0x00003066
|
||||
#define NV03_SCALED_IMAGE_FROM_MEMORY 0x00000037
|
||||
#define NV04_SCALED_IMAGE_FROM_MEMORY 0x00000077
|
||||
#define NV05_SCALED_IMAGE_FROM_MEMORY 0x00000063
|
||||
#define NV10_SCALED_IMAGE_FROM_MEMORY 0x00000089
|
||||
#define NV30_SCALED_IMAGE_FROM_MEMORY 0x00000389
|
||||
#define NV40_SCALED_IMAGE_FROM_MEMORY 0x00003089
|
||||
#define NV50_SCALED_IMAGE_FROM_MEMORY 0x00005089
|
||||
#define NV04_DVD_SUBPICTURE 0x00000038
|
||||
#define NV10_DVD_SUBPICTURE 0x00000088
|
||||
#define NV03_GDI_RECTANGLE_TEXT 0x0000004b
|
||||
#define NV04_GDI_RECTANGLE_TEXT 0x0000004a
|
||||
#define NV04_SWIZZLED_SURFACE 0x00000052
|
||||
#define NV11_SWIZZLED_SURFACE 0x0000009e
|
||||
#define NV30_SWIZZLED_SURFACE 0x0000039e
|
||||
#define NV40_SWIZZLED_SURFACE 0x0000309e
|
||||
#define NV03_CONTEXT_SURFACE_DST 0x00000058
|
||||
#define NV03_CONTEXT_SURFACE_SRC 0x00000059
|
||||
#define NV04_CONTEXT_SURFACES_2D 0x00000042
|
||||
#define NV10_CONTEXT_SURFACES_2D 0x00000062
|
||||
#define NV30_CONTEXT_SURFACES_2D 0x00000362
|
||||
#define NV40_CONTEXT_SURFACES_2D 0x00003062
|
||||
#define NV50_CONTEXT_SURFACES_2D 0x00005062
|
||||
#define NV04_INDEXED_IMAGE_FROM_CPU 0x00000060
|
||||
#define NV05_INDEXED_IMAGE_FROM_CPU 0x00000064
|
||||
#define NV30_INDEXED_IMAGE_FROM_CPU 0x00000364
|
||||
#define NV40_INDEXED_IMAGE_FROM_CPU 0x00003064
|
||||
#define NV10_TEXTURE_FROM_CPU 0x0000007b
|
||||
#define NV30_TEXTURE_FROM_CPU 0x0000037b
|
||||
#define NV40_TEXTURE_FROM_CPU 0x0000307b
|
||||
#define NV04_M2MF 0x00000039
|
||||
#define NV50_M2MF 0x00005039
|
||||
#define NVC0_M2MF 0x00009039
|
||||
#define NV03_TEXTURED_TRIANGLE 0x00000048
|
||||
#define NV04_TEXTURED_TRIANGLE 0x00000054
|
||||
#define NV10_TEXTURED_TRIANGLE 0x00000094
|
||||
#define NV04_MULTITEX_TRIANGLE 0x00000055
|
||||
#define NV10_MULTITEX_TRIANGLE 0x00000095
|
||||
#define NV03_CONTEXT_SURFACE_COLOR 0x0000005a
|
||||
#define NV03_CONTEXT_SURFACE_ZETA 0x0000005b
|
||||
#define NV04_CONTEXT_SURFACES_3D 0x00000053
|
||||
#define NV10_CONTEXT_SURFACES_3D 0x00000093
|
||||
#define NV10_3D 0x00000056
|
||||
#define NV11_3D 0x00000096
|
||||
#define NV17_3D 0x00000099
|
||||
#define NV20_3D 0x00000097
|
||||
#define NV25_3D 0x00000597
|
||||
#define NV30_3D 0x00000397
|
||||
#define NV35_3D 0x00000497
|
||||
#define NV34_3D 0x00000697
|
||||
#define NV40_3D 0x00004097
|
||||
#define NV44_3D 0x00004497
|
||||
#define NV50_3D 0x00005097
|
||||
#define NV84_3D 0x00008297
|
||||
#define NVA0_3D 0x00008397
|
||||
#define NVA3_3D 0x00008597
|
||||
#define NVAF_3D 0x00008697
|
||||
#define NVC0_3D 0x00009097
|
||||
#define NV50_2D 0x0000502d
|
||||
#define NVC0_2D 0x0000902d
|
||||
#define NV50_COMPUTE 0x000050c0
|
||||
#define NVA3_COMPUTE 0x000085c0
|
||||
#define NVC0_COMPUTE 0x000090c0
|
||||
#define NV84_CRYPT 0x000074c1
|
||||
#define NV01_SUBCHAN__SIZE 0x00002000
|
||||
#define NV01_DMA_FROM_MEMORY_CLASS 0x00000002
|
||||
#define NV01_DMA_TO_MEMORY_CLASS 0x00000003
|
||||
#define NV01_NULL_CLASS 0x00000030
|
||||
#define NV03_DMA_IN_MEMORY_CLASS 0x0000003d
|
||||
#define NV01_OP_CLIP_CLASS 0x00000010
|
||||
#define NV01_OP_BLEND_AND_CLASS 0x00000011
|
||||
#define NV01_BETA_CLASS 0x00000012
|
||||
#define NV04_BETA4_CLASS 0x00000072
|
||||
#define NV01_OP_ROP_AND_CLASS 0x00000013
|
||||
#define NV01_ROP_CLASS 0x00000014
|
||||
#define NV03_ROP_CLASS 0x00000043
|
||||
#define NV01_OP_CHROMA_CLASS 0x00000015
|
||||
#define NV01_OP_PLANE_SWITCH_CLASS 0x00000016
|
||||
#define NV01_CHROMA_CLASS 0x00000017
|
||||
#define NV04_CHROMA_CLASS 0x00000057
|
||||
#define NV01_PATTERN_CLASS 0x00000018
|
||||
#define NV04_PATTERN_CLASS 0x00000044
|
||||
#define NV01_CLIP_CLASS 0x00000019
|
||||
#define NV01_OP_SRCCOPY_AND_CLASS 0x00000064
|
||||
#define NV03_OP_SRCCOPY_CLASS 0x00000065
|
||||
#define NV04_OP_SRCCOPY_PREMULT_CLASS 0x00000066
|
||||
#define NV04_OP_BLEND_PREMULT_CLASS 0x00000067
|
||||
#define NV01_POINT_CLASS 0x0000001a
|
||||
#define NV01_LINE_CLASS 0x0000001b
|
||||
#define NV01_LIN_CLASS 0x0000001c
|
||||
#define NV04_LIN_CLASS 0x0000005c
|
||||
#define NV30_LIN_CLASS 0x0000035c
|
||||
#define NV40_LIN_CLASS 0x0000305c
|
||||
#define NV01_TRI_CLASS 0x0000001d
|
||||
#define NV04_TRI_CLASS 0x0000005d
|
||||
#define NV01_RECT_CLASS 0x0000001e
|
||||
#define NV04_RECT_CLASS 0x0000005e
|
||||
#define NV01_BLIT_CLASS 0x0000001f
|
||||
#define NV04_BLIT_CLASS 0x0000005f
|
||||
#define NV15_BLIT_CLASS 0x0000009f
|
||||
#define NV01_IFROMMEM_CLASS 0x00000020
|
||||
#define NV01_IFC_CLASS 0x00000021
|
||||
#define NV04_IFC_CLASS 0x00000061
|
||||
#define NV05_IFC_CLASS 0x00000065
|
||||
#define NV10_IFC_CLASS 0x0000008a
|
||||
#define NV30_IFC_CLASS 0x0000038a
|
||||
#define NV40_IFC_CLASS 0x0000308a
|
||||
#define NV01_BITMAP_CLASS 0x00000022
|
||||
#define NV01_ITOMEM_CLASS 0x00000025
|
||||
#define NV03_SIFC_CLASS 0x00000036
|
||||
#define NV04_SIFC_CLASS 0x00000076
|
||||
#define NV05_SIFC_CLASS 0x00000066
|
||||
#define NV30_SIFC_CLASS 0x00000366
|
||||
#define NV40_SIFC_CLASS 0x00003066
|
||||
#define NV03_SIFM_CLASS 0x00000037
|
||||
#define NV04_SIFM_CLASS 0x00000077
|
||||
#define NV05_SIFM_CLASS 0x00000063
|
||||
#define NV10_SIFM_CLASS 0x00000089
|
||||
#define NV30_SIFM_CLASS 0x00000389
|
||||
#define NV40_SIFM_CLASS 0x00003089
|
||||
#define NV50_SIFM_CLASS 0x00005089
|
||||
#define NV03_SYFM_CLASS 0x00000038
|
||||
#define NV03_GDI_CLASS 0x0000004b
|
||||
#define NV04_GDI_CLASS 0x0000004a
|
||||
#define NV04_SURFACE_SWZ_CLASS 0x00000052
|
||||
#define NV20_SURFACE_SWZ_CLASS 0x0000009e
|
||||
#define NV30_SURFACE_SWZ_CLASS 0x0000039e
|
||||
#define NV40_SURFACE_SWZ_CLASS 0x0000309e
|
||||
#define NV03_SURFACE_DST_CLASS 0x00000058
|
||||
#define NV03_SURFACE_SRC_CLASS 0x00000059
|
||||
#define NV04_SURFACE_2D_CLASS 0x00000042
|
||||
#define NV10_SURFACE_2D_CLASS 0x00000062
|
||||
#define NV30_SURFACE_2D_CLASS 0x00000362
|
||||
#define NV40_SURFACE_2D_CLASS 0x00003062
|
||||
#define NV50_SURFACE_2D_CLASS 0x00005062
|
||||
#define NV04_INDEX_CLASS 0x00000060
|
||||
#define NV05_INDEX_CLASS 0x00000064
|
||||
#define NV30_INDEX_CLASS 0x00000364
|
||||
#define NV40_INDEX_CLASS 0x00003064
|
||||
#define NV10_TEXUPLOAD_CLASS 0x0000007b
|
||||
#define NV30_TEXUPLOAD_CLASS 0x0000037b
|
||||
#define NV40_TEXUPLOAD_CLASS 0x0000307b
|
||||
#define NV04_DVD_SUBPICTURE_CLASS 0x00000038
|
||||
#define NV10_DVD_SUBPICTURE_CLASS 0x00000088
|
||||
#define NV03_M2MF_CLASS 0x00000039
|
||||
#define NV50_M2MF_CLASS 0x00005039
|
||||
#define NVC0_M2MF_CLASS 0x00009039
|
||||
#define NV03_SURFACE_COLOR_CLASS 0x0000005a
|
||||
#define NV03_SURFACE_ZETA_CLASS 0x0000005b
|
||||
#define NV03_TEXTURED_TRIANGLE_CLASS 0x00000048
|
||||
#define NV04_TEXTURED_TRIANGLE_CLASS 0x00000054
|
||||
#define NV10_TEXTURED_TRIANGLE_CLASS 0x00000094
|
||||
#define NV04_SURFACE_3D_CLASS 0x00000053
|
||||
#define NV10_SURFACE_3D_CLASS 0x00000093
|
||||
#define NV04_MULTITEX_TRIANGLE_CLASS 0x00000055
|
||||
#define NV10_MULTITEX_TRIANGLE_CLASS 0x00000095
|
||||
#define NV10_3D_CLASS 0x00000056
|
||||
#define NV15_3D_CLASS 0x00000096
|
||||
#define NV11_3D_CLASS 0x00000098
|
||||
#define NV17_3D_CLASS 0x00000099
|
||||
#define NV20_3D_CLASS 0x00000097
|
||||
#define NV25_3D_CLASS 0x00000597
|
||||
#define NV30_3D_CLASS 0x00000397
|
||||
#define NV35_3D_CLASS 0x00000497
|
||||
#define NV34_3D_CLASS 0x00000697
|
||||
#define NV40_3D_CLASS 0x00004097
|
||||
#define NV44_3D_CLASS 0x00004497
|
||||
#define NV50_3D_CLASS 0x00005097
|
||||
#define NV84_3D_CLASS 0x00008297
|
||||
#define NVA0_3D_CLASS 0x00008397
|
||||
#define NVA3_3D_CLASS 0x00008597
|
||||
#define NVAF_3D_CLASS 0x00008697
|
||||
#define NVC0_3D_CLASS 0x00009097
|
||||
#define NVC1_3D_CLASS 0x00009197
|
||||
#define NVC8_3D_CLASS 0x00009297
|
||||
#define NV50_2D_CLASS 0x0000502d
|
||||
#define NVC0_2D_CLASS 0x0000902d
|
||||
#define NV50_COMPUTE_CLASS 0x000050c0
|
||||
#define NVA3_COMPUTE_CLASS 0x000085c0
|
||||
#define NVC0_COMPUTE_CLASS 0x000090c0
|
||||
#define NVC8_COMPUTE_CLASS 0x000092c0
|
||||
#define NV84_CRYPT_CLASS 0x000074c1
|
||||
#define BLOB_NVC0_PCOPY1_CLASS 0x000090b8
|
||||
#define BLOB_NVC0_PCOPY0_CLASS 0x000090b5
|
||||
#define NV31_MPEG_CLASS 0x00003174
|
||||
#define NV84_MPEG_CLASS 0x00008274
|
||||
|
||||
#define NV01_SUBCHAN__SIZE 0x00008000
|
||||
#define NV01_SUBCHAN 0x00000000
|
||||
|
||||
#define NV01_SUBCHAN_OBJECT 0x00000000
|
||||
|
|
@ -217,37 +238,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NV04_GRAPH_NOP 0x00000100
|
||||
|
||||
#define NV01_GRAPH_NOTIFY 0x00000104
|
||||
#define NV01_GRAPH_NOTIFY_WRITE 0x00000000
|
||||
#define NV01_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001
|
||||
|
||||
#define NV50_GRAPH_WAIT_FOR_IDLE 0x00000110
|
||||
|
||||
#define NVA3_GRAPH_UNK0120 0x00000120
|
||||
|
||||
#define NVA3_GRAPH_UNK0124 0x00000124
|
||||
|
||||
#define NV40_GRAPH_PM_TRIGGER 0x00000140
|
||||
|
||||
#define NVC0_SUBCHAN__SIZE 0x00008000
|
||||
#define NVC0_SUBCHAN 0x00000000
|
||||
|
||||
#define NVC0_SUBCHAN_OBJECT 0x00000000
|
||||
|
||||
|
||||
#define NVC0_SUBCHAN_QUERY_ADDRESS_HIGH 0x00000010
|
||||
|
||||
#define NVC0_SUBCHAN_QUERY_ADDRESS_LOW 0x00000014
|
||||
|
||||
#define NVC0_SUBCHAN_QUERY_SEQUENCE 0x00000018
|
||||
|
||||
#define NVC0_SUBCHAN_QUERY_GET 0x0000001c
|
||||
|
||||
#define NVC0_SUBCHAN_REF_CNT 0x00000050
|
||||
|
||||
#define NVC0_GRAPH 0x00000000
|
||||
|
||||
#define NVC0_GRAPH_NOP 0x00000100
|
||||
#define NV04_GRAPH_NOTIFY 0x00000104
|
||||
#define NV04_GRAPH_NOTIFY_WRITE 0x00000000
|
||||
#define NV04_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001
|
||||
|
||||
#define NVC0_GRAPH_NOTIFY_ADDRESS_HIGH 0x00000104
|
||||
|
||||
|
|
@ -257,7 +250,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NVC0_GRAPH_NOTIFY_WRITE 0x00000000
|
||||
#define NVC0_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001
|
||||
|
||||
#define NVC0_GRAPH_SERIALIZE 0x00000110
|
||||
#define NV50_GRAPH_SERIALIZE 0x00000110
|
||||
|
||||
#define NVC0_GRAPH_MACRO_UPLOAD_POS 0x00000114
|
||||
|
||||
|
|
@ -267,5 +260,42 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NVC0_GRAPH_MACRO_POS 0x00000120
|
||||
|
||||
#define NVA3_GRAPH_UNK0120 0x00000120
|
||||
|
||||
#endif /* NV_OBJECT_XML */
|
||||
#define NVA3_GRAPH_UNK0124 0x00000124
|
||||
|
||||
#define NVC0_GRAPH_UNK0124 0x00000124
|
||||
|
||||
#define NVC0_GRAPH_COND_ADDRESS_HIGH 0x00000130
|
||||
|
||||
#define NVC0_GRAPH_COND_ADDRESS_LOW 0x00000134
|
||||
|
||||
#define NVC0_GRAPH_COND_MODE 0x00000138
|
||||
#define NVC0_GRAPH_COND_MODE_NEVER 0x00000000
|
||||
#define NVC0_GRAPH_COND_MODE_ALWAYS 0x00000001
|
||||
#define NVC0_GRAPH_COND_MODE_RES_NON_ZERO 0x00000002
|
||||
#define NVC0_GRAPH_COND_MODE_EQUAL 0x00000003
|
||||
#define NVC0_GRAPH_COND_MODE_NOT_EQUAL 0x00000004
|
||||
|
||||
#define NVC0_GRAPH_UNK013C 0x0000013c
|
||||
|
||||
#define NV40_GRAPH_PM_TRIGGER 0x00000140
|
||||
|
||||
#define NVC0_GRAPH_UNK0150 0x00000150
|
||||
|
||||
#define NVC0_GRAPH_UNK0154 0x00000154
|
||||
|
||||
#define NVC0_GRAPH_SCRATCH(i0) (0x00003400 + 0x4*(i0))
|
||||
#define NVC0_GRAPH_SCRATCH__ESIZE 0x00000004
|
||||
#define NVC0_GRAPH_SCRATCH__LEN 0x00000080
|
||||
|
||||
#define NVC0_GRAPH_MACRO(i0) (0x00003800 + 0x8*(i0))
|
||||
#define NVC0_GRAPH_MACRO__ESIZE 0x00000008
|
||||
#define NVC0_GRAPH_MACRO__LEN 0x00000080
|
||||
|
||||
#define NVC0_GRAPH_MACRO_PARAM(i0) (0x00003804 + 0x8*(i0))
|
||||
#define NVC0_GRAPH_MACRO_PARAM__ESIZE 0x00000008
|
||||
#define NVC0_GRAPH_MACRO_PARAM__LEN 0x00000080
|
||||
|
||||
|
||||
#endif /* RNNDB_NV_OBJECT_XML */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef NV50_3D_XML
|
||||
#define NV50_3D_XML
|
||||
#ifndef RNNDB_NV50_3D_XML
|
||||
#define RNNDB_NV50_3D_XML
|
||||
|
||||
/* Autogenerated file, DO NOT EDIT manually!
|
||||
|
||||
|
|
@ -8,15 +8,15 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
|
|||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- nv50_3d.xml ( 64479 bytes, from 2011-02-27 17:58:08)
|
||||
- copyright.xml ( 6452 bytes, from 2010-12-15 23:45:18)
|
||||
- nv_defs.xml ( 4437 bytes, from 2010-12-15 23:45:18)
|
||||
- nv50_defs.xml ( 4487 bytes, from 2010-12-15 23:45:18)
|
||||
- nv_3ddefs.xml ( 16394 bytes, from 2010-12-15 23:45:18)
|
||||
- nv_object.xml ( 12191 bytes, from 2011-02-27 17:58:08)
|
||||
- nvchipsets.xml ( 3074 bytes, from 2011-02-27 17:58:08)
|
||||
- rnndb/nv50_3d.xml ( 65226 bytes, from 2012-01-28 13:46:30)
|
||||
- ./rnndb/copyright.xml ( 6452 bytes, from 2011-08-11 18:25:12)
|
||||
- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-08-11 18:25:12)
|
||||
- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-08-11 18:25:12)
|
||||
- ./rnndb/nvchipsets.xml ( 3617 bytes, from 2011-08-11 18:25:12)
|
||||
- ./rnndb/nv_3ddefs.xml ( 16394 bytes, from 2011-08-11 18:25:12)
|
||||
- ./rnndb/nv_object.xml ( 12672 bytes, from 2011-08-11 18:25:12)
|
||||
|
||||
Copyright (C) 2006-2011 by the following authors:
|
||||
Copyright (C) 2006-2012 by the following authors:
|
||||
- Artur Huillet <arthur.huillet@free.fr> (ahuillet)
|
||||
- Ben Skeggs (darktama, darktama_)
|
||||
- B. R. <koala_br@users.sourceforge.net> (koala_br)
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -592,9 +592,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NV50_3D_CLIPID_ADDRESS_LOW 0x00000fd0
|
||||
|
||||
#define NV50_3D_MAP_SEMANTIC_5 0x00000fd4
|
||||
#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__MASK 0x000000ff
|
||||
#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__SHIFT 0
|
||||
#define NV50_3D_SEMANTIC_VIEWPORT 0x00000fd4
|
||||
#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__MASK 0x000000ff
|
||||
#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__SHIFT 0
|
||||
|
||||
#define NV50_3D_UNK0FD8 0x00000fd8
|
||||
#define NV50_3D_UNK0FD8_UNK0 0x00000001
|
||||
|
|
@ -1184,7 +1184,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV50_3D_BIND_TSC2__ESIZE 0x00000008
|
||||
#define NV50_3D_BIND_TSC2__LEN 0x00000003
|
||||
#define NV50_3D_BIND_TSC2_VALID 0x00000001
|
||||
#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x000000f0
|
||||
#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x00000010
|
||||
#define NV50_3D_BIND_TSC2_SAMPLER__SHIFT 4
|
||||
#define NV50_3D_BIND_TSC2_TSC__MASK 0x001ff000
|
||||
#define NV50_3D_BIND_TSC2_TSC__SHIFT 12
|
||||
|
|
@ -1193,7 +1193,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV50_3D_BIND_TIC2__ESIZE 0x00000008
|
||||
#define NV50_3D_BIND_TIC2__LEN 0x00000003
|
||||
#define NV50_3D_BIND_TIC2_VALID 0x00000001
|
||||
#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x000001fe
|
||||
#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x00000002
|
||||
#define NV50_3D_BIND_TIC2_TEXTURE__SHIFT 1
|
||||
#define NV50_3D_BIND_TIC2_TIC__MASK 0x7ffffe00
|
||||
#define NV50_3D_BIND_TIC2_TIC__SHIFT 9
|
||||
|
|
@ -1217,15 +1217,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK 0xffff0000
|
||||
#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT 16
|
||||
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE 0x00001510
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_0 0x00000001
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_1 0x00000002
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_2 0x00000004
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_3 0x00000008
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_4 0x00000010
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_5 0x00000020
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_6 0x00000040
|
||||
#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_7 0x00000080
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE 0x00001510
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_0 0x00000001
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_1 0x00000002
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_2 0x00000004
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_3 0x00000008
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_4 0x00000010
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_5 0x00000020
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_6 0x00000040
|
||||
#define NV50_3D_CLIP_DISTANCE_ENABLE_7 0x00000080
|
||||
|
||||
#define NV50_3D_SAMPLECNT_ENABLE 0x00001514
|
||||
|
||||
|
|
@ -1391,9 +1391,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV50_3D_MULTISAMPLE_MODE_MS8 0x00000003
|
||||
#define NV50_3D_MULTISAMPLE_MODE_MS8_ALT 0x00000004
|
||||
#define NV50_3D_MULTISAMPLE_MODE_MS2_ALT 0x00000005
|
||||
#define NV50_3D_MULTISAMPLE_MODE_UNK6 0x00000006
|
||||
#define NV50_3D_MULTISAMPLE_MODE_MS4_CS4 0x00000008
|
||||
#define NV50_3D_MULTISAMPLE_MODE_MS4_CS12 0x00000009
|
||||
#define NV50_3D_MULTISAMPLE_MODE_MS8_CS8 0x0000000a
|
||||
#define NV50_3D_MULTISAMPLE_MODE_MS8_CS24 0x0000000b
|
||||
|
||||
#define NV50_3D_VERTEX_BEGIN_D3D 0x000015d4
|
||||
#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK 0x0fffffff
|
||||
|
|
@ -1440,7 +1442,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV50_3D_VERTEX_END_GL_UNK0 0x00000001
|
||||
#define NVA0_3D_VERTEX_END_GL_UNK1 0x00000002
|
||||
|
||||
#define NV50_3D_EDGEFLAG_ENABLE 0x000015e4
|
||||
#define NV50_3D_EDGEFLAG 0x000015e4
|
||||
|
||||
#define NV50_3D_VB_ELEMENT_U32 0x000015e8
|
||||
|
||||
|
|
@ -1666,34 +1668,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NV50_3D_GP_VIEWPORT_ID_ENABLE 0x00001900
|
||||
|
||||
#define NV50_3D_MAP_SEMANTIC_0 0x00001904
|
||||
#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__MASK 0x000000ff
|
||||
#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT 0
|
||||
#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__MASK 0x0000ff00
|
||||
#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__SHIFT 8
|
||||
#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__MASK 0x00ff0000
|
||||
#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__SHIFT 16
|
||||
#define NV50_3D_MAP_SEMANTIC_0_CLMP_EN 0x01000000
|
||||
#define NV50_3D_SEMANTIC_COLOR 0x00001904
|
||||
#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__MASK 0x000000ff
|
||||
#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT 0
|
||||
#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__MASK 0x0000ff00
|
||||
#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__SHIFT 8
|
||||
#define NV50_3D_SEMANTIC_COLOR_COLR_NR__MASK 0x00ff0000
|
||||
#define NV50_3D_SEMANTIC_COLOR_COLR_NR__SHIFT 16
|
||||
#define NV50_3D_SEMANTIC_COLOR_CLMP_EN 0x01000000
|
||||
|
||||
#define NV50_3D_MAP_SEMANTIC_1 0x00001908
|
||||
#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__MASK 0x000000ff
|
||||
#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__SHIFT 0
|
||||
#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__MASK 0x00000f00
|
||||
#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__SHIFT 8
|
||||
#define NV50_3D_SEMANTIC_CLIP 0x00001908
|
||||
#define NV50_3D_SEMANTIC_CLIP_CLIP_START__MASK 0x000000ff
|
||||
#define NV50_3D_SEMANTIC_CLIP_CLIP_START__SHIFT 0
|
||||
#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__MASK 0x00000f00
|
||||
#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__SHIFT 8
|
||||
|
||||
#define NV50_3D_MAP_SEMANTIC_2 0x0000190c
|
||||
#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__MASK 0x000000ff
|
||||
#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__SHIFT 0
|
||||
#define NV50_3D_SEMANTIC_LAYER 0x0000190c
|
||||
#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__MASK 0x000000ff
|
||||
#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__SHIFT 0
|
||||
|
||||
#define NV50_3D_MAP_SEMANTIC_3 0x00001910
|
||||
#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK 0x00000001
|
||||
#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__SHIFT 0
|
||||
#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__MASK 0x00000ff0
|
||||
#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__SHIFT 4
|
||||
#define NV50_3D_SEMANTIC_PTSZ 0x00001910
|
||||
#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK 0x00000001
|
||||
#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__SHIFT 0
|
||||
#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__MASK 0x00000ff0
|
||||
#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__SHIFT 4
|
||||
|
||||
#define NV50_3D_MAP_SEMANTIC_4 0x00001914
|
||||
#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__MASK 0x000000ff
|
||||
#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__SHIFT 0
|
||||
#define NV50_3D_SEMANTIC_PRIM_ID 0x00001914
|
||||
#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__MASK 0x000000ff
|
||||
#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__SHIFT 0
|
||||
|
||||
#define NV50_3D_CULL_FACE_ENABLE 0x00001918
|
||||
|
||||
|
|
@ -1729,15 +1731,39 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1 0x00001000
|
||||
#define NV84_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2 0x00002000
|
||||
|
||||
#define NV50_3D_UNK1940 0x00001940
|
||||
#define NV50_3D_UNK1940_0 0x00000001
|
||||
#define NV50_3D_UNK1940_1 0x00000010
|
||||
#define NV50_3D_UNK1940_2 0x00000100
|
||||
#define NV50_3D_UNK1940_3 0x00001000
|
||||
#define NV50_3D_UNK1940_4 0x00010000
|
||||
#define NV50_3D_UNK1940_5 0x00100000
|
||||
#define NV50_3D_UNK1940_6 0x01000000
|
||||
#define NV50_3D_UNK1940_7 0x10000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE 0x00001940
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_0__MASK 0x00000001
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_0__SHIFT 0
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_0_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_0_CULL 0x00000001
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_1__MASK 0x00000010
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_1__SHIFT 4
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_1_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_1_CULL 0x00000010
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_2__MASK 0x00000100
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_2__SHIFT 8
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_2_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_2_CULL 0x00000100
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_3__MASK 0x00001000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_3__SHIFT 12
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_3_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_3_CULL 0x00001000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_4__MASK 0x00010000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_4__SHIFT 16
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_4_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_4_CULL 0x00010000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_5__MASK 0x00100000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_5__SHIFT 20
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_5_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_5_CULL 0x00100000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_6__MASK 0x01000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_6__SHIFT 24
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_6_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_6_CULL 0x01000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_7__MASK 0x10000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_7__SHIFT 28
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_7_CLIP 0x00000000
|
||||
#define NV50_3D_CLIP_DISTANCE_MODE_7_CULL 0x10000000
|
||||
|
||||
#define NVA3_3D_UNK1944 0x00001944
|
||||
|
||||
|
|
@ -2048,7 +2074,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NVA3_3D_IBLEND__ESIZE 0x00000020
|
||||
#define NVA3_3D_IBLEND__LEN 0x00000008
|
||||
|
||||
#define NVA3_3D_IBLEND_UNK00(i0) (0x00001e00 + 0x20*(i0))
|
||||
#define NVA3_3D_IBLEND_SEPARATE_ALPHA(i0) (0x00001e00 + 0x20*(i0))
|
||||
|
||||
#define NVA3_3D_IBLEND_EQUATION_RGB(i0) (0x00001e04 + 0x20*(i0))
|
||||
#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_ADD 0x00008006
|
||||
|
|
@ -2081,4 +2107,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__LEN 0x00000020
|
||||
|
||||
|
||||
#endif /* NV50_3D_XML */
|
||||
#endif /* RNNDB_NV50_3D_XML */
|
||||
|
|
|
|||
|
|
@ -33,40 +33,36 @@ static void
|
|||
nv50_flush(struct pipe_context *pipe,
|
||||
struct pipe_fence_handle **fence)
|
||||
{
|
||||
struct nouveau_screen *screen = &nv50_context(pipe)->screen->base;
|
||||
struct nouveau_screen *screen = nouveau_screen(pipe->screen);
|
||||
|
||||
if (fence)
|
||||
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
|
||||
|
||||
/* Try to emit before firing to avoid having to flush again right after
|
||||
* in case we have to wait on this fence.
|
||||
*/
|
||||
nouveau_fence_emit(screen->fence.current);
|
||||
|
||||
FIRE_RING(screen->channel);
|
||||
PUSH_KICK(screen->pushbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_texture_barrier(struct pipe_context *pipe)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
|
||||
OUT_RING (chan, 0x20);
|
||||
BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
|
||||
PUSH_DATA (push, 0x20);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_default_flush_notify(struct nouveau_channel *chan)
|
||||
nv50_default_kick_notify(struct nouveau_pushbuf *push)
|
||||
{
|
||||
struct nv50_screen *screen = chan->user_private;
|
||||
struct nv50_screen *screen = push->user_priv;
|
||||
|
||||
if (!screen)
|
||||
return;
|
||||
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
nouveau_fence_next(&screen->base);
|
||||
if (screen) {
|
||||
nouveau_fence_next(&screen->base);
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
if (screen->cur_ctx)
|
||||
screen->cur_ctx->state.flushed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -74,8 +70,8 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
|
|||
{
|
||||
unsigned s, i;
|
||||
|
||||
for (i = 0; i < NV50_BUFCTX_COUNT; ++i)
|
||||
nv50_bufctx_reset(nv50, i);
|
||||
nouveau_bufctx_del(&nv50->bufctx_3d);
|
||||
nouveau_bufctx_del(&nv50->bufctx);
|
||||
|
||||
for (i = 0; i < nv50->num_vtxbufs; ++i)
|
||||
pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
|
||||
|
|
@ -96,13 +92,18 @@ nv50_destroy(struct pipe_context *pipe)
|
|||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
|
||||
if (nv50_context_screen(nv50)->cur_ctx == nv50) {
|
||||
nv50->base.pushbuf->kick_notify = NULL;
|
||||
nv50_context_screen(nv50)->cur_ctx = NULL;
|
||||
nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
|
||||
}
|
||||
/* need to flush before destroying the bufctx */
|
||||
nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);
|
||||
|
||||
nv50_context_unreference_resources(nv50);
|
||||
|
||||
draw_destroy(nv50->draw);
|
||||
|
||||
if (nv50->screen->cur_ctx == nv50)
|
||||
nv50->screen->cur_ctx = NULL;
|
||||
|
||||
FREE(nv50);
|
||||
}
|
||||
|
||||
|
|
@ -112,17 +113,28 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
|
|||
struct nv50_screen *screen = nv50_screen(pscreen);
|
||||
struct nv50_context *nv50;
|
||||
struct pipe_context *pipe;
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
|
||||
nv50 = CALLOC_STRUCT(nv50_context);
|
||||
if (!nv50)
|
||||
return NULL;
|
||||
pipe = &nv50->base.pipe;
|
||||
|
||||
nv50->screen = screen;
|
||||
nv50->base.pushbuf = screen->base.pushbuf;
|
||||
|
||||
ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT,
|
||||
&nv50->bufctx_3d);
|
||||
if (!ret)
|
||||
ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
nv50->base.screen = &screen->base;
|
||||
nv50->base.copy_data = nv50_m2mf_copy_linear;
|
||||
nv50->base.push_data = nv50_sifc_linear_u8;
|
||||
|
||||
nv50->screen = screen;
|
||||
pipe->screen = pscreen;
|
||||
pipe->priv = priv;
|
||||
|
||||
|
|
@ -134,9 +146,10 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
|
|||
pipe->flush = nv50_flush;
|
||||
pipe->texture_barrier = nv50_texture_barrier;
|
||||
|
||||
if (!screen->cur_ctx)
|
||||
if (!screen->cur_ctx) {
|
||||
screen->cur_ctx = nv50;
|
||||
screen->base.channel->flush_notify = nv50_default_flush_notify;
|
||||
nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
|
||||
}
|
||||
|
||||
nv50_init_query_functions(nv50);
|
||||
nv50_init_surface_functions(nv50);
|
||||
|
|
@ -149,72 +162,41 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
|
|||
|
||||
nouveau_context_init_vdec(&nv50->base);
|
||||
|
||||
flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
|
||||
|
||||
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->code);
|
||||
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms);
|
||||
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc);
|
||||
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo);
|
||||
|
||||
flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
|
||||
|
||||
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo);
|
||||
BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
struct resident {
|
||||
struct nv04_resource *res;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
void
|
||||
nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
|
||||
struct nv04_resource *resource, uint32_t flags)
|
||||
{
|
||||
struct resident rsd = { resource, flags };
|
||||
|
||||
if (!resource->bo)
|
||||
return;
|
||||
nv50->residents_size += sizeof(struct resident);
|
||||
|
||||
/* We don't need to reference the resource here, it will be referenced
|
||||
* in the context/state, and bufctx will be reset when state changes.
|
||||
*/
|
||||
util_dynarray_append(&nv50->residents[ctx], struct resident, rsd);
|
||||
out_err:
|
||||
if (nv50) {
|
||||
if (nv50->bufctx_3d)
|
||||
nouveau_bufctx_del(&nv50->bufctx_3d);
|
||||
if (nv50->bufctx)
|
||||
nouveau_bufctx_del(&nv50->bufctx);
|
||||
FREE(nv50);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
|
||||
struct nv04_resource *resource)
|
||||
nv50_bufctx_fence(struct nouveau_bufctx *bufctx, boolean on_flush)
|
||||
{
|
||||
struct resident *rsd, *top;
|
||||
unsigned i;
|
||||
struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
|
||||
struct nouveau_list *it;
|
||||
|
||||
for (i = 0; i < nv50->residents[ctx].size / sizeof(struct resident); ++i) {
|
||||
rsd = util_dynarray_element(&nv50->residents[ctx], struct resident, i);
|
||||
|
||||
if (rsd->res == resource) {
|
||||
top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident);
|
||||
if (rsd != top)
|
||||
*rsd = *top;
|
||||
nv50->residents_size -= sizeof(struct resident);
|
||||
break;
|
||||
}
|
||||
for (it = list->next; it != list; it = it->next) {
|
||||
struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
|
||||
struct nv04_resource *res = ref->priv;
|
||||
if (res)
|
||||
nv50_resource_validate(res, (unsigned)ref->priv_data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nv50_bufctx_emit_relocs(struct nv50_context *nv50)
|
||||
{
|
||||
struct resident *rsd;
|
||||
struct util_dynarray *array;
|
||||
unsigned ctx, i, n;
|
||||
|
||||
n = nv50->residents_size / sizeof(struct resident);
|
||||
n += NV50_SCREEN_RESIDENT_BO_COUNT;
|
||||
|
||||
MARK_RING(nv50->screen->base.channel, 0, n);
|
||||
|
||||
for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) {
|
||||
array = &nv50->residents[ctx];
|
||||
|
||||
n = array->size / sizeof(struct resident);
|
||||
for (i = 0; i < n; ++i) {
|
||||
rsd = util_dynarray_element(array, struct resident, i);
|
||||
|
||||
nv50_resource_validate(rsd->res, rsd->flags);
|
||||
}
|
||||
}
|
||||
|
||||
nv50_screen_make_buffers_resident(nv50->screen);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,12 +46,20 @@
|
|||
#define NV50_NEW_CONSTBUF (1 << 18)
|
||||
#define NV50_NEW_TEXTURES (1 << 19)
|
||||
#define NV50_NEW_SAMPLERS (1 << 20)
|
||||
#define NV50_NEW_CONTEXT (1 << 31)
|
||||
|
||||
#define NV50_BUFCTX_CONSTANT 0
|
||||
#define NV50_BUFCTX_FRAME 1
|
||||
#define NV50_BUFCTX_VERTEX 2
|
||||
#define NV50_BUFCTX_TEXTURES 3
|
||||
#define NV50_BUFCTX_COUNT 4
|
||||
#define NV50_BIND_FB 0
|
||||
#define NV50_BIND_VERTEX 1
|
||||
#define NV50_BIND_VERTEX_TMP 2
|
||||
#define NV50_BIND_INDEX 3
|
||||
#define NV50_BIND_TEXTURES 4
|
||||
#define NV50_BIND_CB(s, i) (5 + 16 * (s) + (i))
|
||||
#define NV50_BIND_SCREEN 53
|
||||
#define NV50_BIND_TLS 54
|
||||
#define NV50_BIND_COUNT 55
|
||||
#define NV50_BIND_2D 0
|
||||
#define NV50_BIND_M2MF 0
|
||||
#define NV50_BIND_FENCE 1
|
||||
|
||||
#define NV50_CB_TMP 123
|
||||
/* fixed constant buffer binding points - low indices for user's constbufs */
|
||||
|
|
@ -60,13 +68,14 @@
|
|||
#define NV50_CB_PFP 125
|
||||
#define NV50_CB_AUX 127
|
||||
|
||||
|
||||
struct nv50_context {
|
||||
struct nouveau_context base;
|
||||
|
||||
struct nv50_screen *screen;
|
||||
|
||||
struct util_dynarray residents[NV50_BUFCTX_COUNT];
|
||||
unsigned residents_size;
|
||||
struct nouveau_bufctx *bufctx_3d;
|
||||
struct nouveau_bufctx *bufctx;
|
||||
|
||||
uint32_t dirty;
|
||||
|
||||
|
|
@ -79,6 +88,9 @@ struct nv50_context {
|
|||
int32_t index_bias;
|
||||
boolean prim_restart;
|
||||
boolean point_sprite;
|
||||
boolean rt_serialize;
|
||||
boolean flushed;
|
||||
uint8_t tls_required;
|
||||
uint8_t num_vtxbufs;
|
||||
uint8_t num_vtxelts;
|
||||
uint8_t num_textures[3];
|
||||
|
|
@ -97,6 +109,7 @@ struct nv50_context {
|
|||
|
||||
struct pipe_resource *constbuf[3][16];
|
||||
uint16_t constbuf_dirty[3];
|
||||
uint16_t constbuf_valid[3];
|
||||
|
||||
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
|
||||
unsigned num_vtxbufs;
|
||||
|
|
@ -132,22 +145,19 @@ nv50_context(struct pipe_context *pipe)
|
|||
return (struct nv50_context *)pipe;
|
||||
}
|
||||
|
||||
static INLINE struct nv50_screen *
|
||||
nv50_context_screen(struct nv50_context *nv50)
|
||||
{
|
||||
return nv50_screen(&nv50->base.screen->base);
|
||||
}
|
||||
|
||||
|
||||
/* nv50_context.c */
|
||||
struct pipe_context *nv50_create(struct pipe_screen *, void *);
|
||||
|
||||
void nv50_default_flush_notify(struct nouveau_channel *);
|
||||
void nv50_bufctx_fence(struct nouveau_bufctx *, boolean on_flush);
|
||||
|
||||
void nv50_bufctx_emit_relocs(struct nv50_context *);
|
||||
void nv50_bufctx_add_resident(struct nv50_context *, int ctx,
|
||||
struct nv04_resource *, uint32_t flags);
|
||||
void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
|
||||
struct nv04_resource *);
|
||||
static INLINE void
|
||||
nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
|
||||
{
|
||||
nv50->residents_size -= nv50->residents[ctx].size;
|
||||
util_dynarray_resize(&nv50->residents[ctx], 0);
|
||||
}
|
||||
void nv50_default_kick_notify(struct nouveau_pushbuf *);
|
||||
|
||||
/* nv50_draw.c */
|
||||
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
|
||||
|
|
@ -194,7 +204,7 @@ nv50_create_sampler_view(struct pipe_context *,
|
|||
|
||||
/* nv50_transfer.c */
|
||||
void
|
||||
nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
||||
nv50_m2mf_transfer_rect(struct nv50_context *,
|
||||
const struct nv50_m2mf_rect *dst,
|
||||
const struct nv50_m2mf_rect *src,
|
||||
uint32_t nblocksx, uint32_t nblocksy);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
static INLINE uint32_t
|
||||
nv50_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz)
|
||||
{
|
||||
return nvc0_tex_choose_tile_dims(nx, ny * 2, nz) >> 4;
|
||||
return nvc0_tex_choose_tile_dims(nx, ny * 2, nz);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
|
@ -41,58 +41,60 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
|
|||
|
||||
uint32_t tile_flags;
|
||||
|
||||
if (mt->base.base.bind & PIPE_BIND_CURSOR)
|
||||
return NOUVEAU_BO_TILE_SCANOUT;
|
||||
if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
|
||||
return 0;
|
||||
if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
|
||||
return 0;
|
||||
|
||||
switch (mt->base.base.format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
tile_flags = 0x6c00 + (ms << 8);
|
||||
tile_flags = 0x6c + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
|
||||
tile_flags = 0x1800 + (ms << 8);
|
||||
tile_flags = 0x18 + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
|
||||
tile_flags = 0x22800 + (ms << 8);
|
||||
tile_flags = 0x128 + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT:
|
||||
tile_flags = 0x4000 + (ms << 8);
|
||||
tile_flags = 0x40 + (ms << 8);
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
|
||||
tile_flags = 0x6000 + (ms << 8);
|
||||
tile_flags = 0x60 + (ms << 8);
|
||||
break;
|
||||
default:
|
||||
switch (util_format_get_blocksizebits(mt->base.base.format)) {
|
||||
case 128:
|
||||
assert(ms < 3);
|
||||
tile_flags = 0x7400;
|
||||
tile_flags = 0x74;
|
||||
break;
|
||||
case 64:
|
||||
switch (ms) {
|
||||
case 2: tile_flags = 0x17c00; break;
|
||||
case 3: tile_flags = 0x17d00; break;
|
||||
case 2: tile_flags = 0xfc; break;
|
||||
case 3: tile_flags = 0xfd; break;
|
||||
default:
|
||||
tile_flags = 0x7000;
|
||||
tile_flags = 0x70;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (mt->base.base.bind & PIPE_BIND_SCANOUT) {
|
||||
assert(ms == 0);
|
||||
tile_flags = 0x7a00;
|
||||
tile_flags = 0x7a;
|
||||
} else {
|
||||
switch (ms) {
|
||||
case 2: tile_flags = 0x17800; break;
|
||||
case 3: tile_flags = 0x17900; break;
|
||||
case 2: tile_flags = 0xf8; break;
|
||||
case 3: tile_flags = 0xf9; break;
|
||||
default:
|
||||
tile_flags = 0x7000;
|
||||
tile_flags = 0x70;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
case 8:
|
||||
tile_flags = 0x7000;
|
||||
tile_flags = 0x70;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -101,14 +103,8 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
|
|||
tile_flags = 0;
|
||||
}
|
||||
|
||||
if (mt->base.base.bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR))
|
||||
tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
|
||||
|
||||
if (!compressed)
|
||||
tile_flags &= ~0x30000;
|
||||
|
||||
if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
|
||||
tile_flags &= ~0x3ff00;
|
||||
tile_flags &= ~0x180;
|
||||
|
||||
return tile_flags;
|
||||
}
|
||||
|
|
@ -118,7 +114,7 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
|
|||
{
|
||||
struct nv50_miptree *mt = nv50_miptree(pt);
|
||||
|
||||
nouveau_screen_bo_release(pscreen, mt->base.bo);
|
||||
nouveau_bo_ref(NULL, &mt->base.bo);
|
||||
|
||||
FREE(mt);
|
||||
}
|
||||
|
|
@ -260,7 +256,8 @@ nv50_miptree_create(struct pipe_screen *pscreen,
|
|||
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
int ret;
|
||||
uint32_t tile_flags;
|
||||
union nouveau_bo_config bo_config;
|
||||
uint32_t bo_flags;
|
||||
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
|
@ -270,30 +267,34 @@ nv50_miptree_create(struct pipe_screen *pscreen,
|
|||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
|
||||
tile_flags = nv50_mt_choose_storage_type(mt, TRUE);
|
||||
bo_config.nv50.memtype = nv50_mt_choose_storage_type(mt, TRUE);
|
||||
|
||||
if (!nv50_miptree_init_ms_mode(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
|
||||
if (bo_config.nv50.memtype != 0) {
|
||||
nv50_miptree_init_layout_tiled(mt);
|
||||
} else
|
||||
if (!nv50_miptree_init_layout_linear(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
bo_config.nv50.tile_mode = mt->level[0].tile_mode;
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
|
||||
mt->total_size,
|
||||
mt->level[0].tile_mode, tile_flags,
|
||||
&mt->base.bo);
|
||||
bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP;
|
||||
if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
|
||||
bo_flags |= NOUVEAU_BO_CONTIG;
|
||||
|
||||
ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config,
|
||||
&mt->base.bo);
|
||||
if (ret) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
mt->base.domain = NOUVEAU_BO_VRAM;
|
||||
mt->base.address = mt->base.bo->offset;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
|
@ -323,6 +324,8 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
|
|||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
mt->base.domain = NOUVEAU_BO_VRAM;
|
||||
mt->base.address = mt->base.bo->offset;
|
||||
|
||||
mt->base.base = *templ;
|
||||
mt->base.vtbl = &nv50_miptree_vtbl;
|
||||
|
|
@ -330,7 +333,7 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
|
|||
mt->base.base.screen = pscreen;
|
||||
mt->level[0].pitch = stride;
|
||||
mt->level[0].offset = 0;
|
||||
mt->level[0].tile_mode = mt->base.bo->tile_mode;
|
||||
mt->level[0].tile_mode = mt->base.bo->config.nv50.tile_mode;
|
||||
|
||||
/* no need to adjust bo reference count */
|
||||
return &mt->base.base;
|
||||
|
|
|
|||
|
|
@ -489,7 +489,8 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti)
|
|||
++nintp;
|
||||
}
|
||||
|
||||
p->fp.colors = 4 << NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT; /* after HPOS */
|
||||
/* after HPOS */
|
||||
p->fp.colors = 4 << NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT;
|
||||
|
||||
for (i = 0; i < p->in_nr; ++i) {
|
||||
int j = p->in[i].id;
|
||||
|
|
@ -680,8 +681,8 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
|
|||
const struct pipe_shader_state pipe = p->pipe;
|
||||
const ubyte type = p->type;
|
||||
|
||||
if (p->res)
|
||||
nouveau_resource_free(&p->res);
|
||||
if (p->mem)
|
||||
nouveau_heap_free(&p->mem);
|
||||
|
||||
if (p->code)
|
||||
FREE(p->code);
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ struct nv50_program {
|
|||
void *fixups;
|
||||
unsigned num_fixups;
|
||||
|
||||
struct nouveau_resource *res;
|
||||
struct nouveau_heap *mem;
|
||||
};
|
||||
|
||||
#define NV50_INTERP_LINEAR (1 << 0)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "nv50_3d.xml.h"
|
||||
|
||||
struct push_context {
|
||||
struct nouveau_channel *chan;
|
||||
struct nouveau_pushbuf *push;
|
||||
|
||||
void *idxbuf;
|
||||
|
||||
|
|
@ -74,20 +74,20 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
|
|||
|
||||
size = ctx->vertex_words * nr;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->push->cur);
|
||||
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur += size;
|
||||
count -= nr;
|
||||
elts += nr;
|
||||
|
||||
if (nr != push) {
|
||||
count--;
|
||||
elts++;
|
||||
BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (ctx->chan, ctx->restart_index);
|
||||
BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (ctx->push, ctx->restart_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -107,20 +107,20 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
|
|||
|
||||
size = ctx->vertex_words * nr;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->push->cur);
|
||||
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur += size;
|
||||
count -= nr;
|
||||
elts += nr;
|
||||
|
||||
if (nr != push) {
|
||||
count--;
|
||||
elts++;
|
||||
BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (ctx->chan, ctx->restart_index);
|
||||
BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (ctx->push, ctx->restart_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -140,20 +140,20 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
|
|||
|
||||
size = ctx->vertex_words * nr;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->push->cur);
|
||||
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur += size;
|
||||
count -= nr;
|
||||
elts += nr;
|
||||
|
||||
if (nr != push) {
|
||||
count--;
|
||||
elts++;
|
||||
BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (ctx->chan, ctx->restart_index);
|
||||
BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (ctx->push, ctx->restart_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -165,11 +165,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
|
|||
unsigned push = MIN2(count, ctx->packet_vertex_limit);
|
||||
unsigned size = ctx->vertex_words * push;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur);
|
||||
ctx->push->cur += size;
|
||||
count -= push;
|
||||
start += push;
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
|
|||
unsigned inst = info->instance_count;
|
||||
boolean apply_bias = info->indexed && info->index_bias;
|
||||
|
||||
ctx.chan = nv50->screen->base.channel;
|
||||
ctx.push = nv50->base.pushbuf;
|
||||
ctx.translate = nv50->vertex->translate;
|
||||
ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
|
||||
ctx.vertex_words = nv50->vertex->vertex_size;
|
||||
|
|
@ -252,19 +252,19 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
|
|||
ctx.prim = nv50_prim_gl(info->mode);
|
||||
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 2);
|
||||
OUT_RING (ctx.chan, 1);
|
||||
OUT_RING (ctx.chan, info->restart_index);
|
||||
BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 2);
|
||||
PUSH_DATA (ctx.push, 1);
|
||||
PUSH_DATA (ctx.push, info->restart_index);
|
||||
} else
|
||||
if (nv50->state.prim_restart) {
|
||||
BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 1);
|
||||
OUT_RING (ctx.chan, 0);
|
||||
BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 1);
|
||||
PUSH_DATA (ctx.push, 0);
|
||||
}
|
||||
nv50->state.prim_restart = info->primitive_restart;
|
||||
|
||||
while (inst--) {
|
||||
BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (ctx.chan, ctx.prim);
|
||||
BEGIN_NV04(ctx.push, NV50_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (ctx.push, ctx.prim);
|
||||
switch (index_size) {
|
||||
case 0:
|
||||
emit_vertices_seq(&ctx, info->start, info->count);
|
||||
|
|
@ -282,8 +282,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
|
|||
assert(0);
|
||||
break;
|
||||
}
|
||||
BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1);
|
||||
OUT_RING (ctx.chan, 0);
|
||||
BEGIN_NV04(ctx.push, NV50_3D(VERTEX_END_GL), 1);
|
||||
PUSH_DATA (ctx.push, 0);
|
||||
|
||||
ctx.instance_id++;
|
||||
ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
* Authors: Christoph Bumiller
|
||||
*/
|
||||
|
||||
#define NV50_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
|
||||
#include "nv50_context.h"
|
||||
#include "nouveau/nv_object.xml.h"
|
||||
|
||||
|
|
@ -64,7 +66,8 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
|
|||
if (q->ready)
|
||||
nouveau_mm_free(q->mm);
|
||||
else
|
||||
nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm);
|
||||
nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work,
|
||||
q->mm);
|
||||
}
|
||||
}
|
||||
if (size) {
|
||||
|
|
@ -73,14 +76,12 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
|
|||
return FALSE;
|
||||
q->offset = q->base;
|
||||
|
||||
ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD |
|
||||
NOUVEAU_BO_NOSYNC);
|
||||
ret = nouveau_bo_map(q->bo, 0, screen->base.client);
|
||||
if (ret) {
|
||||
nv50_query_allocate(nv50, q, 0);
|
||||
return FALSE;
|
||||
}
|
||||
q->data = q->bo->map;
|
||||
nouveau_bo_unmap(q->bo);
|
||||
q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -121,24 +122,25 @@ nv50_query_create(struct pipe_context *pipe, unsigned type)
|
|||
}
|
||||
|
||||
static void
|
||||
nv50_query_get(struct nouveau_channel *chan, struct nv50_query *q,
|
||||
nv50_query_get(struct nouveau_pushbuf *push, struct nv50_query *q,
|
||||
unsigned offset, uint32_t get)
|
||||
{
|
||||
offset += q->offset;
|
||||
|
||||
MARK_RING (chan, 5, 2);
|
||||
BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, q->sequence);
|
||||
OUT_RING (chan, get);
|
||||
PUSH_SPACE(push, 5);
|
||||
PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
|
||||
BEGIN_NV04(push, NV50_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
PUSH_DATAh(push, q->bo->offset + offset);
|
||||
PUSH_DATA (push, q->bo->offset + offset);
|
||||
PUSH_DATA (push, q->sequence);
|
||||
PUSH_DATA (push, get);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_query *q = nv50_query(pq);
|
||||
|
||||
/* For occlusion queries we have to change the storage, because a previous
|
||||
|
|
@ -161,27 +163,31 @@ nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
|
||||
switch (q->type) {
|
||||
case PIPE_QUERY_OCCLUSION_COUNTER:
|
||||
BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
|
||||
OUT_RING (chan, NV50_3D_COUNTER_RESET_SAMPLECNT);
|
||||
BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
PUSH_SPACE(push, 4);
|
||||
BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
|
||||
PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT);
|
||||
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_GENERATED: /* store before & after instead ? */
|
||||
BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
|
||||
OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
|
||||
PUSH_SPACE(push, 2);
|
||||
BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
|
||||
PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
|
||||
OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
|
||||
PUSH_SPACE(push, 2);
|
||||
BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
|
||||
PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
|
||||
break;
|
||||
case PIPE_QUERY_SO_STATISTICS:
|
||||
BEGIN_RING_NI(chan, RING_3D(COUNTER_RESET), 2);
|
||||
OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
|
||||
OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
|
||||
PUSH_SPACE(push, 3);
|
||||
BEGIN_NI04(push, NV50_3D(COUNTER_RESET), 2);
|
||||
PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
|
||||
PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT:
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
nv50_query_get(chan, q, 0x10, 0x00005002);
|
||||
nv50_query_get(push, q, 0x10, 0x00005002);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -193,31 +199,32 @@ static void
|
|||
nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_query *q = nv50_query(pq);
|
||||
|
||||
switch (q->type) {
|
||||
case PIPE_QUERY_OCCLUSION_COUNTER:
|
||||
nv50_query_get(chan, q, 0, 0x0100f002);
|
||||
BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
nv50_query_get(push, q, 0, 0x0100f002);
|
||||
PUSH_SPACE(push, 2);
|
||||
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_GENERATED:
|
||||
nv50_query_get(chan, q, 0, 0x06805002);
|
||||
nv50_query_get(push, q, 0, 0x06805002);
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
nv50_query_get(chan, q, 0, 0x05805002);
|
||||
nv50_query_get(push, q, 0, 0x05805002);
|
||||
break;
|
||||
case PIPE_QUERY_SO_STATISTICS:
|
||||
nv50_query_get(chan, q, 0x00, 0x05805002);
|
||||
nv50_query_get(chan, q, 0x10, 0x06805002);
|
||||
nv50_query_get(push, q, 0x00, 0x05805002);
|
||||
nv50_query_get(push, q, 0x10, 0x06805002);
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT:
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
nv50_query_get(chan, q, 0, 0x00005002);
|
||||
nv50_query_get(push, q, 0, 0x00005002);
|
||||
break;
|
||||
case PIPE_QUERY_GPU_FINISHED:
|
||||
nv50_query_get(chan, q, 0, 0x1000f010);
|
||||
nv50_query_get(push, q, 0, 0x1000f010);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
@ -231,45 +238,33 @@ nv50_query_ready(struct nv50_query *q)
|
|||
return q->ready || (!q->is64bit && (q->data[0] == q->sequence));
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
nv50_query_wait(struct nv50_query *q)
|
||||
{
|
||||
int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
|
||||
if (ret)
|
||||
return FALSE;
|
||||
nouveau_bo_unmap(q->bo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
||||
boolean wait, union pipe_query_result *result)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nv50_query *q = nv50_query(pq);
|
||||
uint64_t *res64 = (uint64_t*)result;
|
||||
boolean *res8 = (boolean*)result;
|
||||
uint64_t *res64 = (uint64_t *)result;
|
||||
boolean *res8 = (boolean *)result;
|
||||
uint64_t *data64 = (uint64_t *)q->data;
|
||||
|
||||
if (q->type == PIPE_QUERY_GPU_FINISHED) {
|
||||
res8[0] = nv50_query_ready(q);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!q->ready) /* update ? */
|
||||
q->ready = nv50_query_ready(q);
|
||||
if (!q->ready) {
|
||||
struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
|
||||
if (!wait) {
|
||||
if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
|
||||
FIRE_RING(chan);
|
||||
/* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
|
||||
PUSH_KICK(nv50->base.pushbuf);
|
||||
return FALSE;
|
||||
}
|
||||
if (!nv50_query_wait(q))
|
||||
if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
|
||||
return FALSE;
|
||||
}
|
||||
q->ready = TRUE;
|
||||
|
||||
switch (q->type) {
|
||||
case PIPE_QUERY_GPU_FINISHED:
|
||||
res8[0] = TRUE;
|
||||
break;
|
||||
case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */
|
||||
res64[0] = q->data[1];
|
||||
break;
|
||||
|
|
@ -300,27 +295,28 @@ nv50_render_condition(struct pipe_context *pipe,
|
|||
struct pipe_query *pq, uint mode)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_query *q;
|
||||
|
||||
PUSH_SPACE(push, 6);
|
||||
|
||||
if (!pq) {
|
||||
BEGIN_RING(chan, RING_3D(COND_MODE), 1);
|
||||
OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS);
|
||||
BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
|
||||
PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
|
||||
return;
|
||||
}
|
||||
q = nv50_query(pq);
|
||||
|
||||
if (mode == PIPE_RENDER_COND_WAIT ||
|
||||
mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
|
||||
BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
MARK_RING (chan, 4, 2);
|
||||
BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, NV50_3D_COND_MODE_RES_NON_ZERO);
|
||||
BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, q->bo->offset + q->offset);
|
||||
PUSH_DATA (push, q->bo->offset + q->offset);
|
||||
PUSH_DATA (push, NV50_3D_COND_MODE_RES_NON_ZERO);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -4,10 +4,9 @@
|
|||
|
||||
#include "util/u_transfer.h"
|
||||
#include "util/u_double_list.h"
|
||||
#define NOUVEAU_NVC0
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau/nouveau_buffer.h"
|
||||
#undef NOUVEAU_NVC0
|
||||
|
||||
#ifndef __NVC0_RESOURCE_H__ /* make sure we don't use these in nvc0: */
|
||||
|
||||
|
|
@ -19,12 +18,12 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
|
|||
|
||||
|
||||
#define NV50_TILE_SHIFT_X(m) 6
|
||||
#define NV50_TILE_SHIFT_Y(m) ((((m) >> 0) & 0xf) + 2)
|
||||
#define NV50_TILE_SHIFT_Z(m) ((((m) >> 4) & 0xf) + 0)
|
||||
#define NV50_TILE_SHIFT_Y(m) ((((m) >> 4) & 0xf) + 2)
|
||||
#define NV50_TILE_SHIFT_Z(m) ((((m) >> 8) & 0xf) + 0)
|
||||
|
||||
#define NV50_TILE_SIZE_X(m) 64
|
||||
#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 0) & 0xf))
|
||||
#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 4) & 0xf))
|
||||
#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 4) & 0xf))
|
||||
#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 8) & 0xf))
|
||||
|
||||
#define NV50_TILE_SIZE_2D(m) (NV50_TILE_SIZE_X(m) << NV50_TILE_SHIFT_Y(m))
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,6 @@
|
|||
# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
|
||||
#endif
|
||||
|
||||
extern int nouveau_device_get_param(struct nouveau_device *dev,
|
||||
uint64_t param, uint64_t *value);
|
||||
|
||||
static boolean
|
||||
nv50_screen_is_format_supported(struct pipe_screen *pscreen,
|
||||
enum pipe_format format,
|
||||
|
|
@ -53,7 +50,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
|
|||
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
if (nv50_screen(pscreen)->tesla->grclass < NVA0_3D)
|
||||
if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS)
|
||||
return FALSE;
|
||||
break;
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
|
|
@ -100,7 +97,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
return 1;
|
||||
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP:
|
||||
return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D;
|
||||
return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS;
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
|
||||
return 0;
|
||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
||||
|
|
@ -131,7 +128,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
||||
return 1;
|
||||
case PIPE_CAP_INDEP_BLEND_FUNC:
|
||||
return nv50_screen(pscreen)->tesla->grclass >= NVA3_3D;
|
||||
return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS;
|
||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
||||
return 1;
|
||||
|
|
@ -241,8 +238,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
|
|||
nouveau_fence_wait(screen->base.fence.current);
|
||||
nouveau_fence_ref (NULL, &screen->base.fence.current);
|
||||
}
|
||||
if (screen->base.channel)
|
||||
screen->base.channel->user_private = NULL;
|
||||
if (screen->base.pushbuf)
|
||||
screen->base.pushbuf->user_priv = NULL;
|
||||
|
||||
if (screen->blitctx)
|
||||
FREE(screen->blitctx);
|
||||
|
||||
|
|
@ -253,20 +251,17 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
|
|||
nouveau_bo_ref(NULL, &screen->uniforms);
|
||||
nouveau_bo_ref(NULL, &screen->fence.bo);
|
||||
|
||||
nouveau_resource_destroy(&screen->vp_code_heap);
|
||||
nouveau_resource_destroy(&screen->gp_code_heap);
|
||||
nouveau_resource_destroy(&screen->fp_code_heap);
|
||||
nouveau_heap_destroy(&screen->vp_code_heap);
|
||||
nouveau_heap_destroy(&screen->gp_code_heap);
|
||||
nouveau_heap_destroy(&screen->fp_code_heap);
|
||||
|
||||
if (screen->tic.entries)
|
||||
FREE(screen->tic.entries);
|
||||
|
||||
nouveau_mm_destroy(screen->mm_VRAM_fe0);
|
||||
|
||||
nouveau_grobj_free(&screen->tesla);
|
||||
nouveau_grobj_free(&screen->eng2d);
|
||||
nouveau_grobj_free(&screen->m2mf);
|
||||
|
||||
nouveau_notifier_free(&screen->sync);
|
||||
nouveau_object_del(&screen->tesla);
|
||||
nouveau_object_del(&screen->eng2d);
|
||||
nouveau_object_del(&screen->m2mf);
|
||||
nouveau_object_del(&screen->sync);
|
||||
|
||||
nouveau_screen_fini(&screen->base);
|
||||
|
||||
|
|
@ -277,18 +272,16 @@ static void
|
|||
nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_screen(pscreen);
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
|
||||
MARK_RING (chan, 5, 2);
|
||||
struct nouveau_pushbuf *push = screen->base.pushbuf;
|
||||
|
||||
/* we need to do it after possible flush in MARK_RING */
|
||||
*sequence = ++screen->base.fence.sequence;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, *sequence);
|
||||
OUT_RING (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
|
||||
PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4));
|
||||
PUSH_DATAh(push, screen->fence.bo->offset);
|
||||
PUSH_DATA (push, screen->fence.bo->offset);
|
||||
PUSH_DATA (push, *sequence);
|
||||
PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
|
||||
NV50_3D_QUERY_GET_UNK4 |
|
||||
NV50_3D_QUERY_GET_UNIT_CROP |
|
||||
NV50_3D_QUERY_GET_TYPE_QUERY |
|
||||
|
|
@ -299,8 +292,205 @@ nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
|
|||
static u32
|
||||
nv50_screen_fence_update(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_screen(pscreen);
|
||||
return screen->fence.map[0];
|
||||
return nv50_screen(pscreen)->fence.map[0];
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space)
|
||||
{
|
||||
struct nouveau_pushbuf *push = screen->base.pushbuf;
|
||||
struct nv04_fifo *fifo;
|
||||
unsigned i;
|
||||
|
||||
fifo = (struct nv04_fifo *)screen->base.channel->data;
|
||||
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, screen->m2mf->handle);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
|
||||
PUSH_DATA (push, screen->sync->handle);
|
||||
PUSH_DATA (push, fifo->vram);
|
||||
PUSH_DATA (push, fifo->vram);
|
||||
|
||||
BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, screen->eng2d->handle);
|
||||
BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
|
||||
PUSH_DATA (push, screen->sync->handle);
|
||||
PUSH_DATA (push, fifo->vram);
|
||||
PUSH_DATA (push, fifo->vram);
|
||||
PUSH_DATA (push, fifo->vram);
|
||||
BEGIN_NV04(push, NV50_2D(OPERATION), 1);
|
||||
PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
|
||||
BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, SUBC_2D(0x0888), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, screen->tesla->handle);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
|
||||
PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
|
||||
PUSH_DATA (push, screen->sync->handle);
|
||||
BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
|
||||
for (i = 0; i < 11; ++i)
|
||||
PUSH_DATA(push, fifo->vram);
|
||||
BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
|
||||
for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
|
||||
PUSH_DATA(push, fifo->vram);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
|
||||
PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
|
||||
BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
|
||||
PUSH_DATA (push, 0xf);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
|
||||
PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
|
||||
BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
if (screen->tesla->oclass >= NVA0_3D_CLASS) {
|
||||
BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
|
||||
PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
|
||||
}
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
|
||||
PUSH_DATA (push, 0x3f);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
|
||||
PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
|
||||
PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
|
||||
PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
|
||||
PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
|
||||
PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
|
||||
PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->tls_bo->offset);
|
||||
PUSH_DATA (push, screen->tls_bo->offset);
|
||||
PUSH_DATA (push, util_logbase2(tls_space / 8));
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->stack_bo->offset);
|
||||
PUSH_DATA (push, screen->stack_bo->offset);
|
||||
PUSH_DATA (push, 4);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
|
||||
PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
|
||||
PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
|
||||
PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
|
||||
PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
|
||||
PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
|
||||
PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
|
||||
PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
|
||||
PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
|
||||
|
||||
BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6);
|
||||
PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001);
|
||||
PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021);
|
||||
PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031);
|
||||
PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
|
||||
PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
|
||||
PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
|
||||
|
||||
/* max TIC (bits 4:8) & TSC bindings, per program type */
|
||||
for (i = 0; i < 3; ++i) {
|
||||
BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
|
||||
PUSH_DATA (push, 0x54);
|
||||
}
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->txc->offset);
|
||||
PUSH_DATA (push, screen->txc->offset);
|
||||
PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->txc->offset + 65536);
|
||||
PUSH_DATA (push, screen->txc->offset + 65536);
|
||||
PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
|
||||
PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
|
||||
BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
|
||||
for (i = 0; i < 8 * 2; ++i)
|
||||
PUSH_DATA(push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
PUSH_DATAf(push, 1.0f);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
|
||||
#ifdef NV50_SCISSORS_CLIPPING
|
||||
PUSH_DATA (push, 0x0000);
|
||||
#else
|
||||
PUSH_DATA (push, 0x1080);
|
||||
#endif
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
|
||||
PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
|
||||
|
||||
/* We use scissors instead of exact view volume clipping,
|
||||
* so they're always enabled.
|
||||
*/
|
||||
BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 8192 << 16);
|
||||
PUSH_DATA (push, 8192 << 16);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
|
||||
PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
|
||||
BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
|
||||
PUSH_DATA (push, 0x11111111);
|
||||
BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
PUSH_KICK (push);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FAIL_SCREEN_INIT(str, err) \
|
||||
|
|
@ -314,13 +504,12 @@ struct pipe_screen *
|
|||
nv50_screen_create(struct nouveau_device *dev)
|
||||
{
|
||||
struct nv50_screen *screen;
|
||||
struct nouveau_channel *chan;
|
||||
struct pipe_screen *pscreen;
|
||||
struct nouveau_object *chan;
|
||||
uint64_t value;
|
||||
uint32_t tesla_class;
|
||||
unsigned stack_size, max_warps, tls_space;
|
||||
int ret;
|
||||
unsigned i, base;
|
||||
|
||||
screen = CALLOC_STRUCT(nv50_screen);
|
||||
if (!screen)
|
||||
|
|
@ -333,8 +522,10 @@ nv50_screen_create(struct nouveau_device *dev)
|
|||
if (ret)
|
||||
FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret);
|
||||
|
||||
screen->base.pushbuf->user_priv = screen;
|
||||
screen->base.pushbuf->rsvd_kick = 5;
|
||||
|
||||
chan = screen->base.channel;
|
||||
chan->user_private = screen;
|
||||
|
||||
pscreen->destroy = nv50_screen_destroy;
|
||||
pscreen->context_create = nv50_create;
|
||||
|
|
@ -348,68 +539,52 @@ nv50_screen_create(struct nouveau_device *dev)
|
|||
nouveau_screen_init_vdec(&screen->base);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
|
||||
&screen->fence.bo);
|
||||
NULL, &screen->fence.bo);
|
||||
if (ret)
|
||||
goto fail;
|
||||
nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
|
||||
nouveau_bo_map(screen->fence.bo, 0, NULL);
|
||||
screen->fence.map = screen->fence.bo->map;
|
||||
nouveau_bo_unmap(screen->fence.bo);
|
||||
screen->base.fence.emit = nv50_screen_fence_emit;
|
||||
screen->base.fence.update = nv50_screen_fence_update;
|
||||
|
||||
ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
|
||||
ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS,
|
||||
&(struct nv04_notify){ .length = 32 },
|
||||
sizeof(struct nv04_notify), &screen->sync);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret);
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf);
|
||||
|
||||
ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS,
|
||||
NULL, 0, &screen->m2mf);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
|
||||
|
||||
BIND_RING (chan, screen->m2mf, NV50_SUBCH_MF);
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_DMA_NOTIFY), 3);
|
||||
OUT_RING (chan, screen->sync->handle);
|
||||
OUT_RING (chan, chan->vram->handle);
|
||||
OUT_RING (chan, chan->vram->handle);
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
|
||||
ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS,
|
||||
NULL, 0, &screen->eng2d);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
|
||||
|
||||
BIND_RING (chan, screen->eng2d, NV50_SUBCH_2D);
|
||||
BEGIN_RING(chan, RING_2D(DMA_NOTIFY), 4);
|
||||
OUT_RING (chan, screen->sync->handle);
|
||||
OUT_RING (chan, chan->vram->handle);
|
||||
OUT_RING (chan, chan->vram->handle);
|
||||
OUT_RING (chan, chan->vram->handle);
|
||||
BEGIN_RING(chan, RING_2D(OPERATION), 1);
|
||||
OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
|
||||
BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_2D_(0x0888), 1);
|
||||
OUT_RING (chan, 1);
|
||||
|
||||
switch (dev->chipset & 0xf0) {
|
||||
case 0x50:
|
||||
tesla_class = NV50_3D;
|
||||
tesla_class = NV50_3D_CLASS;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
tesla_class = NV84_3D;
|
||||
tesla_class = NV84_3D_CLASS;
|
||||
break;
|
||||
case 0xa0:
|
||||
switch (dev->chipset) {
|
||||
case 0xa0:
|
||||
case 0xaa:
|
||||
case 0xac:
|
||||
tesla_class = NVA0_3D;
|
||||
tesla_class = NVA0_3D_CLASS;
|
||||
break;
|
||||
case 0xaf:
|
||||
tesla_class = NVAF_3D;
|
||||
tesla_class = NVAF_3D_CLASS;
|
||||
break;
|
||||
default:
|
||||
tesla_class = NVA3_3D;
|
||||
tesla_class = NVA3_3D_CLASS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -418,98 +593,33 @@ nv50_screen_create(struct nouveau_device *dev)
|
|||
break;
|
||||
}
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
|
||||
ret = nouveau_object_new(chan, 0xbeef5097, tesla_class,
|
||||
NULL, 0, &screen->tesla);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
|
||||
|
||||
BIND_RING (chan, screen->tesla, NV50_SUBCH_3D);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(COND_MODE), 1);
|
||||
OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(DMA_NOTIFY), 1);
|
||||
OUT_RING (chan, screen->sync->handle);
|
||||
BEGIN_RING(chan, RING_3D(DMA_ZETA), 11);
|
||||
for (i = 0; i < 11; ++i)
|
||||
OUT_RING(chan, chan->vram->handle);
|
||||
BEGIN_RING(chan, RING_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
|
||||
for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
|
||||
OUT_RING(chan, chan->vram->handle);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(REG_MODE), 1);
|
||||
OUT_RING (chan, NV50_3D_REG_MODE_STRIPED);
|
||||
BEGIN_RING(chan, RING_3D(UNK1400_LANES), 1);
|
||||
OUT_RING (chan, 0xf);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
|
||||
OUT_RING (chan, NV50_3D_MULTISAMPLE_MODE_MS1);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1);
|
||||
OUT_RING (chan, 1);
|
||||
|
||||
if (tesla_class >= NVA0_3D) {
|
||||
BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1);
|
||||
OUT_RING (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
|
||||
OUT_RING (chan, 0x3f);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
|
||||
3 << NV50_CODE_BO_SIZE_LOG2, &screen->code);
|
||||
3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
nouveau_resource_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
|
||||
nouveau_resource_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
|
||||
nouveau_resource_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
|
||||
nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
|
||||
nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
|
||||
nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
|
||||
|
||||
base = 1 << NV50_CODE_BO_SIZE_LOG2;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VP_ADDRESS_HIGH), 2);
|
||||
OUT_RELOCh(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(FP_ADDRESS_HIGH), 2);
|
||||
OUT_RELOCh(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(GP_ADDRESS_HIGH), 2);
|
||||
OUT_RELOCh(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
|
||||
nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
|
||||
nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
|
||||
|
||||
max_warps = util_bitcount(value & 0xffff);
|
||||
max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
|
||||
|
||||
stack_size = max_warps * 64 * 8;
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL,
|
||||
&screen->stack_bo);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(STACK_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, 4);
|
||||
|
||||
tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
|
||||
|
||||
screen->tls_size = tls_space * max_warps * 32;
|
||||
|
|
@ -518,126 +628,32 @@ nv50_screen_create(struct nouveau_device *dev)
|
|||
debug_printf("max_warps = %i, tls_size = %"PRIu64" KiB\n",
|
||||
max_warps, screen->tls_size >> 10);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, NULL,
|
||||
&screen->tls_bo);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, util_logbase2(tls_space / 8));
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL,
|
||||
&screen->uniforms);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, (NV50_CB_PVP << 16) | 0x0000);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, (NV50_CB_PGP << 16) | 0x0000);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, (NV50_CB_PFP << 16) | 0x0000);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200);
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(SET_PROGRAM_CB), 6);
|
||||
OUT_RING (chan, (NV50_CB_PVP << 12) | 0x001);
|
||||
OUT_RING (chan, (NV50_CB_PGP << 12) | 0x021);
|
||||
OUT_RING (chan, (NV50_CB_PFP << 12) | 0x031);
|
||||
OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf01);
|
||||
OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf21);
|
||||
OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf31);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL,
|
||||
&screen->txc);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret);
|
||||
|
||||
/* max TIC (bits 4:8) & TSC bindings, per program type */
|
||||
for (i = 0; i < 3; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
|
||||
OUT_RING (chan, 0x54);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, NV50_TIC_MAX_ENTRIES - 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, NV50_TSC_MAX_ENTRIES - 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
|
||||
OUT_RING (chan, 0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
|
||||
OUT_RING (chan, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
|
||||
BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
|
||||
for (i = 0; i < 8 * 2; ++i)
|
||||
OUT_RING(chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
OUT_RINGf (chan, 1.0f);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
|
||||
#ifdef NV50_SCISSORS_CLIPPING
|
||||
OUT_RING (chan, 0x0000);
|
||||
#else
|
||||
OUT_RING (chan, 0x1080);
|
||||
#endif
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
|
||||
OUT_RING (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
|
||||
|
||||
/* We use scissors instead of exact view volume clipping,
|
||||
* so they're always enabled.
|
||||
*/
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 8192 << 16);
|
||||
OUT_RING (chan, 8192 << 16);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
|
||||
OUT_RING (chan, NV50_3D_POINT_RASTER_RULES_OGL);
|
||||
BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
|
||||
OUT_RING (chan, 0x11111111);
|
||||
BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
|
||||
FIRE_RING (chan);
|
||||
|
||||
screen->tic.entries = CALLOC(4096, sizeof(void *));
|
||||
screen->tsc.entries = screen->tic.entries + 2048;
|
||||
|
||||
screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
|
||||
|
||||
if (!nv50_blitctx_create(screen))
|
||||
goto fail;
|
||||
|
||||
if (nv50_screen_init_hwctx(screen, tls_space))
|
||||
goto fail;
|
||||
|
||||
nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
|
||||
|
||||
return pscreen;
|
||||
|
|
@ -647,21 +663,6 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nv50_screen_make_buffers_resident(struct nv50_screen *screen)
|
||||
{
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
|
||||
const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
|
||||
|
||||
MARK_RING(chan, 0, 5);
|
||||
nouveau_bo_validate(chan, screen->code, flags);
|
||||
nouveau_bo_validate(chan, screen->uniforms, flags);
|
||||
nouveau_bo_validate(chan, screen->txc, flags);
|
||||
nouveau_bo_validate(chan, screen->tls_bo, flags);
|
||||
nouveau_bo_validate(chan, screen->stack_bo, flags);
|
||||
}
|
||||
|
||||
int
|
||||
nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#ifndef __NV50_SCREEN_H__
|
||||
#define __NV50_SCREEN_H__
|
||||
|
||||
#define NOUVEAU_NVC0
|
||||
#include "nouveau/nouveau_screen.h"
|
||||
#include "nouveau/nouveau_fence.h"
|
||||
#include "nouveau/nouveau_mm.h"
|
||||
#undef NOUVEAU_NVC0
|
||||
#include "nouveau/nouveau_heap.h"
|
||||
|
||||
#include "nv50_winsys.h"
|
||||
#include "nv50_stateobj.h"
|
||||
|
||||
|
|
@ -36,9 +36,9 @@ struct nv50_screen {
|
|||
|
||||
uint64_t tls_size;
|
||||
|
||||
struct nouveau_resource *vp_code_heap;
|
||||
struct nouveau_resource *gp_code_heap;
|
||||
struct nouveau_resource *fp_code_heap;
|
||||
struct nouveau_heap *vp_code_heap;
|
||||
struct nouveau_heap *gp_code_heap;
|
||||
struct nouveau_heap *fp_code_heap;
|
||||
|
||||
struct nv50_blitctx *blitctx;
|
||||
|
||||
|
|
@ -59,13 +59,11 @@ struct nv50_screen {
|
|||
struct nouveau_bo *bo;
|
||||
} fence;
|
||||
|
||||
struct nouveau_notifier *sync;
|
||||
struct nouveau_object *sync;
|
||||
|
||||
struct nouveau_mman *mm_VRAM_fe0;
|
||||
|
||||
struct nouveau_grobj *tesla;
|
||||
struct nouveau_grobj *eng2d;
|
||||
struct nouveau_grobj *m2mf;
|
||||
struct nouveau_object *tesla;
|
||||
struct nouveau_object *eng2d;
|
||||
struct nouveau_object *m2mf;
|
||||
};
|
||||
|
||||
static INLINE struct nv50_screen *
|
||||
|
|
@ -76,8 +74,6 @@ nv50_screen(struct pipe_screen *screen)
|
|||
|
||||
boolean nv50_blitctx_create(struct nv50_screen *);
|
||||
|
||||
void nv50_screen_make_buffers_resident(struct nv50_screen *);
|
||||
|
||||
int nv50_screen_tic_alloc(struct nv50_screen *, void *);
|
||||
int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
|
||||
|
||||
|
|
@ -88,7 +84,6 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
|
|||
|
||||
if (res->mm) {
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence);
|
||||
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
|
||||
}
|
||||
|
|
@ -97,11 +92,7 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
|
|||
static INLINE void
|
||||
nv50_resource_validate(struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_screen(res->base.screen);
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
void
|
||||
nv50_constbufs_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
unsigned s;
|
||||
|
||||
for (s = 0; s < 3; ++s) {
|
||||
|
|
@ -58,8 +58,8 @@ nv50_constbufs_validate(struct nv50_context *nv50)
|
|||
res = nv04_resource(nv50->constbuf[s][i]);
|
||||
if (!res) {
|
||||
if (i != 0) {
|
||||
BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
|
||||
OUT_RING (chan, (i << 8) | p | 0);
|
||||
BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
|
||||
PUSH_DATA (push, (i << 8) | p | 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -78,43 +78,35 @@ nv50_constbufs_validate(struct nv50_context *nv50)
|
|||
if (!nouveau_resource_mapped_by_gpu(&res->base)) {
|
||||
nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
MARK_RING (chan, 6, 2);
|
||||
BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
OUT_RESRCh(chan, res, 0, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, 0, NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, (b << 16) | (res->base.width0 & 0xffff));
|
||||
BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
|
||||
OUT_RING (chan, (b << 12) | (i << 8) | p | 1);
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, res->address);
|
||||
PUSH_DATA (push, res->address);
|
||||
PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff));
|
||||
BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
|
||||
PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
|
||||
|
||||
bo = res->bo;
|
||||
|
||||
nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res,
|
||||
res->domain | NOUVEAU_BO_RD);
|
||||
}
|
||||
|
||||
if (words) {
|
||||
MARK_RING(chan, 8, 1);
|
||||
|
||||
nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
|
||||
}
|
||||
if (bo != nv50->screen->uniforms)
|
||||
BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
|
||||
|
||||
while (words) {
|
||||
unsigned nr = AVAIL_RING(chan);
|
||||
unsigned nr;
|
||||
|
||||
if (nr < 16) {
|
||||
FIRE_RING(chan);
|
||||
nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
|
||||
continue;
|
||||
}
|
||||
if (!PUSH_SPACE(push, 16))
|
||||
break;
|
||||
nr = PUSH_AVAIL(push);
|
||||
assert(nr >= 16);
|
||||
nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
|
||||
OUT_RING (chan, (start << 8) | b);
|
||||
BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
|
||||
OUT_RINGp (chan, &res->data[start * 4], nr);
|
||||
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
|
||||
PUSH_DATA (push, (start << 8) | b);
|
||||
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
|
||||
PUSH_DATAp(push, &res->data[start * 4], nr);
|
||||
|
||||
start += nr;
|
||||
words -= nr;
|
||||
|
|
@ -126,7 +118,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
|
|||
static boolean
|
||||
nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
|
||||
{
|
||||
struct nouveau_resource *heap;
|
||||
struct nouveau_heap *heap;
|
||||
int ret;
|
||||
unsigned size;
|
||||
|
||||
|
|
@ -135,7 +127,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
|
|||
if (!prog->translated)
|
||||
return FALSE;
|
||||
} else
|
||||
if (prog->res)
|
||||
if (prog->mem)
|
||||
return TRUE;
|
||||
|
||||
if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap;
|
||||
|
|
@ -146,12 +138,12 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
|
|||
|
||||
size = align(prog->code_size, 0x100);
|
||||
|
||||
ret = nouveau_resource_alloc(heap, size, prog, &prog->res);
|
||||
ret = nouveau_heap_alloc(heap, size, prog, &prog->mem);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("out of code space for shader type %i\n", prog->type);
|
||||
return FALSE;
|
||||
}
|
||||
prog->code_base = prog->res->start;
|
||||
prog->code_base = prog->mem->start;
|
||||
|
||||
nv50_relocate_program(prog, prog->code_base, 0);
|
||||
|
||||
|
|
@ -159,80 +151,99 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
|
|||
(prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
|
||||
NOUVEAU_BO_VRAM, prog->code_size, prog->code);
|
||||
|
||||
BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1);
|
||||
OUT_RING (nv50->screen->base.channel, 0);
|
||||
BEGIN_NV04(nv50->base.pushbuf, NV50_3D(CODE_CB_FLUSH), 1);
|
||||
PUSH_DATA (nv50->base.pushbuf, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
nv50_program_update_context_state(struct nv50_context *nv50,
|
||||
struct nv50_program *prog, int stage)
|
||||
{
|
||||
const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
|
||||
|
||||
if (prog && prog->uses_lmem) {
|
||||
if (!nv50->state.tls_required)
|
||||
BCTX_REFN_bo(nv50->bufctx_3d, TLS, flags, nv50->screen->tls_bo);
|
||||
nv50->state.tls_required |= 1 << stage;
|
||||
} else {
|
||||
if (nv50->state.tls_required == (1 << stage))
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TLS);
|
||||
nv50->state.tls_required &= ~(1 << stage);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nv50_vertprog_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_program *vp = nv50->vertprog;
|
||||
|
||||
if (!nv50_program_validate(nv50, vp))
|
||||
return;
|
||||
nv50_program_update_context_state(nv50, vp, 0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VP_ATTR_EN(0)), 2);
|
||||
OUT_RING (chan, vp->vp.attrs[0]);
|
||||
OUT_RING (chan, vp->vp.attrs[1]);
|
||||
BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_RESULT), 1);
|
||||
OUT_RING (chan, vp->max_out);
|
||||
BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_TEMP), 1);
|
||||
OUT_RING (chan, vp->max_gpr);
|
||||
BEGIN_RING(chan, RING_3D(VP_START_ID), 1);
|
||||
OUT_RING (chan, vp->code_base);
|
||||
BEGIN_NV04(push, NV50_3D(VP_ATTR_EN(0)), 2);
|
||||
PUSH_DATA (push, vp->vp.attrs[0]);
|
||||
PUSH_DATA (push, vp->vp.attrs[1]);
|
||||
BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_RESULT), 1);
|
||||
PUSH_DATA (push, vp->max_out);
|
||||
BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_TEMP), 1);
|
||||
PUSH_DATA (push, vp->max_gpr);
|
||||
BEGIN_NV04(push, NV50_3D(VP_START_ID), 1);
|
||||
PUSH_DATA (push, vp->code_base);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_fragprog_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_program *fp = nv50->fragprog;
|
||||
|
||||
if (!nv50_program_validate(nv50, fp))
|
||||
return;
|
||||
nv50_program_update_context_state(nv50, fp, 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(FP_REG_ALLOC_TEMP), 1);
|
||||
OUT_RING (chan, fp->max_gpr);
|
||||
BEGIN_RING(chan, RING_3D(FP_RESULT_COUNT), 1);
|
||||
OUT_RING (chan, fp->max_out);
|
||||
BEGIN_RING(chan, RING_3D(FP_CONTROL), 1);
|
||||
OUT_RING (chan, fp->fp.flags[0]);
|
||||
BEGIN_RING(chan, RING_3D(FP_CTRL_UNK196C), 1);
|
||||
OUT_RING (chan, fp->fp.flags[1]);
|
||||
BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
|
||||
OUT_RING (chan, fp->code_base);
|
||||
BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1);
|
||||
PUSH_DATA (push, fp->max_gpr);
|
||||
BEGIN_NV04(push, NV50_3D(FP_RESULT_COUNT), 1);
|
||||
PUSH_DATA (push, fp->max_out);
|
||||
BEGIN_NV04(push, NV50_3D(FP_CONTROL), 1);
|
||||
PUSH_DATA (push, fp->fp.flags[0]);
|
||||
BEGIN_NV04(push, NV50_3D(FP_CTRL_UNK196C), 1);
|
||||
PUSH_DATA (push, fp->fp.flags[1]);
|
||||
BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
|
||||
PUSH_DATA (push, fp->code_base);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_gmtyprog_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_program *gp = nv50->gmtyprog;
|
||||
|
||||
if (!gp) /* GP_ENABLE is updated in linkage validation */
|
||||
return;
|
||||
if (!nv50_program_validate(nv50, gp))
|
||||
return;
|
||||
if (gp) {
|
||||
BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_TEMP), 1);
|
||||
PUSH_DATA (push, gp->max_gpr);
|
||||
BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_RESULT), 1);
|
||||
PUSH_DATA (push, gp->max_out);
|
||||
BEGIN_NV04(push, NV50_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
|
||||
PUSH_DATA (push, gp->gp.prim_type);
|
||||
BEGIN_NV04(push, NV50_3D(GP_VERTEX_OUTPUT_COUNT), 1);
|
||||
PUSH_DATA (push, gp->gp.vert_count);
|
||||
BEGIN_NV04(push, NV50_3D(GP_START_ID), 1);
|
||||
PUSH_DATA (push, gp->code_base);
|
||||
}
|
||||
nv50_program_update_context_state(nv50, gp, 2);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1);
|
||||
OUT_RING (chan, gp->max_gpr);
|
||||
BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_RESULT), 1);
|
||||
OUT_RING (chan, gp->max_out);
|
||||
BEGIN_RING(chan, RING_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
|
||||
OUT_RING (chan, gp->gp.prim_type);
|
||||
BEGIN_RING(chan, RING_3D(GP_VERTEX_OUTPUT_COUNT), 1);
|
||||
OUT_RING (chan, gp->gp.vert_count);
|
||||
BEGIN_RING(chan, RING_3D(GP_START_ID), 1);
|
||||
OUT_RING (chan, gp->code_base);
|
||||
/* GP_ENABLE is updated in linkage validation */
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_sprite_coords_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
uint32_t pntc[8], mode;
|
||||
struct nv50_program *fp = nv50->fragprog;
|
||||
unsigned i, c;
|
||||
|
|
@ -240,9 +251,9 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
|
|||
|
||||
if (!nv50->rast->pipe.point_quad_rasterization) {
|
||||
if (nv50->state.point_sprite) {
|
||||
BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
|
||||
BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8);
|
||||
for (i = 0; i < 8; ++i)
|
||||
OUT_RING(chan, 0);
|
||||
PUSH_DATA(push, 0);
|
||||
|
||||
nv50->state.point_sprite = FALSE;
|
||||
}
|
||||
|
|
@ -278,43 +289,43 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
|
|||
else
|
||||
mode = 0x10;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_NV04(push, NV50_3D(POINT_SPRITE_CTRL), 1);
|
||||
PUSH_DATA (push, mode);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
|
||||
OUT_RINGp (chan, pntc, 8);
|
||||
BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8);
|
||||
PUSH_DATAp(push, pntc, 8);
|
||||
}
|
||||
|
||||
/* Validate state derived from shaders and the rasterizer cso. */
|
||||
void
|
||||
nv50_validate_derived_rs(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
uint32_t color, psize;
|
||||
|
||||
nv50_sprite_coords_validate(nv50);
|
||||
|
||||
if (nv50->dirty & NV50_NEW_FRAGPROG)
|
||||
return;
|
||||
psize = nv50->state.semantic_psize & ~NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
|
||||
color = nv50->state.semantic_color & ~NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
|
||||
psize = nv50->state.semantic_psize & ~NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK;
|
||||
color = nv50->state.semantic_color & ~NV50_3D_SEMANTIC_COLOR_CLMP_EN;
|
||||
|
||||
if (nv50->rast->pipe.clamp_vertex_color)
|
||||
color |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
|
||||
color |= NV50_3D_SEMANTIC_COLOR_CLMP_EN;
|
||||
|
||||
if (color != nv50->state.semantic_color) {
|
||||
nv50->state.semantic_color = color;
|
||||
BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 1);
|
||||
OUT_RING (chan, color);
|
||||
BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 1);
|
||||
PUSH_DATA (push, color);
|
||||
}
|
||||
|
||||
if (nv50->rast->pipe.point_size_per_vertex)
|
||||
psize |= NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
|
||||
psize |= NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK;
|
||||
|
||||
if (psize != nv50->state.semantic_psize) {
|
||||
nv50->state.semantic_psize = psize;
|
||||
BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_3), 1);
|
||||
OUT_RING (chan, psize);
|
||||
BEGIN_NV04(push, NV50_3D(SEMANTIC_PTSZ), 1);
|
||||
PUSH_DATA (push, psize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -348,7 +359,7 @@ nv50_vec4_map(uint8_t *map, int mid, uint32_t lin[4],
|
|||
void
|
||||
nv50_fp_linkage_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog;
|
||||
struct nv50_program *fp = nv50->fragprog;
|
||||
struct nv50_varying dummy;
|
||||
|
|
@ -409,48 +420,48 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
|
|||
}
|
||||
|
||||
if (nv50->rast->pipe.clamp_vertex_color)
|
||||
colors |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
|
||||
colors |= NV50_3D_SEMANTIC_COLOR_CLMP_EN;
|
||||
|
||||
n = (m + 3) / 4;
|
||||
assert(m <= 64);
|
||||
|
||||
if (unlikely(nv50->gmtyprog)) {
|
||||
BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1);
|
||||
OUT_RING (chan, m);
|
||||
BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n);
|
||||
OUT_RINGp (chan, map, n);
|
||||
BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP_SIZE), 1);
|
||||
PUSH_DATA (push, m);
|
||||
BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP(0)), n);
|
||||
PUSH_DATAp(push, map, n);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
|
||||
OUT_RING (chan, vp->vp.attrs[2]);
|
||||
BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
|
||||
PUSH_DATA (push, vp->vp.attrs[2]);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1);
|
||||
OUT_RING (chan, primid);
|
||||
BEGIN_NV04(push, NV50_3D(SEMANTIC_PRIM_ID), 1);
|
||||
PUSH_DATA (push, primid);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
|
||||
OUT_RING (chan, m);
|
||||
BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
|
||||
OUT_RINGp (chan, map, n);
|
||||
BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
|
||||
PUSH_DATA (push, m);
|
||||
BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
|
||||
PUSH_DATAp(push, map, n);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4);
|
||||
OUT_RING (chan, colors);
|
||||
OUT_RING (chan, (vp->vp.clpd_nr << 8) | 4);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, psiz);
|
||||
BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4);
|
||||
PUSH_DATA (push, colors);
|
||||
PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, psiz);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1);
|
||||
OUT_RING (chan, interp);
|
||||
BEGIN_NV04(push, NV50_3D(FP_INTERPOLANT_CTRL), 1);
|
||||
PUSH_DATA (push, interp);
|
||||
|
||||
nv50->state.interpolant_ctrl = interp;
|
||||
|
||||
nv50->state.semantic_color = colors;
|
||||
nv50->state.semantic_psize = psiz;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
|
||||
OUT_RINGp (chan, lin, 4);
|
||||
BEGIN_NV04(push, NV50_3D(NOPERSPECTIVE_BITMAP(0)), 4);
|
||||
PUSH_DATAp(push, lin, 4);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(GP_ENABLE), 1);
|
||||
OUT_RING (chan, nv50->gmtyprog ? 1 : 0);
|
||||
BEGIN_NV04(push, NV50_3D(GP_ENABLE), 1);
|
||||
PUSH_DATA (push, nv50->gmtyprog ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -486,7 +497,7 @@ nv50_vp_gp_mapping(uint8_t *map, int m,
|
|||
void
|
||||
nv50_gp_linkage_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_program *vp = nv50->vertprog;
|
||||
struct nv50_program *gp = nv50->gmtyprog;
|
||||
int m = 0;
|
||||
|
|
@ -501,11 +512,11 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
|
|||
|
||||
n = (m + 3) / 4;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
|
||||
OUT_RING (chan, vp->vp.attrs[2] | gp->vp.attrs[2]);
|
||||
BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
|
||||
PUSH_DATA (push, vp->vp.attrs[2] | gp->vp.attrs[2]);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
|
||||
OUT_RING (chan, m);
|
||||
BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
|
||||
OUT_RINGp (chan, map, n);
|
||||
BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
|
||||
PUSH_DATA (push, m);
|
||||
BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
|
||||
PUSH_DATAp(push, map, n);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
|
|||
boolean emit_common_func = cso->rt[0].blend_enable;
|
||||
uint32_t ms;
|
||||
|
||||
if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
|
||||
if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
|
||||
SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
|
||||
SB_DATA (so, cso->independent_blend_enable);
|
||||
}
|
||||
|
|
@ -142,7 +142,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
|
|||
emit_common_func = TRUE;
|
||||
}
|
||||
|
||||
if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
|
||||
if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
|
||||
emit_common_func = FALSE;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
|
|
@ -628,7 +628,7 @@ nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
|
|||
|
||||
nv50->num_textures[s] = nr;
|
||||
|
||||
nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
|
||||
|
||||
nv50->dirty |= NV50_NEW_TEXTURES;
|
||||
}
|
||||
|
|
@ -741,13 +741,15 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
|
||||
if (nv50->constbuf[shader][index])
|
||||
nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
|
||||
nv04_resource(nv50->constbuf[shader][index]));
|
||||
|
||||
pipe_resource_reference(&nv50->constbuf[shader][index], res);
|
||||
|
||||
nv50->constbuf_dirty[shader] |= 1 << index;
|
||||
if (res)
|
||||
nv50->constbuf_valid[shader] |= 1 << index;
|
||||
else
|
||||
nv50->constbuf_valid[shader] &= ~(1 << index);
|
||||
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
|
||||
|
||||
nv50->dirty |= NV50_NEW_CONSTBUF;
|
||||
}
|
||||
|
|
@ -802,6 +804,8 @@ nv50_set_framebuffer_state(struct pipe_context *pipe,
|
|||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
|
||||
|
||||
nv50->framebuffer = *fb;
|
||||
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
|
@ -852,7 +856,7 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
|
|||
memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
|
||||
nv50->num_vtxbufs = count;
|
||||
|
||||
nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
|
||||
|
||||
nv50->dirty |= NV50_NEW_ARRAYS;
|
||||
}
|
||||
|
|
@ -863,10 +867,15 @@ nv50_set_index_buffer(struct pipe_context *pipe,
|
|||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
|
||||
if (ib) {
|
||||
pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
|
||||
if (nv50->idxbuf.buffer)
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
|
||||
|
||||
memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
|
||||
if (ib && ib->buffer) {
|
||||
pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
|
||||
nv50->idxbuf.offset = ib->offset;
|
||||
nv50->idxbuf.index_size = ib->index_size;
|
||||
if (nouveau_resource_mapped_by_gpu(ib->buffer))
|
||||
BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD);
|
||||
} else {
|
||||
pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,48 +5,44 @@
|
|||
static void
|
||||
nv50_validate_fb(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
|
||||
unsigned i;
|
||||
unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
|
||||
boolean serialize = FALSE;
|
||||
|
||||
nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs);
|
||||
BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
OUT_RING (chan, fb->width << 16);
|
||||
OUT_RING (chan, fb->height << 16);
|
||||
|
||||
MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
|
||||
BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
|
||||
BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
PUSH_DATA (push, fb->width << 16);
|
||||
PUSH_DATA (push, fb->height << 16);
|
||||
|
||||
for (i = 0; i < fb->nr_cbufs; ++i) {
|
||||
struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
|
||||
struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t offset = sf->offset;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5);
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, nv50_format_table[sf->base.format].rt);
|
||||
if (likely(nouveau_bo_tile_layout(bo))) {
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
|
||||
OUT_RING (chan, mt->layer_stride >> 2);
|
||||
BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
|
||||
OUT_RING (chan, sf->depth);
|
||||
BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
|
||||
if (likely(nouveau_bo_memtype(bo))) {
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
|
||||
PUSH_DATA (push, sf->width);
|
||||
PUSH_DATA (push, sf->height);
|
||||
BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
|
||||
PUSH_DATA (push, sf->depth);
|
||||
} else {
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
|
||||
OUT_RING (chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
|
||||
OUT_RING (chan, sf->height);
|
||||
BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
|
||||
PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
|
||||
PUSH_DATA (push, sf->height);
|
||||
BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
assert(!fb->zsbuf);
|
||||
assert(!mt->ms_mode);
|
||||
|
|
@ -55,13 +51,12 @@ nv50_validate_fb(struct nv50_context *nv50)
|
|||
ms_mode = mt->ms_mode;
|
||||
|
||||
if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
|
||||
serialize = TRUE;
|
||||
nv50->state.rt_serialize = TRUE;
|
||||
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
/* only register for writing, otherwise we'd always serialize here */
|
||||
nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
|
||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
|
||||
}
|
||||
|
||||
if (fb->zsbuf) {
|
||||
|
|
@ -69,87 +64,79 @@ nv50_validate_fb(struct nv50_context *nv50)
|
|||
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
|
||||
uint32_t offset = sf->offset;
|
||||
|
||||
MARK_RING (chan, 12, 2);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, nv50_format_table[fb->zsbuf->format].rt);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
|
||||
OUT_RING (chan, mt->layer_stride >> 2);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, (unk << 16) | sf->depth);
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
|
||||
PUSH_DATA (push, sf->width);
|
||||
PUSH_DATA (push, sf->height);
|
||||
PUSH_DATA (push, (unk << 16) | sf->depth);
|
||||
|
||||
ms_mode = mt->ms_mode;
|
||||
|
||||
if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
|
||||
serialize = TRUE;
|
||||
nv50->state.rt_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_WR);
|
||||
BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
|
||||
OUT_RING (chan, ms_mode);
|
||||
BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
|
||||
PUSH_DATA (push, ms_mode);
|
||||
|
||||
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);
|
||||
}
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, fb->width << 16);
|
||||
PUSH_DATA (push, fb->height << 16);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_blend_colour(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
|
||||
OUT_RINGf (chan, nv50->blend_colour.color[0]);
|
||||
OUT_RINGf (chan, nv50->blend_colour.color[1]);
|
||||
OUT_RINGf (chan, nv50->blend_colour.color[2]);
|
||||
OUT_RINGf (chan, nv50->blend_colour.color[3]);
|
||||
BEGIN_NV04(push, NV50_3D(BLEND_COLOR(0)), 4);
|
||||
PUSH_DATAf(push, nv50->blend_colour.color[0]);
|
||||
PUSH_DATAf(push, nv50->blend_colour.color[1]);
|
||||
PUSH_DATAf(push, nv50->blend_colour.color[2]);
|
||||
PUSH_DATAf(push, nv50->blend_colour.color[3]);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_stencil_ref(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1);
|
||||
OUT_RING (chan, nv50->stencil_ref.ref_value[0]);
|
||||
BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1);
|
||||
OUT_RING (chan, nv50->stencil_ref.ref_value[1]);
|
||||
BEGIN_NV04(push, NV50_3D(STENCIL_FRONT_FUNC_REF), 1);
|
||||
PUSH_DATA (push, nv50->stencil_ref.ref_value[0]);
|
||||
BEGIN_NV04(push, NV50_3D(STENCIL_BACK_FUNC_REF), 1);
|
||||
PUSH_DATA (push, nv50->stencil_ref.ref_value[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_stipple(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
unsigned i;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
|
||||
BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
|
||||
for (i = 0; i < 32; ++i)
|
||||
OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i]));
|
||||
PUSH_DATA(push, util_bswap32(nv50->stipple.stipple[i]));
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_scissor(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct pipe_scissor_state *s = &nv50->scissor;
|
||||
#ifdef NV50_SCISSORS_CLIPPING
|
||||
struct pipe_viewport_state *vp = &nv50->viewport;
|
||||
|
|
@ -178,38 +165,38 @@ nv50_validate_scissor(struct nv50_context *nv50)
|
|||
miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
|
||||
maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (maxx << 16) | minx);
|
||||
OUT_RING (chan, (maxy << 16) | miny);
|
||||
BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (maxx << 16) | minx);
|
||||
PUSH_DATA (push, (maxy << 16) | miny);
|
||||
#else
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (s->maxx << 16) | s->minx);
|
||||
OUT_RING (chan, (s->maxy << 16) | s->miny);
|
||||
BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (s->maxx << 16) | s->minx);
|
||||
PUSH_DATA (push, (s->maxy << 16) | s->miny);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_viewport(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
float zmin, zmax;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
|
||||
OUT_RINGf (chan, nv50->viewport.translate[0]);
|
||||
OUT_RINGf (chan, nv50->viewport.translate[1]);
|
||||
OUT_RINGf (chan, nv50->viewport.translate[2]);
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
|
||||
OUT_RINGf (chan, nv50->viewport.scale[0]);
|
||||
OUT_RINGf (chan, nv50->viewport.scale[1]);
|
||||
OUT_RINGf (chan, nv50->viewport.scale[2]);
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(0)), 3);
|
||||
PUSH_DATAf(push, nv50->viewport.translate[0]);
|
||||
PUSH_DATAf(push, nv50->viewport.translate[1]);
|
||||
PUSH_DATAf(push, nv50->viewport.translate[2]);
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3);
|
||||
PUSH_DATAf(push, nv50->viewport.scale[0]);
|
||||
PUSH_DATAf(push, nv50->viewport.scale[1]);
|
||||
PUSH_DATAf(push, nv50->viewport.scale[2]);
|
||||
|
||||
zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
|
||||
zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
|
||||
|
||||
#ifdef NV50_SCISSORS_CLIPPING
|
||||
BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
OUT_RINGf (chan, zmin);
|
||||
OUT_RINGf (chan, zmax);
|
||||
BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
PUSH_DATAf(push, zmin);
|
||||
PUSH_DATAf(push, zmax);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -234,15 +221,15 @@ nv50_check_program_ucps(struct nv50_context *nv50,
|
|||
static void
|
||||
nv50_validate_clip(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_program *vp;
|
||||
uint8_t clip_enable;
|
||||
|
||||
if (nv50->dirty & NV50_NEW_CLIP) {
|
||||
BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
|
||||
OUT_RING (chan, (0 << 8) | NV50_CB_AUX);
|
||||
BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
|
||||
OUT_RINGp (chan, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
|
||||
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
|
||||
PUSH_DATA (push, (0 << 8) | NV50_CB_AUX);
|
||||
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
|
||||
PUSH_DATAp(push, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
|
||||
}
|
||||
|
||||
vp = nv50->gmtyprog;
|
||||
|
|
@ -251,8 +238,8 @@ nv50_validate_clip(struct nv50_context *nv50)
|
|||
|
||||
clip_enable = nv50->rast->pipe.clip_plane_enable;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
|
||||
OUT_RING (chan, clip_enable);
|
||||
BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_ENABLE), 1);
|
||||
PUSH_DATA (push, clip_enable);
|
||||
|
||||
if (clip_enable)
|
||||
nv50_check_program_ucps(nv50, vp, clip_enable);
|
||||
|
|
@ -261,34 +248,34 @@ nv50_validate_clip(struct nv50_context *nv50)
|
|||
static void
|
||||
nv50_validate_blend(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
WAIT_RING(chan, nv50->blend->size);
|
||||
OUT_RINGp(chan, nv50->blend->state, nv50->blend->size);
|
||||
PUSH_SPACE(push, nv50->blend->size);
|
||||
PUSH_DATAp(push, nv50->blend->state, nv50->blend->size);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_zsa(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
WAIT_RING(chan, nv50->zsa->size);
|
||||
OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size);
|
||||
PUSH_SPACE(push, nv50->zsa->size);
|
||||
PUSH_DATAp(push, nv50->zsa->state, nv50->zsa->size);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_rasterizer(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
WAIT_RING(chan, nv50->rast->size);
|
||||
OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
|
||||
PUSH_SPACE(push, nv50->rast->size);
|
||||
PUSH_DATAp(push, nv50->rast->state, nv50->rast->size);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_validate_sample_mask(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
unsigned mask[4] =
|
||||
{
|
||||
|
|
@ -298,11 +285,11 @@ nv50_validate_sample_mask(struct nv50_context *nv50)
|
|||
nv50->sample_mask & 0xffff
|
||||
};
|
||||
|
||||
BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
|
||||
OUT_RING (chan, mask[0]);
|
||||
OUT_RING (chan, mask[1]);
|
||||
OUT_RING (chan, mask[2]);
|
||||
OUT_RING (chan, mask[3]);
|
||||
BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
|
||||
PUSH_DATA (push, mask[0]);
|
||||
PUSH_DATA (push, mask[1]);
|
||||
PUSH_DATA (push, mask[2]);
|
||||
PUSH_DATA (push, mask[3]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -378,6 +365,7 @@ boolean
|
|||
nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
|
||||
{
|
||||
uint32_t state_mask;
|
||||
int ret;
|
||||
unsigned i;
|
||||
|
||||
if (nv50->screen->cur_ctx != nv50)
|
||||
|
|
@ -393,11 +381,21 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
|
|||
validate->func(nv50);
|
||||
}
|
||||
nv50->dirty &= ~state_mask;
|
||||
|
||||
if (nv50->state.rt_serialize) {
|
||||
nv50->state.rt_serialize = FALSE;
|
||||
BEGIN_NV04(nv50->base.pushbuf, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
|
||||
PUSH_DATA (nv50->base.pushbuf, 0);
|
||||
}
|
||||
|
||||
nv50_bufctx_fence(nv50->bufctx_3d, FALSE);
|
||||
}
|
||||
nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d);
|
||||
ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
|
||||
|
||||
MARK_RING(nv50->screen->base.channel, words, 0);
|
||||
|
||||
nv50_bufctx_emit_relocs(nv50);
|
||||
|
||||
return TRUE;
|
||||
if (unlikely(nv50->state.flushed)) {
|
||||
nv50->state.flushed = FALSE;
|
||||
nv50_bufctx_fence(nv50->bufctx_3d, TRUE);
|
||||
}
|
||||
return !ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,11 @@
|
|||
|
||||
#define NV50_SCISSORS_CLIPPING
|
||||
|
||||
#define SB_BEGIN_3D(so, m, s) \
|
||||
(so)->state[(so)->size++] = \
|
||||
((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m
|
||||
#define SB_BEGIN_3D(so, m, s) \
|
||||
(so)->state[(so)->size++] = NV50_FIFO_PKHDR(NV50_3D(m), s)
|
||||
|
||||
#define SB_BEGIN_3D_(so, m, s) \
|
||||
(so)->state[(so)->size++] = \
|
||||
((s) << 18) | (NV50_SUBCH_3D << 13) | m
|
||||
#define SB_BEGIN_3D_(so, m, s) \
|
||||
(so)->state[(so)->size++] = NV50_FIFO_PKHDR(SUBC_3D(m), s)
|
||||
|
||||
#define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
|
||||
|
||||
|
|
|
|||
|
|
@ -70,14 +70,13 @@ nv50_2d_format(enum pipe_format format)
|
|||
}
|
||||
|
||||
static int
|
||||
nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
|
||||
nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
|
||||
struct nv50_miptree *mt, unsigned level, unsigned layer)
|
||||
{
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t width, height, depth;
|
||||
uint32_t format;
|
||||
uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
|
||||
uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
|
||||
uint32_t offset = mt->level[level].offset;
|
||||
|
||||
format = nv50_2d_format(mt->base.base.format);
|
||||
|
|
@ -99,44 +98,44 @@ nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
|
|||
depth = u_minify(mt->base.base.depth0, level);
|
||||
}
|
||||
|
||||
if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
|
||||
BEGIN_RING(chan, RING_2D_(mthd), 2);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
|
||||
OUT_RING (chan, mt->level[level].pitch);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RELOCh(chan, bo, offset, flags);
|
||||
OUT_RELOCl(chan, bo, offset, flags);
|
||||
if (!nouveau_bo_memtype(bo)) {
|
||||
BEGIN_NV04(push, SUBC_2D(mthd), 2);
|
||||
PUSH_DATA (push, format);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, SUBC_2D(mthd + 0x14), 5);
|
||||
PUSH_DATA (push, mt->level[level].pitch);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_2D_(mthd), 5);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, mt->level[level].tile_mode << 4);
|
||||
OUT_RING (chan, depth);
|
||||
OUT_RING (chan, layer);
|
||||
BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RELOCh(chan, bo, offset, flags);
|
||||
OUT_RELOCl(chan, bo, offset, flags);
|
||||
BEGIN_NV04(push, SUBC_2D(mthd), 5);
|
||||
PUSH_DATA (push, format);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, mt->level[level].tile_mode);
|
||||
PUSH_DATA (push, depth);
|
||||
PUSH_DATA (push, layer);
|
||||
BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (dst) {
|
||||
BEGIN_RING(chan, RING_2D_(NV50_2D_CLIP_X), 4);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
BEGIN_NV04(push, SUBC_2D(NV50_2D_CLIP_X), 4);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_2d_texture_do_copy(struct nouveau_channel *chan,
|
||||
nv50_2d_texture_do_copy(struct nouveau_pushbuf *push,
|
||||
struct nv50_miptree *dst, unsigned dst_level,
|
||||
unsigned dx, unsigned dy, unsigned dz,
|
||||
struct nv50_miptree *src, unsigned src_level,
|
||||
|
|
@ -150,16 +149,16 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan,
|
|||
|
||||
int ret;
|
||||
uint32_t ctrl;
|
||||
|
||||
#if 0
|
||||
ret = MARK_RING(chan, 2 * 16 + 32, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nv50_2d_texture_set(chan, 1, dst, dst_level, dz);
|
||||
#endif
|
||||
ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nv50_2d_texture_set(chan, 0, src, src_level, sz);
|
||||
ret = nv50_2d_texture_set(push, 0, src, src_level, sz);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -168,23 +167,23 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan,
|
|||
ctrl = 0x11;
|
||||
|
||||
/* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */
|
||||
BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
|
||||
OUT_RING (chan, ctrl);
|
||||
BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
|
||||
OUT_RING (chan, dx << dst->ms_x);
|
||||
OUT_RING (chan, dy << dst->ms_y);
|
||||
OUT_RING (chan, w << dst->ms_x);
|
||||
OUT_RING (chan, h << dst->ms_y);
|
||||
BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
|
||||
BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sx << src->ms_x);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sy << src->ms_y);
|
||||
BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
|
||||
PUSH_DATA (push, ctrl);
|
||||
BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
|
||||
PUSH_DATA (push, dx << dst->ms_x);
|
||||
PUSH_DATA (push, dy << dst->ms_y);
|
||||
PUSH_DATA (push, w << dst->ms_x);
|
||||
PUSH_DATA (push, h << dst->ms_y);
|
||||
BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
|
||||
BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, sx << src->ms_x);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, sy << src->ms_y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -196,7 +195,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
|
|||
struct pipe_resource *src, unsigned src_level,
|
||||
const struct pipe_box *src_box)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_context(pipe)->screen;
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
int ret;
|
||||
boolean m2mf;
|
||||
unsigned dst_layer = dstz, src_layer = src_box->z;
|
||||
|
|
@ -227,7 +226,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
|
|||
src_box->x, src_box->y, src_box->z);
|
||||
|
||||
for (i = 0; i < src_box->depth; ++i) {
|
||||
nv50_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
|
||||
nv50_m2mf_transfer_rect(nv50, &drect, &srect, nx, ny);
|
||||
|
||||
if (nv50_miptree(dst)->layout_3d)
|
||||
drect.z++;
|
||||
|
|
@ -246,16 +245,22 @@ nv50_resource_copy_region(struct pipe_context *pipe,
|
|||
(nv50_2d_format_faithful(src->format) &&
|
||||
nv50_2d_format_faithful(dst->format)));
|
||||
|
||||
BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
|
||||
BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
|
||||
nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
|
||||
nouveau_pushbuf_validate(nv50->base.pushbuf);
|
||||
|
||||
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
|
||||
ret = nv50_2d_texture_do_copy(screen->base.channel,
|
||||
ret = nv50_2d_texture_do_copy(nv50->base.pushbuf,
|
||||
nv50_miptree(dst), dst_level,
|
||||
dstx, dsty, dst_layer,
|
||||
nv50_miptree(src), src_level,
|
||||
src_box->x, src_box->y, src_layer,
|
||||
src_box->width, src_box->height);
|
||||
if (ret)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -266,51 +271,50 @@ nv50_clear_render_target(struct pipe_context *pipe,
|
|||
unsigned width, unsigned height)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nv50_screen *screen = nv50->screen;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||
struct nv50_surface *sf = nv50_surface(dst);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
|
||||
OUT_RINGf (chan, color->f[0]);
|
||||
OUT_RINGf (chan, color->f[1]);
|
||||
OUT_RINGf (chan, color->f[2]);
|
||||
OUT_RINGf (chan, color->f[3]);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
|
||||
PUSH_DATAf(push, color->f[0]);
|
||||
PUSH_DATAf(push, color->f[1]);
|
||||
PUSH_DATAf(push, color->f[2]);
|
||||
PUSH_DATAf(push, color->f[3]);
|
||||
#if 0
|
||||
if (MARK_RING(chan, 18, 2))
|
||||
return;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 5);
|
||||
OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, nv50_format_table[dst->format].rt);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2);
|
||||
if (nouveau_bo_tile_layout(bo))
|
||||
OUT_RING(chan, sf->width);
|
||||
#endif
|
||||
BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[dst->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
|
||||
if (nouveau_bo_memtype(bo))
|
||||
PUSH_DATA(push, sf->width);
|
||||
else
|
||||
OUT_RING(chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
|
||||
OUT_RING (chan, sf->height);
|
||||
BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
PUSH_DATA(push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
|
||||
PUSH_DATA (push, sf->height);
|
||||
BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
if (!nouveau_bo_tile_layout(bo)) {
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
if (!nouveau_bo_memtype(bo)) {
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
/* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (width << 16) | dstx);
|
||||
OUT_RING (chan, (height << 16) | dsty);
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (width << 16) | dstx);
|
||||
PUSH_DATA (push, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, 0x3c);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, 0x3c);
|
||||
|
||||
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
|
@ -325,49 +329,48 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
|
|||
unsigned width, unsigned height)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nv50_screen *screen = nv50->screen;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||
struct nv50_surface *sf = nv50_surface(dst);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t mode = 0;
|
||||
|
||||
assert(nouveau_bo_tile_layout(bo)); /* ZETA cannot be linear */
|
||||
assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
|
||||
|
||||
if (clear_flags & PIPE_CLEAR_DEPTH) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
|
||||
OUT_RINGf (chan, depth);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
|
||||
PUSH_DATAf(push, depth);
|
||||
mode |= NV50_3D_CLEAR_BUFFERS_Z;
|
||||
}
|
||||
|
||||
if (clear_flags & PIPE_CLEAR_STENCIL) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
|
||||
OUT_RING (chan, stencil & 0xff);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
|
||||
PUSH_DATA (push, stencil & 0xff);
|
||||
mode |= NV50_3D_CLEAR_BUFFERS_S;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (MARK_RING(chan, 17, 2))
|
||||
return;
|
||||
#endif
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[dst->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
|
||||
PUSH_DATA (push, sf->width);
|
||||
PUSH_DATA (push, sf->height);
|
||||
PUSH_DATA (push, (1 << 16) | 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, nv50_format_table[dst->format].rt);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, (1 << 16) | 1);
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (width << 16) | dstx);
|
||||
PUSH_DATA (push, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (width << 16) | dstx);
|
||||
OUT_RING (chan, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, mode);
|
||||
|
||||
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
|
@ -378,7 +381,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
|
|||
double depth, unsigned stencil)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
|
||||
unsigned i;
|
||||
uint32_t mode = 0;
|
||||
|
|
@ -388,34 +391,34 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
|
|||
return;
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
|
||||
OUT_RINGf (chan, color->f[0]);
|
||||
OUT_RINGf (chan, color->f[1]);
|
||||
OUT_RINGf (chan, color->f[2]);
|
||||
OUT_RINGf (chan, color->f[3]);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
|
||||
PUSH_DATAf(push, color->f[0]);
|
||||
PUSH_DATAf(push, color->f[1]);
|
||||
PUSH_DATAf(push, color->f[2]);
|
||||
PUSH_DATAf(push, color->f[3]);
|
||||
mode =
|
||||
NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G |
|
||||
NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A;
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_DEPTH) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
|
||||
OUT_RING (chan, fui(depth));
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
|
||||
PUSH_DATA (push, fui(depth));
|
||||
mode |= NV50_3D_CLEAR_BUFFERS_Z;
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_STENCIL) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
|
||||
OUT_RING (chan, stencil & 0xff);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
|
||||
PUSH_DATA (push, stencil & 0xff);
|
||||
mode |= NV50_3D_CLEAR_BUFFERS_S;
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, mode);
|
||||
|
||||
for (i = 1; i < fb->nr_cbufs; i++) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, (i << 6) | 0x3c);
|
||||
BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, (i << 6) | 0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,50 +712,50 @@ nv50_blit_set_src(struct nv50_context *nv50,
|
|||
static void
|
||||
nv50_blitctx_prepare_state(struct nv50_blitctx *blit)
|
||||
{
|
||||
struct nouveau_channel *chan = blit->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
|
||||
|
||||
/* blend state */
|
||||
BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1);
|
||||
OUT_RING (chan, blit->color_mask);
|
||||
BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(LOGIC_OP_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(COLOR_MASK(0)), 1);
|
||||
PUSH_DATA (push, blit->color_mask);
|
||||
BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(LOGIC_OP_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
/* rasterizer state */
|
||||
#ifndef NV50_SCISSORS_CLIPPING
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
#endif
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_TWO_SIDE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
|
||||
OUT_RING (chan, 0xffff);
|
||||
OUT_RING (chan, 0xffff);
|
||||
OUT_RING (chan, 0xffff);
|
||||
OUT_RING (chan, 0xffff);
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 3);
|
||||
OUT_RING (chan, NV50_3D_POLYGON_MODE_FRONT_FILL);
|
||||
OUT_RING (chan, NV50_3D_POLYGON_MODE_BACK_FILL);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(CULL_FACE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_TWO_SIDE_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
BEGIN_NV04(push, NV50_3D(POLYGON_MODE_FRONT), 3);
|
||||
PUSH_DATA (push, NV50_3D_POLYGON_MODE_FRONT_FILL);
|
||||
PUSH_DATA (push, NV50_3D_POLYGON_MODE_BACK_FILL);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(CULL_FACE_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
/* zsa state */
|
||||
BEGIN_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(STENCIL_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(DEPTH_TEST_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(STENCIL_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NV50_3D(ALPHA_TEST_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -834,7 +837,7 @@ nv50_resource_resolve(struct pipe_context *pipe,
|
|||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nv50_screen *screen = nv50->screen;
|
||||
struct nv50_blitctx *blit = screen->blitctx;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct pipe_resource *src = info->src.res;
|
||||
struct pipe_resource *dst = info->dst.res;
|
||||
float x0, x1, y0, y1, z;
|
||||
|
|
@ -873,12 +876,12 @@ nv50_resource_resolve(struct pipe_context *pipe,
|
|||
|
||||
z = (float)info->src.layer;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
|
||||
OUT_RING (chan,
|
||||
BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
|
||||
PUSH_DATA (push,
|
||||
blit->fp.code_base + blit->fp_offset);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
/* Draw a large triangle in screen coordinates covering the whole
|
||||
* render target, with scissors defining the destination region.
|
||||
|
|
@ -886,40 +889,40 @@ nv50_resource_resolve(struct pipe_context *pipe,
|
|||
* arranged in a way to yield the desired offset and scale.
|
||||
*/
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (info->dst.x1 << 16) | info->dst.x0);
|
||||
OUT_RING (chan, (info->dst.y1 << 16) | info->dst.y0);
|
||||
BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0);
|
||||
PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
|
||||
OUT_RINGf (chan, x0);
|
||||
OUT_RINGf (chan, y0);
|
||||
OUT_RINGf (chan, z);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
|
||||
OUT_RINGf (chan, x1);
|
||||
OUT_RINGf (chan, y0);
|
||||
OUT_RINGf (chan, z);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
|
||||
OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
|
||||
OUT_RINGf (chan, x0);
|
||||
OUT_RINGf (chan, y1);
|
||||
OUT_RINGf (chan, z);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
|
||||
PUSH_DATAf(push, x0);
|
||||
PUSH_DATAf(push, y0);
|
||||
PUSH_DATAf(push, z);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
|
||||
PUSH_DATAf(push, x1);
|
||||
PUSH_DATAf(push, y0);
|
||||
PUSH_DATAf(push, z);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
|
||||
PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
|
||||
PUSH_DATAf(push, x0);
|
||||
PUSH_DATAf(push, y1);
|
||||
PUSH_DATAf(push, z);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
/* re-enable normally constant state */
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
nv50_blitctx_post_blit(nv50, blit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
|
|||
const struct pipe_sampler_view *templ)
|
||||
{
|
||||
const struct util_format_description *desc;
|
||||
uint64_t addr;
|
||||
uint32_t *tic;
|
||||
uint32_t swz[4];
|
||||
uint32_t depth;
|
||||
|
|
@ -115,15 +116,25 @@ nv50_create_sampler_view(struct pipe_context *pipe,
|
|||
(swz[2] << NV50_TIC_0_MAPB__SHIFT) |
|
||||
(swz[3] << NV50_TIC_0_MAPA__SHIFT);
|
||||
|
||||
tic[1] = /* mt->base.bo->offset; */ 0;
|
||||
tic[2] = /* mt->base.bo->offset >> 32 */ 0;
|
||||
addr = mt->base.address;
|
||||
|
||||
if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY ||
|
||||
mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) {
|
||||
addr += view->pipe.u.tex.first_layer * mt->layer_stride;
|
||||
depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
|
||||
} else {
|
||||
depth = mt->base.base.depth0;
|
||||
}
|
||||
|
||||
tic[1] = addr;
|
||||
tic[2] = (addr >> 32) & 0xff;
|
||||
|
||||
tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
|
||||
|
||||
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
|
||||
tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
|
||||
|
||||
if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
|
||||
if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
|
||||
nv50_init_tic_entry_linear(tic, texture);
|
||||
return &view->pipe;
|
||||
}
|
||||
|
|
@ -132,16 +143,8 @@ nv50_create_sampler_view(struct pipe_context *pipe,
|
|||
tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
|
||||
|
||||
tic[2] |=
|
||||
((mt->base.bo->tile_mode & 0x0f) << (22 - 0)) |
|
||||
((mt->base.bo->tile_mode & 0xf0) << (25 - 4));
|
||||
|
||||
depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
|
||||
|
||||
if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY ||
|
||||
mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) {
|
||||
tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride;
|
||||
depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
|
||||
}
|
||||
((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
|
||||
((mt->level[0].tile_mode & 0xf00) << (25 - 8));
|
||||
|
||||
switch (mt->base.base.target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
|
|
@ -196,7 +199,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
|
|||
static boolean
|
||||
nv50_validate_tic(struct nv50_context *nv50, int s)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nouveau_bo *txc = nv50->screen->txc;
|
||||
unsigned i;
|
||||
boolean need_flush = FALSE;
|
||||
|
|
@ -206,53 +209,46 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
|
|||
struct nv04_resource *res;
|
||||
|
||||
if (!tic) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
|
||||
OUT_RING (chan, (i << 1) | 0);
|
||||
BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
|
||||
PUSH_DATA (push, (i << 1) | 0);
|
||||
continue;
|
||||
}
|
||||
res = &nv50_miptree(tic->pipe.texture)->base;
|
||||
|
||||
if (tic->id < 0) {
|
||||
uint32_t offset = tic->tic[1];
|
||||
|
||||
tic->id = nv50_screen_tic_alloc(nv50->screen, tic);
|
||||
|
||||
MARK_RING (chan, 24 + 8, 4);
|
||||
BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
|
||||
OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
|
||||
OUT_RING (chan, 262144);
|
||||
OUT_RING (chan, 65536);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RELOCh(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
|
||||
OUT_RING (chan, 32);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, tic->id * 32);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), 8);
|
||||
OUT_RING (chan, tic->tic[0]);
|
||||
OUT_RELOCl(chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOC (chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
|
||||
NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
|
||||
OUT_RINGp (chan, &tic->tic[3], 5);
|
||||
BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
|
||||
PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
|
||||
PUSH_DATA (push, 262144);
|
||||
PUSH_DATA (push, 65536);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATAh(push, txc->offset);
|
||||
PUSH_DATA (push, txc->offset);
|
||||
BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
|
||||
PUSH_DATA (push, 32);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, tic->id * 32);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NI04(push, NV50_2D(SIFC_DATA), 8);
|
||||
PUSH_DATAp(push, &tic->tic[0], 8);
|
||||
|
||||
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);
|
||||
BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
|
||||
PUSH_DATA (push, 0x20);
|
||||
}
|
||||
|
||||
nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
|
||||
|
|
@ -260,15 +256,14 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
|
|||
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);
|
||||
BCTX_REFN(nv50->bufctx_3d, TEXTURES, res, RD);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
|
||||
OUT_RING (chan, (tic->id << 9) | (i << 1) | 1);
|
||||
BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
|
||||
PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
|
||||
}
|
||||
for (; i < nv50->state.num_textures[s]; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
|
||||
OUT_RING (chan, (i << 1) | 0);
|
||||
BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
|
||||
PUSH_DATA (push, (i << 1) | 0);
|
||||
}
|
||||
nv50->state.num_textures[s] = nv50->num_textures[s];
|
||||
|
||||
|
|
@ -283,15 +278,15 @@ void nv50_validate_textures(struct nv50_context *nv50)
|
|||
need_flush |= nv50_validate_tic(nv50, 2);
|
||||
|
||||
if (need_flush) {
|
||||
BEGIN_RING(nv50->screen->base.channel, RING_3D(TIC_FLUSH), 1);
|
||||
OUT_RING (nv50->screen->base.channel, 0);
|
||||
BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TIC_FLUSH), 1);
|
||||
PUSH_DATA (nv50->base.pushbuf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv50_validate_tsc(struct nv50_context *nv50, int s)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
unsigned i;
|
||||
boolean need_flush = FALSE;
|
||||
|
||||
|
|
@ -299,8 +294,8 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
|
|||
struct nv50_tsc_entry *tsc = nv50_tsc_entry(nv50->samplers[s][i]);
|
||||
|
||||
if (!tsc) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
|
||||
OUT_RING (chan, (i << 4) | 0);
|
||||
BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 0);
|
||||
continue;
|
||||
}
|
||||
if (tsc->id < 0) {
|
||||
|
|
@ -313,12 +308,12 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
|
|||
}
|
||||
nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
|
||||
OUT_RING (chan, (tsc->id << 12) | (i << 4) | 1);
|
||||
BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
|
||||
PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
|
||||
}
|
||||
for (; i < nv50->state.num_samplers[s]; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
|
||||
OUT_RING (chan, (i << 4) | 0);
|
||||
BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 0);
|
||||
}
|
||||
nv50->state.num_samplers[s] = nv50->num_samplers[s];
|
||||
|
||||
|
|
@ -333,7 +328,7 @@ void nv50_validate_samplers(struct nv50_context *nv50)
|
|||
need_flush |= nv50_validate_tsc(nv50, 2);
|
||||
|
||||
if (need_flush) {
|
||||
BEGIN_RING(nv50->screen->base.channel, RING_3D(TSC_FLUSH), 1);
|
||||
OUT_RING (nv50->screen->base.channel, 0);
|
||||
BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TSC_FLUSH), 1);
|
||||
PUSH_DATA (nv50->base.pushbuf, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,12 +50,13 @@ nv50_m2mf_rect_setup(struct nv50_m2mf_rect *rect,
|
|||
}
|
||||
|
||||
void
|
||||
nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
||||
nv50_m2mf_transfer_rect(struct nv50_context *nv50,
|
||||
const struct nv50_m2mf_rect *dst,
|
||||
const struct nv50_m2mf_rect *src,
|
||||
uint32_t nblocksx, uint32_t nblocksy)
|
||||
{
|
||||
struct nouveau_channel *chan = nouveau_screen(pscreen)->channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nouveau_bufctx *bctx = nv50->bufctx;
|
||||
const int cpp = dst->cpp;
|
||||
uint32_t src_ofst = src->base;
|
||||
uint32_t dst_ofst = dst->base;
|
||||
|
|
@ -65,76 +66,81 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
|||
|
||||
assert(dst->cpp == src->cpp);
|
||||
|
||||
if (nouveau_bo_tile_layout(src->bo)) {
|
||||
BEGIN_RING(chan, RING_MF(LINEAR_IN), 6);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, src->tile_mode << 4);
|
||||
OUT_RING (chan, src->width * cpp);
|
||||
OUT_RING (chan, src->height);
|
||||
OUT_RING (chan, src->depth);
|
||||
OUT_RING (chan, src->z);
|
||||
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
|
||||
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
if (nouveau_bo_memtype(src->bo)) {
|
||||
BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 6);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, src->tile_mode);
|
||||
PUSH_DATA (push, src->width * cpp);
|
||||
PUSH_DATA (push, src->height);
|
||||
PUSH_DATA (push, src->depth);
|
||||
PUSH_DATA (push, src->z);
|
||||
} else {
|
||||
src_ofst += src->y * src->pitch + src->x * cpp;
|
||||
|
||||
BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_IN), 1);
|
||||
OUT_RING (chan, src->pitch);
|
||||
BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_IN), 1);
|
||||
PUSH_DATA (push, src->pitch);
|
||||
}
|
||||
|
||||
if (nouveau_bo_tile_layout(dst->bo)) {
|
||||
BEGIN_RING(chan, RING_MF(LINEAR_OUT), 6);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, dst->tile_mode << 4);
|
||||
OUT_RING (chan, dst->width * cpp);
|
||||
OUT_RING (chan, dst->height);
|
||||
OUT_RING (chan, dst->depth);
|
||||
OUT_RING (chan, dst->z);
|
||||
if (nouveau_bo_memtype(dst->bo)) {
|
||||
BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 6);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, dst->tile_mode);
|
||||
PUSH_DATA (push, dst->width * cpp);
|
||||
PUSH_DATA (push, dst->height);
|
||||
PUSH_DATA (push, dst->depth);
|
||||
PUSH_DATA (push, dst->z);
|
||||
} else {
|
||||
dst_ofst += dst->y * dst->pitch + dst->x * cpp;
|
||||
|
||||
BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_OUT), 1);
|
||||
OUT_RING (chan, dst->pitch);
|
||||
BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_OUT), 1);
|
||||
PUSH_DATA (push, dst->pitch);
|
||||
}
|
||||
|
||||
while (height) {
|
||||
int line_count = height > 2047 ? 2047 : height;
|
||||
|
||||
MARK_RING (chan, 17, 4);
|
||||
BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2);
|
||||
PUSH_DATAh(push, src->bo->offset + src_ofst);
|
||||
PUSH_DATAh(push, dst->bo->offset + dst_ofst);
|
||||
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
|
||||
OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
|
||||
OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2);
|
||||
PUSH_DATA (push, src->bo->offset + src_ofst);
|
||||
PUSH_DATA (push, dst->bo->offset + dst_ofst);
|
||||
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
|
||||
OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
|
||||
|
||||
if (nouveau_bo_tile_layout(src->bo)) {
|
||||
BEGIN_RING(chan, RING_MF(TILING_POSITION_IN), 1);
|
||||
OUT_RING (chan, (sy << 16) | (src->x * cpp));
|
||||
if (nouveau_bo_memtype(src->bo)) {
|
||||
BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_IN), 1);
|
||||
PUSH_DATA (push, (sy << 16) | (src->x * cpp));
|
||||
} else {
|
||||
src_ofst += line_count * src->pitch;
|
||||
}
|
||||
if (nouveau_bo_tile_layout(dst->bo)) {
|
||||
BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT), 1);
|
||||
OUT_RING (chan, (dy << 16) | (dst->x * cpp));
|
||||
if (nouveau_bo_memtype(dst->bo)) {
|
||||
BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_OUT), 1);
|
||||
PUSH_DATA (push, (dy << 16) | (dst->x * cpp));
|
||||
} else {
|
||||
dst_ofst += line_count * dst->pitch;
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
|
||||
OUT_RING (chan, nblocksx * cpp);
|
||||
OUT_RING (chan, line_count);
|
||||
OUT_RING (chan, (1 << 8) | (1 << 0));
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4);
|
||||
PUSH_DATA (push, nblocksx * cpp);
|
||||
PUSH_DATA (push, line_count);
|
||||
PUSH_DATA (push, (1 << 8) | (1 << 0));
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
height -= line_count;
|
||||
sy += line_count;
|
||||
dy += line_count;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -142,55 +148,60 @@ nv50_sifc_linear_u8(struct nouveau_context *nv,
|
|||
struct nouveau_bo *dst, unsigned offset, unsigned domain,
|
||||
unsigned size, const void *data)
|
||||
{
|
||||
struct nouveau_channel *chan = nv->screen->channel;
|
||||
struct nv50_context *nv50 = nv50_context(&nv->pipe);
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
uint32_t *src = (uint32_t *)data;
|
||||
unsigned count = (size + 3) / 4;
|
||||
unsigned xcoord = offset & 0xff;
|
||||
|
||||
nouveau_bufctx_refn(nv50->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
|
||||
nouveau_pushbuf_bufctx(push, nv50->bufctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
offset &= ~0xff;
|
||||
|
||||
MARK_RING (chan, 23, 4);
|
||||
BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
|
||||
OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
|
||||
OUT_RING (chan, 262144);
|
||||
OUT_RING (chan, 65536);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
|
||||
OUT_RING (chan, size);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, xcoord);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
|
||||
PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
|
||||
PUSH_DATA (push, 262144);
|
||||
PUSH_DATA (push, 65536);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATAh(push, dst->offset + offset);
|
||||
PUSH_DATA (push, dst->offset + offset);
|
||||
BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
|
||||
BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
|
||||
PUSH_DATA (push, size);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, xcoord);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
while (count) {
|
||||
unsigned nr = AVAIL_RING(chan);
|
||||
unsigned nr;
|
||||
|
||||
if (nr < 9) {
|
||||
FIRE_RING(chan);
|
||||
nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR);
|
||||
continue;
|
||||
}
|
||||
if (!PUSH_SPACE(push, 16))
|
||||
break;
|
||||
nr = PUSH_AVAIL(push);
|
||||
assert(nr >= 16);
|
||||
nr = MIN2(count, nr - 1);
|
||||
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), nr);
|
||||
OUT_RINGp (chan, src, nr);
|
||||
BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr);
|
||||
PUSH_DATAp(push, src, nr);
|
||||
|
||||
src += nr;
|
||||
count -= nr;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(nv50->bufctx, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -199,33 +210,40 @@ nv50_m2mf_copy_linear(struct nouveau_context *nv,
|
|||
struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
|
||||
unsigned size)
|
||||
{
|
||||
struct nouveau_channel *chan = nv->screen->channel;
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
|
||||
|
||||
BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
|
||||
OUT_RING (chan, 1);
|
||||
nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
|
||||
nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
while (size) {
|
||||
unsigned bytes = MIN2(size, 1 << 17);
|
||||
|
||||
MARK_RING (chan, 11, 4);
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
|
||||
OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
|
||||
OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
|
||||
OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
|
||||
OUT_RING (chan, bytes);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, (1 << 8) | (1 << 0));
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2);
|
||||
PUSH_DATAh(push, src->offset + srcoff);
|
||||
PUSH_DATAh(push, dst->offset + dstoff);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2);
|
||||
PUSH_DATA (push, src->offset + srcoff);
|
||||
PUSH_DATA (push, dst->offset + dstoff);
|
||||
BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4);
|
||||
PUSH_DATA (push, bytes);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, (1 << 8) | (1 << 0));
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
srcoff += bytes;
|
||||
dstoff += bytes;
|
||||
size -= bytes;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
||||
struct pipe_transfer *
|
||||
|
|
@ -236,7 +254,6 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
|
|||
const struct pipe_box *box)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pctx);
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nouveau_device *dev = nv50->screen->base.device;
|
||||
const struct nv50_miptree *mt = nv50_miptree(res);
|
||||
struct nv50_transfer *tx;
|
||||
|
|
@ -272,7 +289,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
|
|||
size = tx->base.layer_stride;
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
|
||||
size * tx->base.box.depth, &tx->rect[1].bo);
|
||||
size * tx->base.box.depth, NULL, &tx->rect[1].bo);
|
||||
if (ret) {
|
||||
FREE(tx);
|
||||
return NULL;
|
||||
|
|
@ -290,7 +307,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
|
|||
unsigned z = tx->rect[0].z;
|
||||
unsigned i;
|
||||
for (i = 0; i < box->depth; ++i) {
|
||||
nv50_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
|
||||
nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0],
|
||||
tx->nblocksx, tx->nblocksy);
|
||||
if (mt->layout_3d)
|
||||
tx->rect[0].z++;
|
||||
|
|
@ -310,14 +327,14 @@ void
|
|||
nv50_miptree_transfer_del(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nv50_context *nv50 = nv50_context(pctx);
|
||||
struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
|
||||
struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
|
||||
unsigned i;
|
||||
|
||||
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
|
||||
for (i = 0; i < tx->base.box.depth; ++i) {
|
||||
nv50_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
|
||||
nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1],
|
||||
tx->nblocksx, tx->nblocksy);
|
||||
if (mt->layout_3d)
|
||||
tx->rect[0].z++;
|
||||
|
|
@ -337,6 +354,7 @@ void *
|
|||
nv50_miptree_transfer_map(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_screen(pctx->screen);
|
||||
struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
|
||||
int ret;
|
||||
unsigned flags = 0;
|
||||
|
|
@ -349,7 +367,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
|
|||
if (transfer->usage & PIPE_TRANSFER_WRITE)
|
||||
flags |= NOUVEAU_BO_WR;
|
||||
|
||||
ret = nouveau_bo_map(tx->rect[1].bo, flags);
|
||||
ret = nouveau_bo_map(tx->rect[1].bo, flags, screen->base.client);
|
||||
if (ret)
|
||||
return NULL;
|
||||
return tx->rect[1].bo->map;
|
||||
|
|
@ -359,9 +377,7 @@ void
|
|||
nv50_miptree_transfer_unmap(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
|
||||
|
||||
nouveau_bo_unmap(tx->rect[1].bo);
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -370,30 +386,36 @@ nv50_cb_push(struct nouveau_context *nv,
|
|||
unsigned base, unsigned size,
|
||||
unsigned offset, unsigned words, const uint32_t *data)
|
||||
{
|
||||
struct nouveau_channel *chan = nv->screen->channel;
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
|
||||
|
||||
assert(!(offset & 3));
|
||||
size = align(size, 0x100);
|
||||
|
||||
nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
while (words) {
|
||||
unsigned nr;
|
||||
|
||||
MARK_RING(chan, 24, 2);
|
||||
nr = AVAIL_RING(chan);
|
||||
nr = PUSH_AVAIL(push);
|
||||
nr = MIN2(nr - 7, words);
|
||||
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, (NV50_CB_TMP << 16) | (size & 0xffff));
|
||||
BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
|
||||
OUT_RING (chan, (offset << 6) | NV50_CB_TMP);
|
||||
BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
|
||||
OUT_RINGp (chan, data, nr);
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, bo->offset + base);
|
||||
PUSH_DATA (push, bo->offset + base);
|
||||
PUSH_DATA (push, (NV50_CB_TMP << 16) | (size & 0xffff));
|
||||
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
|
||||
PUSH_DATA (push, (offset << 6) | NV50_CB_TMP);
|
||||
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
|
||||
PUSH_DATAp(push, data, nr);
|
||||
|
||||
words -= nr;
|
||||
data += nr;
|
||||
offset += nr * 4;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
|
|||
struct pipe_vertex_element *ve, unsigned attr)
|
||||
{
|
||||
const void *data;
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv04_resource *res = nv04_resource(vb->buffer);
|
||||
float v[4];
|
||||
const unsigned nc = util_format_get_nr_components(ve->src_format);
|
||||
|
|
@ -136,30 +136,30 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
|
|||
|
||||
switch (nc) {
|
||||
case 4:
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_4F_X(attr)), 4);
|
||||
OUT_RINGf (chan, v[0]);
|
||||
OUT_RINGf (chan, v[1]);
|
||||
OUT_RINGf (chan, v[2]);
|
||||
OUT_RINGf (chan, v[3]);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_4F_X(attr)), 4);
|
||||
PUSH_DATAf(push, v[0]);
|
||||
PUSH_DATAf(push, v[1]);
|
||||
PUSH_DATAf(push, v[2]);
|
||||
PUSH_DATAf(push, v[3]);
|
||||
break;
|
||||
case 3:
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(attr)), 3);
|
||||
OUT_RINGf (chan, v[0]);
|
||||
OUT_RINGf (chan, v[1]);
|
||||
OUT_RINGf (chan, v[2]);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(attr)), 3);
|
||||
PUSH_DATAf(push, v[0]);
|
||||
PUSH_DATAf(push, v[1]);
|
||||
PUSH_DATAf(push, v[2]);
|
||||
break;
|
||||
case 2:
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(attr)), 2);
|
||||
OUT_RINGf (chan, v[0]);
|
||||
OUT_RINGf (chan, v[1]);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(attr)), 2);
|
||||
PUSH_DATAf(push, v[0]);
|
||||
PUSH_DATAf(push, v[1]);
|
||||
break;
|
||||
case 1:
|
||||
if (attr == nv50->vertprog->vp.edgeflag) {
|
||||
BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
|
||||
OUT_RING (chan, v[0] ? 1 : 0);
|
||||
BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
|
||||
PUSH_DATA (push, v[0] ? 1 : 0);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_1F(attr)), 1);
|
||||
OUT_RINGf (chan, v[0]);
|
||||
BEGIN_NV04(push, NV50_3D(VTX_ATTR_1F(attr)), 1);
|
||||
PUSH_DATAf(push, v[0]);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
@ -193,7 +193,7 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
|
|||
|
||||
nv50->vbo_fifo = nv50->vbo_user = 0;
|
||||
|
||||
nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
|
||||
|
||||
for (i = 0; i < nv50->num_vtxbufs; ++i) {
|
||||
vb = &nv50->vtxbuf[i];
|
||||
|
|
@ -211,33 +211,37 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
|
|||
nv50->vbo_user |= 1 << i;
|
||||
assert(vb->stride > vb->buffer_offset);
|
||||
nv50_vbuf_range(nv50, i, &base, &size);
|
||||
nouveau_user_buffer_upload(buf, base, size);
|
||||
nouveau_user_buffer_upload(&nv50->base, buf, base, size);
|
||||
} else {
|
||||
nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART);
|
||||
}
|
||||
nv50->base.vbo_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
|
||||
BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_update_user_vbufs(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
uint32_t base, offset, size;
|
||||
int i;
|
||||
uint32_t written = 0;
|
||||
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
|
||||
|
||||
for (i = 0; i < nv50->vertex->num_elements; ++i) {
|
||||
struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe;
|
||||
const int b = ve->vertex_buffer_index;
|
||||
struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b];
|
||||
struct nv04_resource *buf = nv04_resource(vb->buffer);
|
||||
|
||||
if (!(nv50->vbo_user & (1 << b)))
|
||||
if (!(nv50->vbo_user & (1 << b))) {
|
||||
BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!vb->stride) {
|
||||
nv50_emit_vtxattr(nv50, vb, ve, i);
|
||||
|
|
@ -247,17 +251,18 @@ nv50_update_user_vbufs(struct nv50_context *nv50)
|
|||
|
||||
if (!(written & (1 << b))) {
|
||||
written |= 1 << b;
|
||||
nouveau_user_buffer_upload(buf, base, size);
|
||||
nouveau_user_buffer_upload(&nv50->base, buf, base, size);
|
||||
}
|
||||
offset = vb->buffer_offset + ve->src_offset;
|
||||
|
||||
MARK_RING (chan, 6, 4);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
|
||||
OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
|
||||
OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
|
||||
PUSH_DATAh(push, buf->address + base + size - 1);
|
||||
PUSH_DATA (push, buf->address + base + size - 1);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
|
||||
PUSH_DATAh(push, buf->address + offset);
|
||||
PUSH_DATA (push, buf->address + offset);
|
||||
|
||||
BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
|
||||
}
|
||||
nv50->base.vbo_dirty = TRUE;
|
||||
}
|
||||
|
|
@ -278,7 +283,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50)
|
|||
void
|
||||
nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_vertex_stateobj *vertex = nv50->vertex;
|
||||
struct pipe_vertex_buffer *vb;
|
||||
struct nv50_vertex_element *ve;
|
||||
|
|
@ -291,15 +296,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
|||
nv50_prevalidate_vbufs(nv50);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
|
||||
for (i = 0; i < vertex->num_elements; ++i) {
|
||||
ve = &vertex->element[i];
|
||||
vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index];
|
||||
|
||||
if (likely(vb->stride) || nv50->vbo_fifo) {
|
||||
OUT_RING(chan, ve->state);
|
||||
PUSH_DATA(push, ve->state);
|
||||
} else {
|
||||
OUT_RING(chan, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
|
||||
PUSH_DATA(push, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
|
||||
nv50->vbo_fifo &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
|
@ -313,15 +318,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
|||
|
||||
if (unlikely(ve->pipe.instance_divisor)) {
|
||||
if (!(nv50->state.instance_elts & (1 << i))) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
|
||||
OUT_RING (chan, ve->pipe.instance_divisor);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
|
||||
PUSH_DATA (push, ve->pipe.instance_divisor);
|
||||
} else
|
||||
if (unlikely(nv50->state.instance_elts & (1 << i))) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
res = nv04_resource(vb->buffer);
|
||||
|
|
@ -329,33 +334,32 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
|||
if (nv50->vbo_fifo || unlikely(vb->stride == 0)) {
|
||||
if (!nv50->vbo_fifo)
|
||||
nv50_emit_vtxattr(nv50, vb, &ve->pipe, i);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
size = vb->buffer->width0;
|
||||
offset = ve->pipe.src_offset + vb->buffer_offset;
|
||||
|
||||
MARK_RING (chan, 8, 4);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
OUT_RING (chan, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
|
||||
OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
|
||||
OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
PUSH_DATA (push, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
|
||||
PUSH_DATAh(push, res->address + size - 1);
|
||||
PUSH_DATA (push, res->address + size - 1);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
|
||||
PUSH_DATAh(push, res->address + offset);
|
||||
PUSH_DATA (push, res->address + offset);
|
||||
}
|
||||
for (; i < nv50->state.num_vtxelts; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
|
||||
OUT_RING (chan, NV50_3D_VERTEX_ATTRIB_INACTIVE);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
|
||||
PUSH_DATA (push, NV50_3D_VERTEX_ATTRIB_INACTIVE);
|
||||
if (unlikely(nv50->state.instance_elts & (1 << i))) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
nv50->state.num_vtxelts = vertex->num_elements;
|
||||
|
|
@ -389,65 +393,55 @@ nv50_prim_gl(unsigned prim)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_draw_vbo_flush_notify(struct nouveau_channel *chan)
|
||||
{
|
||||
struct nv50_screen *screen = chan->user_private;
|
||||
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
|
||||
nv50_bufctx_emit_relocs(screen->cur_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_draw_arrays(struct nv50_context *nv50,
|
||||
unsigned mode, unsigned start, unsigned count,
|
||||
unsigned instance_count)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
unsigned prim;
|
||||
|
||||
if (nv50->state.index_bias) {
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
nv50->state.index_bias = 0;
|
||||
}
|
||||
|
||||
prim = nv50_prim_gl(mode);
|
||||
|
||||
while (instance_count--) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, prim);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2);
|
||||
OUT_RING (chan, start);
|
||||
OUT_RING (chan, count);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, prim);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_BUFFER_FIRST), 2);
|
||||
PUSH_DATA (push, start);
|
||||
PUSH_DATA (push, count);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
|
||||
nv50_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
||||
if (count & 3) {
|
||||
unsigned i;
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3);
|
||||
BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), count & 3);
|
||||
for (i = 0; i < (count & 3); ++i)
|
||||
OUT_RING(chan, *map++);
|
||||
PUSH_DATA(push, *map++);
|
||||
count &= ~3;
|
||||
}
|
||||
while (count) {
|
||||
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr);
|
||||
BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U8), nr);
|
||||
for (i = 0; i < nr; ++i) {
|
||||
OUT_RING(chan,
|
||||
(map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
|
||||
PUSH_DATA(push,
|
||||
(map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
|
||||
map += 4;
|
||||
}
|
||||
count -= nr * 4;
|
||||
|
|
@ -455,22 +449,22 @@ nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
|
|||
}
|
||||
|
||||
static void
|
||||
nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
|
||||
nv50_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
||||
if (count & 1) {
|
||||
count &= ~1;
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (chan, *map++);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (push, *map++);
|
||||
}
|
||||
while (count) {
|
||||
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
|
||||
BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
|
||||
for (i = 0; i < nr; ++i) {
|
||||
OUT_RING(chan, (map[1] << 16) | map[0]);
|
||||
PUSH_DATA(push, (map[1] << 16) | map[0]);
|
||||
map += 2;
|
||||
}
|
||||
count -= nr * 2;
|
||||
|
|
@ -478,7 +472,7 @@ nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
|
|||
}
|
||||
|
||||
static void
|
||||
nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
|
||||
nv50_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
|
@ -486,8 +480,8 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
|
|||
while (count) {
|
||||
const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr);
|
||||
OUT_RINGp (chan, map, nr);
|
||||
BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), nr);
|
||||
PUSH_DATAp(push, map, nr);
|
||||
|
||||
map += nr;
|
||||
count -= nr;
|
||||
|
|
@ -495,22 +489,22 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
|
|||
}
|
||||
|
||||
static void
|
||||
nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
|
||||
nv50_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
||||
if (count & 1) {
|
||||
count--;
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (chan, *map++);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (push, *map++);
|
||||
}
|
||||
while (count) {
|
||||
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
|
||||
BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
|
||||
for (i = 0; i < nr; ++i) {
|
||||
OUT_RING(chan, (map[1] << 16) | map[0]);
|
||||
PUSH_DATA(push, (map[1] << 16) | map[0]);
|
||||
map += 2;
|
||||
}
|
||||
count -= nr * 2;
|
||||
|
|
@ -522,121 +516,116 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
|
|||
unsigned mode, unsigned start, unsigned count,
|
||||
unsigned instance_count, int32_t index_bias)
|
||||
{
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
void *data;
|
||||
struct nv04_resource *buf = nv04_resource(nv50->idxbuf.buffer);
|
||||
unsigned prim;
|
||||
const unsigned index_size = nv50->idxbuf.index_size;
|
||||
|
||||
prim = nv50_prim_gl(mode);
|
||||
|
||||
if (index_bias != nv50->state.index_bias) {
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
|
||||
OUT_RING (chan, index_bias);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
|
||||
PUSH_DATA (push, index_bias);
|
||||
nv50->state.index_bias = index_bias;
|
||||
}
|
||||
|
||||
if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) {
|
||||
struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer);
|
||||
unsigned pb_start;
|
||||
unsigned pb_bytes;
|
||||
const unsigned base = buf->offset;
|
||||
|
||||
start += nv50->idxbuf.offset >> (index_size >> 1);
|
||||
|
||||
while (instance_count--) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, prim);
|
||||
|
||||
nouveau_pushbuf_space(push, 8, 0, 1);
|
||||
|
||||
switch (index_size) {
|
||||
case 4:
|
||||
{
|
||||
WAIT_RING (chan, 2);
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32) | 0x30000, 0);
|
||||
OUT_RING (chan, count);
|
||||
nouveau_pushbuf_submit(chan, res->bo, res->offset + start * 4,
|
||||
count * 4);
|
||||
}
|
||||
BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U32), count);
|
||||
nouveau_pushbuf_data(push, buf->bo, base + start * 4, count * 4);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
unsigned pb_start = (start & ~1);
|
||||
unsigned pb_words = (((start + count + 1) & ~1) - pb_start) >> 1;
|
||||
pb_start = (start & ~1) * 2;
|
||||
pb_bytes = ((start + count + 1) & ~1) * 2 - pb_start;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
|
||||
OUT_RING (chan, (start << 31) | count);
|
||||
WAIT_RING (chan, 2);
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16) | 0x30000, 0);
|
||||
OUT_RING (chan, pb_words);
|
||||
nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start * 2,
|
||||
pb_words * 4);
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
|
||||
PUSH_DATA (push, (start << 31) | count);
|
||||
BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U16), pb_bytes / 4);
|
||||
nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
unsigned pb_start = (start & ~3);
|
||||
unsigned pb_words = (((start + count + 3) & ~3) - pb_start) >> 1;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
|
||||
OUT_RING (chan, (start << 30) | count);
|
||||
WAIT_RING (chan, 2);
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8) | 0x30000, 0);
|
||||
OUT_RING (chan, pb_words);
|
||||
nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start,
|
||||
pb_words * 4);
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
|
||||
OUT_RING (chan, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
assert(index_size == 1);
|
||||
pb_start = start & ~3;
|
||||
pb_bytes = ((start + count + 3) & ~3) - pb_start;
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
|
||||
PUSH_DATA (push, (start << 30) | count);
|
||||
BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U8), pb_bytes / 4);
|
||||
nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
|
||||
BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
break;
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
nv50_resource_fence(res, NOUVEAU_BO_RD);
|
||||
|
||||
mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
} else {
|
||||
data = nouveau_resource_map_offset(&nv50->base,
|
||||
nv04_resource(nv50->idxbuf.buffer),
|
||||
data = nouveau_resource_map_offset(&nv50->base, buf,
|
||||
nv50->idxbuf.offset, NOUVEAU_BO_RD);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
while (instance_count--) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, prim);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, prim);
|
||||
switch (index_size) {
|
||||
case 1:
|
||||
nv50_draw_elements_inline_u08(chan, data, start, count);
|
||||
nv50_draw_elements_inline_u08(push, data, start, count);
|
||||
break;
|
||||
case 2:
|
||||
nv50_draw_elements_inline_u16(chan, data, start, count);
|
||||
nv50_draw_elements_inline_u16(push, data, start, count);
|
||||
break;
|
||||
case 4:
|
||||
if (shorten)
|
||||
nv50_draw_elements_inline_u32_short(chan, data, start, count);
|
||||
nv50_draw_elements_inline_u32_short(push, data, start, count);
|
||||
else
|
||||
nv50_draw_elements_inline_u32(chan, data, start, count);
|
||||
nv50_draw_elements_inline_u32(push, data, start, count);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
|
||||
{
|
||||
struct nv50_screen *screen = chan->user_priv;
|
||||
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
|
||||
nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nouveau_channel *chan = nv50->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
|
||||
/* For picking only a few vertices from a large user buffer, push is better,
|
||||
* if index count is larger and we expect repeated vertices, suggest upload.
|
||||
|
|
@ -656,24 +645,25 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
|
||||
nv50_state_validate(nv50, ~0, 8); /* 8 as minimum, we use flush_notify */
|
||||
|
||||
chan->flush_notify = nv50_draw_vbo_flush_notify;
|
||||
push->kick_notify = nv50_draw_vbo_kick_notify;
|
||||
|
||||
if (nv50->vbo_fifo) {
|
||||
nv50_push_vbo(nv50, info);
|
||||
chan->flush_notify = nv50_default_flush_notify;
|
||||
push->kick_notify = nv50_default_kick_notify;
|
||||
nouveau_pushbuf_bufctx(push, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nv50->state.instance_base != info->start_instance) {
|
||||
nv50->state.instance_base = info->start_instance;
|
||||
/* NOTE: this does not affect the shader input, should it ? */
|
||||
BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1);
|
||||
OUT_RING (chan, info->start_instance);
|
||||
BEGIN_NV04(push, NV50_3D(VB_INSTANCE_BASE), 1);
|
||||
PUSH_DATA (push, info->start_instance);
|
||||
}
|
||||
|
||||
if (nv50->base.vbo_dirty) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
nv50->base.vbo_dirty = FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -688,21 +678,21 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
|
||||
if (info->primitive_restart != nv50->state.prim_restart) {
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, info->restart_index);
|
||||
BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 2);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, info->restart_index);
|
||||
|
||||
if (info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
nv50->state.prim_restart = info->primitive_restart;
|
||||
} else
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1);
|
||||
OUT_RING (chan, info->restart_index);
|
||||
BEGIN_NV04(push, NV50_3D(PRIM_RESTART_INDEX), 1);
|
||||
PUSH_DATA (push, info->restart_index);
|
||||
|
||||
if (info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
|
|
@ -712,7 +702,9 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
info->mode, info->start, info->count,
|
||||
info->instance_count, info->index_bias);
|
||||
}
|
||||
chan->flush_notify = nv50_default_flush_notify;
|
||||
push->kick_notify = nv50_default_kick_notify;
|
||||
|
||||
nv50_release_user_vbufs(nv50);
|
||||
|
||||
nouveau_pushbuf_bufctx(push, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,100 +7,118 @@
|
|||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "nouveau/nouveau_bo.h"
|
||||
#include "nouveau/nouveau_channel.h"
|
||||
#include "nouveau/nouveau_grobj.h"
|
||||
#include "nouveau/nouveau_device.h"
|
||||
#include "nouveau/nouveau_resource.h"
|
||||
#include "nouveau/nouveau_pushbuf.h"
|
||||
#include "nouveau/nouveau_reloc.h"
|
||||
#include "nouveau/nouveau_notifier.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau/nouveau_buffer.h"
|
||||
|
||||
|
||||
#ifndef NV04_PFIFO_MAX_PACKET_LEN
|
||||
#define NV04_PFIFO_MAX_PACKET_LEN 2047
|
||||
#endif
|
||||
|
||||
#define NV50_SUBCH_3D 5
|
||||
#define NV50_SUBCH_2D 6
|
||||
#define NV50_SUBCH_MF 7
|
||||
|
||||
#define NV50_MF_(n) NV50_M2MF_##n
|
||||
|
||||
#define RING_3D(n) ((NV50_SUBCH_3D << 13) | NV50_3D_##n)
|
||||
#define RING_2D(n) ((NV50_SUBCH_2D << 13) | NV50_2D_##n)
|
||||
#define RING_MF(n) ((NV50_SUBCH_MF << 13) | NV50_MF_(n))
|
||||
|
||||
#define RING_3D_(m) ((NV50_SUBCH_3D << 13) | (m))
|
||||
#define RING_2D_(m) ((NV50_SUBCH_2D << 13) | (m))
|
||||
#define RING_MF_(m) ((NV50_SUBCH_MF << 13) | (m))
|
||||
|
||||
#define RING_GR(gr, m) (((gr)->subc << 13) | (m))
|
||||
|
||||
int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
|
||||
|
||||
static inline uint32_t
|
||||
nouveau_bo_tile_layout(const struct nouveau_bo *bo)
|
||||
static INLINE void
|
||||
nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin,
|
||||
unsigned flags, struct nouveau_bo *bo)
|
||||
{
|
||||
return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
|
||||
nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
nouveau_bo_validate(struct nouveau_channel *chan,
|
||||
struct nouveau_bo *bo, unsigned flags)
|
||||
nv50_add_bufctx_resident(struct nouveau_bufctx *bufctx, int bin,
|
||||
struct nv04_resource *res, unsigned flags)
|
||||
{
|
||||
nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
|
||||
struct nouveau_bufref *ref =
|
||||
nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain);
|
||||
ref->priv = res;
|
||||
ref->priv_data = flags;
|
||||
}
|
||||
|
||||
/* incremental methods */
|
||||
#define BCTX_REFN_bo(ctx, bin, fl, bo) \
|
||||
nv50_add_bufctx_resident_bo(ctx, NV50_BIND_##bin, fl, bo);
|
||||
|
||||
#define BCTX_REFN(bctx, bin, res, acc) \
|
||||
nv50_add_bufctx_resident(bctx, NV50_BIND_##bin, res, NOUVEAU_BO_##acc)
|
||||
|
||||
static INLINE void
|
||||
BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
|
||||
PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
|
||||
{
|
||||
WAIT_RING(chan, size + 1);
|
||||
OUT_RING (chan, (size << 18) | mthd);
|
||||
struct nouveau_pushbuf_refn ref = { bo, flags };
|
||||
nouveau_pushbuf_refn(push, &ref, 1);
|
||||
}
|
||||
|
||||
/* non-incremental */
|
||||
|
||||
#define SUBC_3D(m) 3, (m)
|
||||
#define NV50_3D(n) SUBC_3D(NV50_3D_##n)
|
||||
|
||||
#define SUBC_2D(m) 4, (m)
|
||||
#define NV50_2D(n) SUBC_2D(NV50_2D_##n)
|
||||
|
||||
#define SUBC_M2MF(m) 5, (m)
|
||||
#define NV50_M2MF(n) SUBC_M2MF(NV50_M2MF_##n)
|
||||
|
||||
#define SUBC_COMPUTE(m) 6, (m)
|
||||
#define NV50_COMPUTE(n) SUBC_COMPUTE(NV50_COMPUTE_##n)
|
||||
|
||||
|
||||
static INLINE uint32_t
|
||||
NV50_FIFO_PKHDR(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0x00000000 | (size << 18) | (subc << 13) | mthd;
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
NV50_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0x40000000 | (size << 18) | (subc << 13) | mthd;
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
NV50_FIFO_PKHDR_L(int subc, int mthd)
|
||||
{
|
||||
return 0x00030000 | (subc << 13) | mthd;
|
||||
}
|
||||
|
||||
|
||||
static INLINE uint32_t
|
||||
nouveau_bo_memtype(const struct nouveau_bo *bo)
|
||||
{
|
||||
return bo->config.nv50.memtype;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
|
||||
PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data)
|
||||
{
|
||||
WAIT_RING(chan, size + 1);
|
||||
OUT_RING (chan, (0x2 << 29) | (size << 18) | mthd);
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
|
||||
unsigned delta, unsigned flags)
|
||||
{
|
||||
return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
|
||||
unsigned delta, unsigned flags)
|
||||
{
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
|
||||
*push->cur++ = (uint32_t)(data >> 32);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
|
||||
BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
struct nouveau_subchannel *subc = &gr->channel->subc[s];
|
||||
|
||||
assert(s < 8);
|
||||
if (subc->gr) {
|
||||
assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT);
|
||||
subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
|
||||
}
|
||||
subc->gr = gr;
|
||||
subc->gr->subc = s;
|
||||
subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
|
||||
|
||||
BEGIN_RING(chan, RING_GR(gr, 0x0000), 1);
|
||||
OUT_RING (chan, gr->handle);
|
||||
}
|
||||
|
||||
#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, size + 1);
|
||||
#endif
|
||||
PUSH_DATA (push, NV50_FIFO_PKHDR(subc, mthd, size));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, size + 1);
|
||||
#endif
|
||||
PUSH_DATA (push, NV50_FIFO_PKHDR_NI(subc, mthd, size));
|
||||
}
|
||||
|
||||
/* long, non-incremental, nv50-only */
|
||||
static INLINE void
|
||||
BEGIN_NL50(struct nouveau_pushbuf *push, int subc, int mthd, uint32_t size)
|
||||
{
|
||||
#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, 2);
|
||||
#endif
|
||||
PUSH_DATA (push, NV50_FIFO_PKHDR_L(subc, mthd));
|
||||
PUSH_DATA (push, size);
|
||||
}
|
||||
|
||||
#endif /* __NV50_WINSYS_H__ */
|
||||
|
|
|
|||
|
|
@ -153,13 +153,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NVC0_3D_LOCAL_BASE 0x0000077c
|
||||
|
||||
#define NVC0_3D_LOCAL_ADDRESS_HIGH 0x00000790
|
||||
#define NVC0_3D_TEMP_ADDRESS_HIGH 0x00000790
|
||||
|
||||
#define NVC0_3D_LOCAL_ADDRESS_LOW 0x00000794
|
||||
#define NVC0_3D_TEMP_ADDRESS_LOW 0x00000794
|
||||
|
||||
#define NVC0_3D_LOCAL_SIZE_HIGH 0x00000798
|
||||
#define NVC0_3D_TEMP_SIZE_HIGH 0x00000798
|
||||
|
||||
#define NVC0_3D_LOCAL_SIZE_LOW 0x0000079c
|
||||
#define NVC0_3D_TEMP_SIZE_LOW 0x0000079c
|
||||
|
||||
#define NVC0_3D_WARP_TEMP_ALLOC 0x000007a0
|
||||
|
||||
#define NVC0_3D_ZCULL_WIDTH 0x000007c0
|
||||
|
||||
#define NVC0_3D_ZCULL_HEIGHT 0x000007c4
|
||||
|
||||
#define NVC0_3D_ZCULL_ADDRESS_HIGH 0x000007e8
|
||||
|
||||
#define NVC0_3D_ZCULL_ADDRESS_LOW 0x000007ec
|
||||
|
||||
#define NVC0_3D_ZCULL_LIMIT_HIGH 0x000007f0
|
||||
|
||||
#define NVC0_3D_ZCULL_LIMIT_LOW 0x000007f4
|
||||
|
||||
#define NVC0_3D_RT(i0) (0x00000800 + 0x40*(i0))
|
||||
#define NVC0_3D_RT__ESIZE 0x00000040
|
||||
|
|
@ -772,6 +786,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NVC0_3D_TIC_LIMIT 0x0000157c
|
||||
|
||||
#define NVC0_3D_ZCULL_REGION 0x00001590
|
||||
|
||||
#define NVC0_3D_STENCIL_TWO_SIDE_ENABLE 0x00001594
|
||||
|
||||
#define NVC0_3D_STENCIL_BACK_OP_FAIL 0x00001598
|
||||
|
|
@ -856,7 +872,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NVC0_3D_VERTEX_END_D3D_UNK0 0x00000001
|
||||
#define NVC0_3D_VERTEX_END_D3D_UNK1 0x00000002
|
||||
|
||||
#define NVC0_3D_EDGEFLAG_ENABLE 0x000015e4
|
||||
#define NVC0_3D_EDGEFLAG 0x000015e4
|
||||
|
||||
#define NVC0_3D_VB_ELEMENT_U32 0x000015e8
|
||||
|
||||
|
|
@ -876,6 +892,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NVC0_3D_VERTEX_BASE_LOW 0x000015f8
|
||||
|
||||
#define NVC0_3D_ZCULL_WINDOW_OFFSET_X 0x000015fc
|
||||
|
||||
#define NVC0_3D_ZCULL_WINDOW_OFFSET_Y 0x00001600
|
||||
|
||||
#define NVC0_3D_POINT_COORD_REPLACE 0x00001604
|
||||
#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__MASK 0x00000004
|
||||
#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__SHIFT 2
|
||||
|
|
@ -1070,6 +1090,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NVC0_3D_CLIP_RECTS_MODE_OUTSIDE_ALL 0x00000001
|
||||
#define NVC0_3D_CLIP_RECTS_MODE_NEVER 0x00000002
|
||||
|
||||
#define NVC0_3D_ZCULL_INVALIDATE 0x00001958
|
||||
|
||||
#define NVC0_3D_ZCULL_TEST_MASK 0x0000196c
|
||||
#define NVC0_3D_ZCULL_TEST_MASK_FAIL_GT_PASS_LT 0x00000001
|
||||
#define NVC0_3D_ZCULL_TEST_MASK_PASS_GT_FAIL_LT 0x00000010
|
||||
|
||||
#define NVC0_3D_FP_ZORDER_CTRL 0x0000196c
|
||||
#define NVC0_3D_FP_ZORDER_CTRL_0 0x00000001
|
||||
#define NVC0_3D_FP_ZORDER_CTRL_1 0x00000010
|
||||
|
|
@ -1082,11 +1108,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define NVC0_3D_CLIPID_ID 0x00001984
|
||||
|
||||
#define NVC0_3D_FP_CONTROL 0x000019a8
|
||||
#define NVC0_3D_FP_CONTROL_MULTIPLE_RESULTS 0x00000001
|
||||
#define NVC0_3D_FP_CONTROL_EXPORTS_Z 0x00000100
|
||||
#define NVC0_3D_FP_CONTROL_USES_KIL 0x00100000
|
||||
|
||||
#define NVC0_3D_DEPTH_BOUNDS_EN 0x000019bc
|
||||
|
||||
#define NVC0_3D_LOGIC_OP_ENABLE 0x000019c4
|
||||
|
|
|
|||
|
|
@ -33,26 +33,22 @@ static void
|
|||
nvc0_flush(struct pipe_context *pipe,
|
||||
struct pipe_fence_handle **fence)
|
||||
{
|
||||
struct nouveau_screen *screen = &nvc0_context(pipe)->screen->base;
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_screen *screen = &nvc0->screen->base;
|
||||
|
||||
if (fence)
|
||||
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
|
||||
|
||||
/* Try to emit before firing to avoid having to flush again right after
|
||||
* in case we have to wait on this fence.
|
||||
*/
|
||||
nouveau_fence_emit(screen->fence.current);
|
||||
|
||||
FIRE_RING(screen->channel);
|
||||
PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_texture_barrier(struct pipe_context *pipe)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf;
|
||||
|
||||
IMMED_RING(chan, RING_3D(SERIALIZE), 0);
|
||||
IMMED_RING(chan, RING_3D(TEX_CACHE_CTL), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -60,8 +56,8 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0)
|
|||
{
|
||||
unsigned s, i;
|
||||
|
||||
for (i = 0; i < NVC0_BUFCTX_COUNT; ++i)
|
||||
nvc0_bufctx_reset(nvc0, i);
|
||||
nouveau_bufctx_del(&nvc0->bufctx_3d);
|
||||
nouveau_bufctx_del(&nvc0->bufctx);
|
||||
|
||||
for (i = 0; i < nvc0->num_vtxbufs; ++i)
|
||||
pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
|
||||
|
|
@ -85,26 +81,31 @@ nvc0_destroy(struct pipe_context *pipe)
|
|||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
|
||||
if (nvc0->screen->cur_ctx == nvc0) {
|
||||
nvc0->base.pushbuf->kick_notify = NULL;
|
||||
nvc0->screen->cur_ctx = NULL;
|
||||
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
|
||||
}
|
||||
nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);
|
||||
|
||||
nvc0_context_unreference_resources(nvc0);
|
||||
|
||||
draw_destroy(nvc0->draw);
|
||||
|
||||
if (nvc0->screen->cur_ctx == nvc0)
|
||||
nvc0->screen->cur_ctx = NULL;
|
||||
|
||||
FREE(nvc0);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_default_flush_notify(struct nouveau_channel *chan)
|
||||
nvc0_default_kick_notify(struct nouveau_pushbuf *push)
|
||||
{
|
||||
struct nvc0_screen *screen = chan->user_private;
|
||||
struct nvc0_screen *screen = push->user_priv;
|
||||
|
||||
if (!screen)
|
||||
return;
|
||||
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
nouveau_fence_next(&screen->base);
|
||||
if (screen) {
|
||||
nouveau_fence_next(&screen->base);
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
if (screen->cur_ctx)
|
||||
screen->cur_ctx->state.flushed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
|
|
@ -113,12 +114,23 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
|
|||
struct nvc0_screen *screen = nvc0_screen(pscreen);
|
||||
struct nvc0_context *nvc0;
|
||||
struct pipe_context *pipe;
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
|
||||
nvc0 = CALLOC_STRUCT(nvc0_context);
|
||||
if (!nvc0)
|
||||
return NULL;
|
||||
pipe = &nvc0->base.pipe;
|
||||
|
||||
nvc0->base.pushbuf = screen->base.pushbuf;
|
||||
|
||||
ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT,
|
||||
&nvc0->bufctx_3d);
|
||||
if (!ret)
|
||||
nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
nvc0->screen = screen;
|
||||
nvc0->base.screen = &screen->base;
|
||||
nvc0->base.copy_data = nvc0_m2mf_copy_linear;
|
||||
|
|
@ -136,9 +148,11 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
|
|||
pipe->flush = nvc0_flush;
|
||||
pipe->texture_barrier = nvc0_texture_barrier;
|
||||
|
||||
if (!screen->cur_ctx)
|
||||
if (!screen->cur_ctx) {
|
||||
screen->cur_ctx = nvc0;
|
||||
screen->base.channel->flush_notify = nvc0_default_flush_notify;
|
||||
nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
|
||||
}
|
||||
screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;
|
||||
|
||||
nvc0_init_query_functions(nvc0);
|
||||
nvc0_init_surface_functions(nvc0);
|
||||
|
|
@ -154,72 +168,43 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
|
|||
/* shader builtin library is per-screen, but we need a context for m2mf */
|
||||
nvc0_program_library_upload(nvc0);
|
||||
|
||||
/* add permanently resident buffers to bufctxts */
|
||||
|
||||
flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
|
||||
|
||||
BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
|
||||
BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniforms);
|
||||
BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);
|
||||
|
||||
flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
|
||||
|
||||
BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
|
||||
BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
struct resident {
|
||||
struct nv04_resource *res;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
void
|
||||
nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx,
|
||||
struct nv04_resource *resource, uint32_t flags)
|
||||
{
|
||||
struct resident rsd = { resource, flags };
|
||||
|
||||
if (!resource->bo)
|
||||
return;
|
||||
nvc0->residents_size += sizeof(struct resident);
|
||||
|
||||
/* We don't need to reference the resource here, it will be referenced
|
||||
* in the context/state, and bufctx will be reset when state changes.
|
||||
*/
|
||||
util_dynarray_append(&nvc0->residents[ctx], struct resident, rsd);
|
||||
out_err:
|
||||
if (nvc0) {
|
||||
if (nvc0->bufctx_3d)
|
||||
nouveau_bufctx_del(&nvc0->bufctx_3d);
|
||||
if (nvc0->bufctx)
|
||||
nouveau_bufctx_del(&nvc0->bufctx);
|
||||
FREE(nvc0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx,
|
||||
struct nv04_resource *resource)
|
||||
nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
|
||||
boolean on_flush)
|
||||
{
|
||||
struct resident *rsd, *top;
|
||||
unsigned i;
|
||||
struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
|
||||
struct nouveau_list *it;
|
||||
|
||||
for (i = 0; i < nvc0->residents[ctx].size / sizeof(struct resident); ++i) {
|
||||
rsd = util_dynarray_element(&nvc0->residents[ctx], struct resident, i);
|
||||
|
||||
if (rsd->res == resource) {
|
||||
top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident);
|
||||
if (rsd != top)
|
||||
*rsd = *top;
|
||||
nvc0->residents_size -= sizeof(struct resident);
|
||||
break;
|
||||
}
|
||||
for (it = list->next; it != list; it = it->next) {
|
||||
struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
|
||||
struct nv04_resource *res = ref->priv;
|
||||
if (res)
|
||||
nvc0_resource_validate(res, (unsigned)ref->priv_data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct resident *rsd;
|
||||
struct util_dynarray *array;
|
||||
unsigned ctx, i, n;
|
||||
|
||||
n = nvc0->residents_size / sizeof(struct resident);
|
||||
n += NVC0_SCREEN_RESIDENT_BO_COUNT;
|
||||
|
||||
MARK_RING(nvc0->screen->base.channel, 0, n);
|
||||
|
||||
for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) {
|
||||
array = &nvc0->residents[ctx];
|
||||
|
||||
n = array->size / sizeof(struct resident);
|
||||
for (i = 0; i < n; ++i) {
|
||||
rsd = util_dynarray_element(array, struct resident, i);
|
||||
|
||||
nvc0_resource_validate(rsd->res, rsd->flags);
|
||||
}
|
||||
}
|
||||
|
||||
nvc0_screen_make_buffers_resident(nvc0->screen);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,32 +50,40 @@
|
|||
#define NVC0_NEW_TEXTURES (1 << 19)
|
||||
#define NVC0_NEW_SAMPLERS (1 << 20)
|
||||
#define NVC0_NEW_TFB_TARGETS (1 << 21)
|
||||
#define NVC0_NEW_IDXBUF (1 << 22)
|
||||
|
||||
#define NVC0_BUFCTX_CONSTANT 0
|
||||
#define NVC0_BUFCTX_FRAME 1
|
||||
#define NVC0_BUFCTX_VERTEX 2
|
||||
#define NVC0_BUFCTX_TEXTURES 3
|
||||
#define NVC0_BUFCTX_TFB 4
|
||||
#define NVC0_BUFCTX_COUNT 5
|
||||
#define NVC0_BIND_FB 0
|
||||
#define NVC0_BIND_VTX 1
|
||||
#define NVC0_BIND_IDX 2
|
||||
#define NVC0_BIND_TEX 3
|
||||
#define NVC0_BIND_CB(s, i) (4 + 16 * (s) + (i))
|
||||
#define NVC0_BIND_TFB 84
|
||||
#define NVC0_BIND_SCREEN 85
|
||||
#define NVC0_BIND_TLS 86
|
||||
#define NVC0_BIND_COUNT 87
|
||||
#define NVC0_BIND_2D 0
|
||||
#define NVC0_BIND_M2MF 0
|
||||
#define NVC0_BIND_FENCE 1
|
||||
|
||||
struct nvc0_context {
|
||||
struct nouveau_context base;
|
||||
|
||||
struct nvc0_screen *screen;
|
||||
struct nouveau_bufctx *bufctx_3d;
|
||||
struct nouveau_bufctx *bufctx;
|
||||
|
||||
struct util_dynarray residents[NVC0_BUFCTX_COUNT];
|
||||
unsigned residents_size;
|
||||
struct nvc0_screen *screen;
|
||||
|
||||
uint32_t dirty;
|
||||
|
||||
struct {
|
||||
boolean flushed;
|
||||
boolean rasterizer_discard;
|
||||
boolean early_z;
|
||||
boolean prim_restart;
|
||||
uint32_t instance_elts; /* bitmask of per-instance elements */
|
||||
uint32_t instance_base;
|
||||
int32_t index_bias;
|
||||
boolean prim_restart;
|
||||
boolean early_z;
|
||||
uint16_t scissor;
|
||||
boolean rasterizer_discard;
|
||||
uint8_t num_vtxbufs;
|
||||
uint8_t num_vtxelts;
|
||||
uint8_t num_textures[5];
|
||||
|
|
@ -142,20 +150,9 @@ nvc0_context(struct pipe_context *pipe)
|
|||
|
||||
/* nvc0_context.c */
|
||||
struct pipe_context *nvc0_create(struct pipe_screen *, void *);
|
||||
|
||||
void nvc0_default_flush_notify(struct nouveau_channel *);
|
||||
|
||||
void nvc0_bufctx_emit_relocs(struct nvc0_context *);
|
||||
void nvc0_bufctx_add_resident(struct nvc0_context *, int ctx,
|
||||
struct nv04_resource *, uint32_t flags);
|
||||
void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx,
|
||||
struct nv04_resource *);
|
||||
static INLINE void
|
||||
nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx)
|
||||
{
|
||||
nvc0->residents_size -= nvc0->residents[ctx].size;
|
||||
util_dynarray_resize(&nvc0->residents[ctx], 0);
|
||||
}
|
||||
void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
|
||||
boolean on_flush);
|
||||
void nvc0_default_kick_notify(struct nouveau_pushbuf *);
|
||||
|
||||
/* nvc0_draw.c */
|
||||
extern struct draw_stage *nvc0_draw_render_stage(struct nvc0_context *);
|
||||
|
|
@ -168,9 +165,9 @@ void nvc0_program_library_upload(struct nvc0_context *);
|
|||
|
||||
/* nvc0_query.c */
|
||||
void nvc0_init_query_functions(struct nvc0_context *);
|
||||
void nvc0_query_pushbuf_submit(struct nouveau_channel *,
|
||||
void nvc0_query_pushbuf_submit(struct nouveau_pushbuf *,
|
||||
struct pipe_query *, unsigned result_offset);
|
||||
void nvc0_query_fifo_wait(struct nouveau_channel *, struct pipe_query *);
|
||||
void nvc0_query_fifo_wait(struct nouveau_pushbuf *, struct pipe_query *);
|
||||
void nvc0_so_target_save_offset(struct pipe_context *,
|
||||
struct pipe_stream_output_target *, unsigned i,
|
||||
boolean *serialize);
|
||||
|
|
@ -210,7 +207,7 @@ nvc0_create_sampler_view(struct pipe_context *,
|
|||
|
||||
/* nvc0_transfer.c */
|
||||
void
|
||||
nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
||||
nvc0_m2mf_transfer_rect(struct nvc0_context *,
|
||||
const struct nv50_m2mf_rect *dst,
|
||||
const struct nv50_m2mf_rect *src,
|
||||
uint32_t nblocksx, uint32_t nblocksy);
|
||||
|
|
@ -241,8 +238,9 @@ nvc0_vertex_state_delete(struct pipe_context *pipe, void *hwcso);
|
|||
|
||||
void nvc0_vertex_arrays_validate(struct nvc0_context *nvc0);
|
||||
|
||||
void nvc0_idxbuf_validate(struct nvc0_context *);
|
||||
|
||||
/* nvc0_push.c */
|
||||
void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *);
|
||||
void nvc0_push_vbo2(struct nvc0_context *, const struct pipe_draw_info *);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,80 +65,82 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
|
|||
|
||||
compressed = FALSE; /* not yet supported */
|
||||
|
||||
if (mt->base.base.bind & PIPE_BIND_CURSOR)
|
||||
return NOUVEAU_BO_TILE_SCANOUT;
|
||||
if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
|
||||
return 0;
|
||||
if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
|
||||
return 0;
|
||||
|
||||
switch (mt->base.base.format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
if (compressed)
|
||||
tile_flags = 0x0200 + (ms << 8);
|
||||
tile_flags = 0x02 + ms;
|
||||
else
|
||||
tile_flags = 0x0100;
|
||||
tile_flags = 0x01;
|
||||
break;
|
||||
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
|
||||
if (compressed)
|
||||
tile_flags = 0x5100 + (ms << 8);
|
||||
tile_flags = 0x51 + ms;
|
||||
else
|
||||
tile_flags = 0x4600;
|
||||
tile_flags = 0x46;
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
|
||||
if (compressed)
|
||||
tile_flags = 0x1700 + (ms << 8);
|
||||
tile_flags = 0x17 + ms;
|
||||
else
|
||||
tile_flags = 0x1100;
|
||||
tile_flags = 0x11;
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT:
|
||||
if (compressed)
|
||||
tile_flags = 0x8600 + (ms << 8);
|
||||
tile_flags = 0x86 + ms;
|
||||
else
|
||||
tile_flags = 0x7b00;
|
||||
tile_flags = 0x7b;
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
|
||||
if (compressed)
|
||||
tile_flags = 0xce00 + (ms << 8);
|
||||
tile_flags = 0xce + ms;
|
||||
else
|
||||
tile_flags = 0xc300;
|
||||
tile_flags = 0xc3;
|
||||
break;
|
||||
default:
|
||||
switch (util_format_get_blocksizebits(mt->base.base.format)) {
|
||||
case 128:
|
||||
if (compressed)
|
||||
tile_flags = 0xf400 + (ms << 9);
|
||||
tile_flags = 0xf4 + ms;
|
||||
else
|
||||
tile_flags = 0xfe00;
|
||||
tile_flags = 0xfe;
|
||||
break;
|
||||
case 64:
|
||||
if (compressed) {
|
||||
switch (ms) {
|
||||
case 0: tile_flags = 0xe600; break;
|
||||
case 1: tile_flags = 0xeb00; break;
|
||||
case 2: tile_flags = 0xed00; break;
|
||||
case 3: tile_flags = 0xf200; break;
|
||||
case 0: tile_flags = 0xe6; break;
|
||||
case 1: tile_flags = 0xeb; break;
|
||||
case 2: tile_flags = 0xed; break;
|
||||
case 3: tile_flags = 0xf2; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
tile_flags = 0xfe00;
|
||||
tile_flags = 0xfe;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (compressed) {
|
||||
switch (ms) {
|
||||
case 0: tile_flags = 0xdb00; break;
|
||||
case 1: tile_flags = 0xdd00; break;
|
||||
case 2: tile_flags = 0xdf00; break;
|
||||
case 3: tile_flags = 0xe400; break;
|
||||
case 0: tile_flags = 0xdb; break;
|
||||
case 1: tile_flags = 0xdd; break;
|
||||
case 2: tile_flags = 0xdf; break;
|
||||
case 3: tile_flags = 0xe4; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
tile_flags = 0xfe00;
|
||||
tile_flags = 0xfe;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
case 8:
|
||||
tile_flags = 0xfe00;
|
||||
tile_flags = 0xfe;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -146,12 +148,6 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
|
|||
break;
|
||||
}
|
||||
|
||||
if (mt->base.base.bind & PIPE_BIND_SCANOUT)
|
||||
tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
|
||||
|
||||
if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
|
||||
tile_flags &= ~0xff00;
|
||||
|
||||
return tile_flags;
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +275,8 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
int ret;
|
||||
uint32_t tile_flags;
|
||||
union nouveau_bo_config bo_config;
|
||||
uint32_t bo_flags;
|
||||
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
|
@ -289,7 +286,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
|
||||
tile_flags = nvc0_mt_choose_storage_type(mt, TRUE);
|
||||
bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(mt, TRUE);
|
||||
|
||||
if (!nvc0_miptree_init_ms_mode(mt)) {
|
||||
FREE(mt);
|
||||
|
|
@ -299,23 +296,29 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
|||
if (unlikely(pt->flags & NVC0_RESOURCE_FLAG_VIDEO)) {
|
||||
nvc0_miptree_init_layout_video(mt);
|
||||
} else
|
||||
if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
|
||||
if (likely(bo_config.nvc0.memtype)) {
|
||||
nvc0_miptree_init_layout_tiled(mt);
|
||||
} else
|
||||
if (!nv50_miptree_init_layout_linear(mt)) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
bo_config.nvc0.tile_mode = mt->level[0].tile_mode;
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
|
||||
mt->total_size,
|
||||
mt->level[0].tile_mode, tile_flags,
|
||||
&mt->base.bo);
|
||||
mt->base.domain = NOUVEAU_BO_VRAM;
|
||||
|
||||
bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP;
|
||||
|
||||
if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
|
||||
bo_flags |= NOUVEAU_BO_CONTIG;
|
||||
|
||||
ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config,
|
||||
&mt->base.bo);
|
||||
if (ret) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
mt->base.domain = NOUVEAU_BO_VRAM;
|
||||
mt->base.address = mt->base.bo->offset;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -618,7 +618,17 @@ nvc0_program_translate(struct nvc0_program *prog)
|
|||
assert(info->bin.tlsSpace < (1 << 24));
|
||||
prog->hdr[0] |= 1 << 26;
|
||||
prog->hdr[1] |= info->bin.tlsSpace; /* l[] size */
|
||||
prog->need_tls = TRUE;
|
||||
}
|
||||
/* TODO: factor 2 only needed where joinat/precont is used,
|
||||
* and we only have to count non-uniform branches
|
||||
*/
|
||||
/*
|
||||
if ((info->maxCFDepth * 2) > 16) {
|
||||
prog->hdr[2] |= (((info->maxCFDepth * 2) + 47) / 48) * 0x200;
|
||||
prog->need_tls = TRUE;
|
||||
}
|
||||
*/
|
||||
if (info->io.globalAccess)
|
||||
prog->hdr[0] |= 1 << 16;
|
||||
|
||||
|
|
@ -649,15 +659,15 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
|
|||
}
|
||||
size = align(size, 0x40); /* required by SP_START_ID */
|
||||
|
||||
ret = nouveau_resource_alloc(screen->text_heap, size, prog, &prog->res);
|
||||
ret = nouveau_heap_alloc(screen->text_heap, size, prog, &prog->mem);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("out of code space\n");
|
||||
return FALSE;
|
||||
}
|
||||
prog->code_base = prog->res->start;
|
||||
prog->immd_base = align(prog->res->start + prog->immd_base, 0x100);
|
||||
prog->code_base = prog->mem->start;
|
||||
prog->immd_base = align(prog->mem->start + prog->immd_base, 0x100);
|
||||
assert((prog->immd_size == 0) || (prog->immd_base + prog->immd_size <=
|
||||
prog->res->start + prog->res->size));
|
||||
prog->mem->start + prog->mem->size));
|
||||
|
||||
code_pos = prog->code_base + NVC0_SHADER_HEADER_SIZE;
|
||||
|
||||
|
|
@ -679,8 +689,8 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
|
|||
screen->text, prog->immd_base, NOUVEAU_BO_VRAM,
|
||||
prog->immd_size, prog->immd_data);
|
||||
|
||||
BEGIN_RING(screen->base.channel, RING_3D(MEM_BARRIER), 1);
|
||||
OUT_RING (screen->base.channel, 0x1111);
|
||||
BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(MEM_BARRIER), 1);
|
||||
PUSH_DATA (nvc0->base.pushbuf, 0x1111);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -701,8 +711,8 @@ nvc0_program_library_upload(struct nvc0_context *nvc0)
|
|||
if (!size)
|
||||
return;
|
||||
|
||||
ret = nouveau_resource_alloc(screen->text_heap, align(size, 0x100), NULL,
|
||||
&screen->lib_code);
|
||||
ret = nouveau_heap_alloc(screen->text_heap, align(size, 0x100), NULL,
|
||||
&screen->lib_code);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
|
|
@ -718,8 +728,8 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog)
|
|||
const struct pipe_shader_state pipe = prog->pipe;
|
||||
const ubyte type = prog->type;
|
||||
|
||||
if (prog->res)
|
||||
nouveau_resource_free(&prog->res);
|
||||
if (prog->mem)
|
||||
nouveau_heap_free(&prog->mem);
|
||||
|
||||
if (prog->code)
|
||||
FREE(prog->code);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct nvc0_program {
|
|||
|
||||
ubyte type;
|
||||
boolean translated;
|
||||
boolean need_tls;
|
||||
uint8_t max_gpr;
|
||||
|
||||
uint32_t *code;
|
||||
|
|
@ -54,7 +55,7 @@ struct nvc0_program {
|
|||
|
||||
struct nvc0_transform_feedback_state *tfb;
|
||||
|
||||
struct nouveau_resource *res;
|
||||
struct nouveau_heap *mem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "nvc0_3d.xml.h"
|
||||
|
||||
struct push_context {
|
||||
struct nouveau_channel *chan;
|
||||
struct nouveau_pushbuf *push;
|
||||
|
||||
void *idxbuf;
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ init_push_context(struct nvc0_context *nvc0, struct push_context *ctx)
|
|||
{
|
||||
struct pipe_vertex_element *ve;
|
||||
|
||||
ctx->chan = nvc0->screen->base.channel;
|
||||
ctx->push = nvc0->base.pushbuf;
|
||||
ctx->translate = nvc0->vertex->translate;
|
||||
|
||||
if (likely(nvc0->vertex->num_elements < 32))
|
||||
|
|
@ -72,7 +72,7 @@ set_edgeflag(struct push_context *ctx, unsigned vtx_id)
|
|||
|
||||
if (ctx->edgeflag.value != f) {
|
||||
ctx->edgeflag.value = f;
|
||||
IMMED_RING(ctx->chan, RING_3D(EDGEFLAG_ENABLE), f ? 1 : 0);
|
||||
IMMED_NVC0(ctx->push, NVC0_3D(EDGEFLAG), f ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,11 +80,11 @@ static INLINE void
|
|||
set_vertexid(struct push_context *ctx, uint32_t vtx_id)
|
||||
{
|
||||
#if 0
|
||||
BEGIN_RING(ctx->chan, RING_3D(VERTEX_ID), 1); /* broken on nvc0 */
|
||||
BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_ID), 1); /* broken on nvc0 */
|
||||
#else
|
||||
BEGIN_RING(ctx->chan, RING_3D(VERTEX_DATA), 1); /* as last attribute */
|
||||
BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_DATA), 1); /* as last attribute */
|
||||
#endif
|
||||
OUT_RING (ctx->chan, vtx_id);
|
||||
PUSH_DATA (ctx->push, vtx_id);
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
|
|
@ -135,11 +135,11 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
|
|||
|
||||
size = ctx->vertex_words * nr;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur);
|
||||
ctx->push->cur += size;
|
||||
|
||||
if (unlikely(ctx->need_vertex_id) && likely(size))
|
||||
set_vertexid(ctx, elts[0]);
|
||||
|
|
@ -150,9 +150,9 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
|
|||
if (nr != push) {
|
||||
count--;
|
||||
elts++;
|
||||
BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
|
||||
OUT_RING (ctx->chan, 0);
|
||||
OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
|
||||
BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
|
||||
PUSH_DATA (ctx->push, 0);
|
||||
PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
|
||||
(ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
|
||||
}
|
||||
}
|
||||
|
|
@ -176,11 +176,11 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
|
|||
|
||||
size = ctx->vertex_words * nr;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur);
|
||||
ctx->push->cur += size;
|
||||
|
||||
if (unlikely(ctx->need_vertex_id))
|
||||
set_vertexid(ctx, elts[0]);
|
||||
|
|
@ -191,9 +191,9 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
|
|||
if (nr != push) {
|
||||
count--;
|
||||
elts++;
|
||||
BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
|
||||
OUT_RING (ctx->chan, 0);
|
||||
OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
|
||||
BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
|
||||
PUSH_DATA (ctx->push, 0);
|
||||
PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
|
||||
(ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
|
||||
}
|
||||
}
|
||||
|
|
@ -217,11 +217,11 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
|
|||
|
||||
size = ctx->vertex_words * nr;
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur);
|
||||
ctx->push->cur += size;
|
||||
|
||||
if (unlikely(ctx->need_vertex_id))
|
||||
set_vertexid(ctx, elts[0]);
|
||||
|
|
@ -232,9 +232,9 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
|
|||
if (nr != push) {
|
||||
count--;
|
||||
elts++;
|
||||
BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
|
||||
OUT_RING (ctx->chan, 0);
|
||||
OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
|
||||
BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
|
||||
PUSH_DATA (ctx->push, 0);
|
||||
PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
|
||||
(ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
|
||||
}
|
||||
}
|
||||
|
|
@ -250,11 +250,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
|
|||
if (unlikely(ctx->edgeflag.buffer >= 0))
|
||||
set_edgeflag(ctx, start);
|
||||
|
||||
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
|
||||
BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
|
||||
|
||||
ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
|
||||
ctx->chan->cur);
|
||||
ctx->chan->cur += size;
|
||||
ctx->push->cur);
|
||||
ctx->push->cur += size;
|
||||
|
||||
if (unlikely(ctx->need_vertex_id))
|
||||
set_vertexid(ctx, start);
|
||||
|
|
@ -354,17 +354,17 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
|
|||
|
||||
if (unlikely(ctx.need_vertex_id)) {
|
||||
const unsigned a = nvc0->vertex->num_elements;
|
||||
BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
|
||||
OUT_RING (ctx.chan, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
|
||||
BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
|
||||
PUSH_DATA (ctx.push, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
|
||||
NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
|
||||
NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
|
||||
BEGIN_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 1);
|
||||
OUT_RING (ctx.chan, (((0x80 + a * 0x10) / 4) << 4) | 1);
|
||||
BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 1);
|
||||
PUSH_DATA (ctx.push, (((0x80 + a * 0x10) / 4) << 4) | 1);
|
||||
}
|
||||
|
||||
while (inst_count--) {
|
||||
BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (ctx.chan, ctx.prim);
|
||||
BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (ctx.push, ctx.prim);
|
||||
switch (index_size) {
|
||||
case 0:
|
||||
emit_vertices_seq(&ctx, info->start, vert_count);
|
||||
|
|
@ -382,20 +382,20 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
|
|||
assert(0);
|
||||
break;
|
||||
}
|
||||
IMMED_RING(ctx.chan, RING_3D(VERTEX_END_GL), 0);
|
||||
IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_END_GL), 0);
|
||||
|
||||
ctx.instance_id++;
|
||||
ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
|
||||
if (unlikely(ctx.edgeflag.value == 0.0f))
|
||||
IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1);
|
||||
IMMED_NVC0(ctx.push, NVC0_3D(EDGEFLAG), 1);
|
||||
|
||||
if (unlikely(ctx.need_vertex_id)) {
|
||||
const unsigned a = nvc0->vertex->num_elements;
|
||||
IMMED_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 0);
|
||||
BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
|
||||
OUT_RING (ctx.chan,
|
||||
IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 0);
|
||||
BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
|
||||
PUSH_DATA (ctx.push,
|
||||
NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST |
|
||||
NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
|
||||
NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
* Authors: Christoph Bumiller
|
||||
*/
|
||||
|
||||
#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
|
||||
#include "nvc0_context.h"
|
||||
#include "nouveau/nv_object.xml.h"
|
||||
|
||||
|
|
@ -71,14 +73,12 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size)
|
|||
return FALSE;
|
||||
q->offset = q->base;
|
||||
|
||||
ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD |
|
||||
NOUVEAU_BO_NOSYNC);
|
||||
ret = nouveau_bo_map(q->bo, 0, screen->base.client);
|
||||
if (ret) {
|
||||
nvc0_query_allocate(nvc0, q, 0);
|
||||
return FALSE;
|
||||
}
|
||||
q->data = q->bo->map;
|
||||
nouveau_bo_unmap(q->bo);
|
||||
q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -150,17 +150,18 @@ nvc0_query_create(struct pipe_context *pipe, unsigned type)
|
|||
}
|
||||
|
||||
static void
|
||||
nvc0_query_get(struct nouveau_channel *chan, struct nvc0_query *q,
|
||||
nvc0_query_get(struct nouveau_pushbuf *push, struct nvc0_query *q,
|
||||
unsigned offset, uint32_t get)
|
||||
{
|
||||
offset += q->offset;
|
||||
|
||||
MARK_RING (chan, 5, 2);
|
||||
BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, q->sequence);
|
||||
OUT_RING (chan, get);
|
||||
PUSH_SPACE(push, 5);
|
||||
PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
|
||||
BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
PUSH_DATAh(push, q->bo->offset + offset);
|
||||
PUSH_DATA (push, q->bo->offset + offset);
|
||||
PUSH_DATA (push, q->sequence);
|
||||
PUSH_DATA (push, get);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -176,7 +177,7 @@ static void
|
|||
nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_query *q = nvc0_query(pq);
|
||||
|
||||
/* For occlusion queries we have to change the storage, because a previous
|
||||
|
|
@ -201,41 +202,42 @@ nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
case PIPE_QUERY_OCCLUSION_PREDICATE:
|
||||
q->nesting = nvc0->screen->num_occlusion_queries_active++;
|
||||
if (q->nesting) {
|
||||
nvc0_query_get(chan, q, 0x10, 0x0100f002);
|
||||
nvc0_query_get(push, q, 0x10, 0x0100f002);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
|
||||
OUT_RING (chan, NVC0_3D_COUNTER_RESET_SAMPLECNT);
|
||||
IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
|
||||
PUSH_SPACE(push, 3);
|
||||
BEGIN_NVC0(push, NVC0_3D(COUNTER_RESET), 1);
|
||||
PUSH_DATA (push, NVC0_3D_COUNTER_RESET_SAMPLECNT);
|
||||
IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1);
|
||||
}
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_GENERATED:
|
||||
nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
nvc0_query_get(chan, q, 0x10, 0x05805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x10, 0x05805002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_SO_STATISTICS:
|
||||
nvc0_query_get(chan, q, 0x20, 0x05805002 | (q->index << 5));
|
||||
nvc0_query_get(chan, q, 0x30, 0x06805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x20, 0x05805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x30, 0x06805002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
|
||||
nvc0_query_get(chan, q, 0x10, 0x03005002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x10, 0x03005002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT:
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
nvc0_query_get(chan, q, 0x10, 0x00005002);
|
||||
nvc0_query_get(push, q, 0x10, 0x00005002);
|
||||
break;
|
||||
case PIPE_QUERY_PIPELINE_STATISTICS:
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */
|
||||
nvc0_query_get(chan, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -248,7 +250,7 @@ static void
|
|||
nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_query *q = nvc0_query(pq);
|
||||
|
||||
if (!q->active) {
|
||||
|
|
@ -263,49 +265,51 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
switch (q->type) {
|
||||
case PIPE_QUERY_OCCLUSION_COUNTER:
|
||||
case PIPE_QUERY_OCCLUSION_PREDICATE:
|
||||
nvc0_query_get(chan, q, 0, 0x0100f002);
|
||||
if (--nvc0->screen->num_occlusion_queries_active == 0)
|
||||
IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 0);
|
||||
nvc0_query_get(push, q, 0, 0x0100f002);
|
||||
if (--nvc0->screen->num_occlusion_queries_active == 0) {
|
||||
PUSH_SPACE(push, 1);
|
||||
IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0);
|
||||
}
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_GENERATED:
|
||||
nvc0_query_get(chan, q, 0, 0x06805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0, 0x06805002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
nvc0_query_get(chan, q, 0, 0x05805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0, 0x05805002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_SO_STATISTICS:
|
||||
nvc0_query_get(chan, q, 0x00, 0x05805002 | (q->index << 5));
|
||||
nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x00, 0x05805002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
|
||||
/* TODO: How do we sum over all streams for render condition ? */
|
||||
/* PRIMS_DROPPED doesn't write sequence, use a ZERO query to sync on */
|
||||
nvc0_query_get(chan, q, 0x00, 0x03005002 | (q->index << 5));
|
||||
nvc0_query_get(chan, q, 0x20, 0x00005002);
|
||||
nvc0_query_get(push, q, 0x00, 0x03005002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x20, 0x00005002);
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP:
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT:
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
nvc0_query_get(chan, q, 0, 0x00005002);
|
||||
nvc0_query_get(push, q, 0, 0x00005002);
|
||||
break;
|
||||
case PIPE_QUERY_GPU_FINISHED:
|
||||
nvc0_query_get(chan, q, 0, 0x1000f010);
|
||||
nvc0_query_get(push, q, 0, 0x1000f010);
|
||||
break;
|
||||
case PIPE_QUERY_PIPELINE_STATISTICS:
|
||||
nvc0_query_get(chan, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
|
||||
nvc0_query_get(chan, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
|
||||
nvc0_query_get(chan, q, 0x20, 0x02802002); /* VP, LAUNCHES */
|
||||
nvc0_query_get(chan, q, 0x30, 0x03806002); /* GP, LAUNCHES */
|
||||
nvc0_query_get(chan, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
|
||||
nvc0_query_get(chan, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
|
||||
nvc0_query_get(chan, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
|
||||
nvc0_query_get(chan, q, 0x70, 0x0980a002); /* ROP, PIXELS */
|
||||
nvc0_query_get(chan, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */
|
||||
nvc0_query_get(chan, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
|
||||
nvc0_query_get(push, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
|
||||
nvc0_query_get(push, q, 0x20, 0x02802002); /* VP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0x30, 0x03806002); /* GP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
|
||||
nvc0_query_get(push, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
|
||||
nvc0_query_get(push, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
|
||||
nvc0_query_get(push, q, 0x70, 0x0980a002); /* ROP, PIXELS */
|
||||
nvc0_query_get(push, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */
|
||||
nvc0_query_get(push, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */
|
||||
break;
|
||||
case NVC0_QUERY_TFB_BUFFER_OFFSET:
|
||||
/* indexed by TFB buffer instead of by vertex stream */
|
||||
nvc0_query_get(chan, q, 0x00, 0x0d005002 | (q->index << 5));
|
||||
nvc0_query_get(push, q, 0x00, 0x0d005002 | (q->index << 5));
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
@ -314,32 +318,20 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
}
|
||||
|
||||
static INLINE boolean
|
||||
nvc0_query_ready(struct nvc0_query *q)
|
||||
nvc0_query_ready(struct nouveau_client *cli, struct nvc0_query *q)
|
||||
{
|
||||
if (q->is64bit) {
|
||||
if (nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOWAIT))
|
||||
return FALSE;
|
||||
nouveau_bo_unmap(q->bo);
|
||||
return TRUE;
|
||||
return !nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOBLOCK, cli);
|
||||
} else {
|
||||
return q->data[0] == q->sequence;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
nvc0_query_wait(struct nvc0_query *q)
|
||||
{
|
||||
int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
|
||||
if (ret)
|
||||
return FALSE;
|
||||
nouveau_bo_unmap(q->bo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
||||
boolean wait, union pipe_query_result *result)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nvc0_query *q = nvc0_query(pq);
|
||||
uint64_t *res64 = (uint64_t*)result;
|
||||
uint32_t *res32 = (uint32_t*)result;
|
||||
|
|
@ -348,15 +340,15 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
|||
unsigned i;
|
||||
|
||||
if (!q->ready) /* update ? */
|
||||
q->ready = nvc0_query_ready(q);
|
||||
q->ready = nvc0_query_ready(nvc0->screen->base.client, q);
|
||||
if (!q->ready) {
|
||||
struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
|
||||
if (!wait) {
|
||||
if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
|
||||
FIRE_RING(chan);
|
||||
/* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
|
||||
if (nouveau_pushbuf_refd(nvc0->base.pushbuf, q->bo) & NOUVEAU_BO_WR)
|
||||
PUSH_KICK(nvc0->base.pushbuf);
|
||||
return FALSE;
|
||||
}
|
||||
if (!nvc0_query_wait(q))
|
||||
if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
|
||||
return FALSE;
|
||||
}
|
||||
q->ready = TRUE;
|
||||
|
|
@ -407,19 +399,20 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
|||
}
|
||||
|
||||
void
|
||||
nvc0_query_fifo_wait(struct nouveau_channel *chan, struct pipe_query *pq)
|
||||
nvc0_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq)
|
||||
{
|
||||
struct nvc0_query *q = nvc0_query(pq);
|
||||
unsigned offset = q->offset;
|
||||
|
||||
if (q->type == PIPE_QUERY_SO_OVERFLOW_PREDICATE) offset += 0x20;
|
||||
|
||||
MARK_RING (chan, 5, 2);
|
||||
BEGIN_RING(chan, RING_3D_(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
|
||||
OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, q->sequence);
|
||||
OUT_RING (chan, (1 << 12) |
|
||||
PUSH_SPACE(push, 5);
|
||||
PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
BEGIN_NVC0(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
|
||||
PUSH_DATAh(push, q->bo->offset + offset);
|
||||
PUSH_DATA (push, q->bo->offset + offset);
|
||||
PUSH_DATA (push, q->sequence);
|
||||
PUSH_DATA (push, (1 << 12) |
|
||||
NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +421,7 @@ nvc0_render_condition(struct pipe_context *pipe,
|
|||
struct pipe_query *pq, uint mode)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_query *q;
|
||||
uint32_t cond;
|
||||
boolean negated = FALSE;
|
||||
|
|
@ -437,7 +430,8 @@ nvc0_render_condition(struct pipe_context *pipe,
|
|||
mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
|
||||
|
||||
if (!pq) {
|
||||
IMMED_RING(chan, RING_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
|
||||
PUSH_SPACE(push, 1);
|
||||
IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
|
||||
return;
|
||||
}
|
||||
q = nvc0_query(pq);
|
||||
|
|
@ -468,25 +462,27 @@ nvc0_render_condition(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
if (wait)
|
||||
nvc0_query_fifo_wait(chan, pq);
|
||||
nvc0_query_fifo_wait(push, pq);
|
||||
|
||||
MARK_RING (chan, 4, 2);
|
||||
BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, cond);
|
||||
PUSH_SPACE(push, 4);
|
||||
PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, q->bo->offset + q->offset);
|
||||
PUSH_DATA (push, q->bo->offset + q->offset);
|
||||
PUSH_DATA (push, cond);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_query_pushbuf_submit(struct nouveau_channel *chan,
|
||||
nvc0_query_pushbuf_submit(struct nouveau_pushbuf *push,
|
||||
struct pipe_query *pq, unsigned result_offset)
|
||||
{
|
||||
struct nvc0_query *q = nvc0_query(pq);
|
||||
|
||||
#define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8))
|
||||
|
||||
nouveau_pushbuf_submit(chan, q->bo, q->offset + result_offset, 4 |
|
||||
NVC0_IB_ENTRY_1_NO_PREFETCH);
|
||||
nouveau_pushbuf_space(push, 0, 0, 1);
|
||||
nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 |
|
||||
NVC0_IB_ENTRY_1_NO_PREFETCH);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -497,9 +493,9 @@ nvc0_so_target_save_offset(struct pipe_context *pipe,
|
|||
struct nvc0_so_target *targ = nvc0_so_target(ptarg);
|
||||
|
||||
if (*serialize) {
|
||||
struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
|
||||
*serialize = FALSE;
|
||||
IMMED_RING(chan, RING_3D(SERIALIZE), 0);
|
||||
PUSH_SPACE(nvc0_context(pipe)->base.pushbuf, 1);
|
||||
IMMED_NVC0(nvc0_context(pipe)->base.pushbuf, NVC0_3D(SERIALIZE), 0);
|
||||
}
|
||||
|
||||
nvc0_query(targ->pq)->index = index;
|
||||
|
|
|
|||
|
|
@ -238,8 +238,8 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
|
|||
nouveau_fence_wait(screen->base.fence.current);
|
||||
nouveau_fence_ref(NULL, &screen->base.fence.current);
|
||||
}
|
||||
if (screen->base.channel)
|
||||
screen->base.channel->user_private = NULL;
|
||||
if (screen->base.pushbuf)
|
||||
screen->base.pushbuf->user_priv = NULL;
|
||||
|
||||
if (screen->blitctx)
|
||||
FREE(screen->blitctx);
|
||||
|
|
@ -250,17 +250,17 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
|
|||
nouveau_bo_ref(NULL, &screen->fence.bo);
|
||||
nouveau_bo_ref(NULL, &screen->vfetch_cache);
|
||||
|
||||
nouveau_resource_destroy(&screen->lib_code);
|
||||
nouveau_resource_destroy(&screen->text_heap);
|
||||
nouveau_heap_destroy(&screen->lib_code);
|
||||
nouveau_heap_destroy(&screen->text_heap);
|
||||
|
||||
if (screen->tic.entries)
|
||||
FREE(screen->tic.entries);
|
||||
|
||||
nouveau_mm_destroy(screen->mm_VRAM_fe0);
|
||||
|
||||
nouveau_grobj_free(&screen->fermi);
|
||||
nouveau_grobj_free(&screen->eng2d);
|
||||
nouveau_grobj_free(&screen->m2mf);
|
||||
nouveau_object_del(&screen->fermi);
|
||||
nouveau_object_del(&screen->eng2d);
|
||||
nouveau_object_del(&screen->m2mf);
|
||||
|
||||
nouveau_screen_fini(&screen->base);
|
||||
|
||||
|
|
@ -271,102 +271,100 @@ static int
|
|||
nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos,
|
||||
unsigned size, const uint32_t *data)
|
||||
{
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nouveau_pushbuf *push = screen->base.pushbuf;
|
||||
|
||||
size /= 4;
|
||||
|
||||
BEGIN_RING(chan, RING_3D_(NVC0_GRAPH_MACRO_ID), 2);
|
||||
OUT_RING (chan, (m - 0x3800) / 8);
|
||||
OUT_RING (chan, pos);
|
||||
BEGIN_RING_1I(chan, RING_3D_(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
|
||||
OUT_RING (chan, pos);
|
||||
OUT_RINGp (chan, data, size);
|
||||
BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2);
|
||||
PUSH_DATA (push, (m - 0x3800) / 8);
|
||||
PUSH_DATA (push, pos);
|
||||
BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
|
||||
PUSH_DATA (push, pos);
|
||||
PUSH_DATAp(push, data, size);
|
||||
|
||||
return pos + size;
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_magic_3d_init(struct nouveau_channel *chan)
|
||||
nvc0_magic_3d_init(struct nouveau_pushbuf *push)
|
||||
{
|
||||
BEGIN_RING(chan, RING_3D_(0x10cc), 1);
|
||||
OUT_RING (chan, 0xff);
|
||||
BEGIN_RING(chan, RING_3D_(0x10e0), 2);
|
||||
OUT_RING(chan, 0xff);
|
||||
OUT_RING(chan, 0xff);
|
||||
BEGIN_RING(chan, RING_3D_(0x10ec), 2);
|
||||
OUT_RING(chan, 0xff);
|
||||
OUT_RING(chan, 0xff);
|
||||
BEGIN_RING(chan, RING_3D_(0x074c), 1);
|
||||
OUT_RING (chan, 0x3f);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x10cc), 1);
|
||||
PUSH_DATA (push, 0xff);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x10e0), 2);
|
||||
PUSH_DATA(push, 0xff);
|
||||
PUSH_DATA(push, 0xff);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x10ec), 2);
|
||||
PUSH_DATA(push, 0xff);
|
||||
PUSH_DATA(push, 0xff);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x074c), 1);
|
||||
PUSH_DATA (push, 0x3f);
|
||||
|
||||
BEGIN_RING(chan, RING_3D_(0x16a8), 1);
|
||||
OUT_RING (chan, (3 << 16) | 3);
|
||||
BEGIN_RING(chan, RING_3D_(0x1794), 1);
|
||||
OUT_RING (chan, (2 << 16) | 2);
|
||||
BEGIN_RING(chan, RING_3D_(0x0de8), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x16a8), 1);
|
||||
PUSH_DATA (push, (3 << 16) | 3);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1794), 1);
|
||||
PUSH_DATA (push, (2 << 16) | 2);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x0de8), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
#if 0 /* software method */
|
||||
BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1528), 1); /* MP poke */
|
||||
PUSH_DATA (push, 0);
|
||||
#endif
|
||||
|
||||
BEGIN_RING(chan, RING_3D_(0x12ac), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D_(0x0218), 1);
|
||||
OUT_RING (chan, 0x10);
|
||||
BEGIN_RING(chan, RING_3D_(0x10fc), 1);
|
||||
OUT_RING (chan, 0x10);
|
||||
BEGIN_RING(chan, RING_3D_(0x1290), 1);
|
||||
OUT_RING (chan, 0x10);
|
||||
BEGIN_RING(chan, RING_3D_(0x12d8), 2);
|
||||
OUT_RING (chan, 0x10);
|
||||
OUT_RING (chan, 0x10);
|
||||
BEGIN_RING(chan, RING_3D_(0x06d4), 1);
|
||||
OUT_RING (chan, 8);
|
||||
BEGIN_RING(chan, RING_3D_(0x1140), 1);
|
||||
OUT_RING (chan, 0x10);
|
||||
BEGIN_RING(chan, RING_3D_(0x1610), 1);
|
||||
OUT_RING (chan, 0xe);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x12ac), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x0218), 1);
|
||||
PUSH_DATA (push, 0x10);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x10fc), 1);
|
||||
PUSH_DATA (push, 0x10);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1290), 1);
|
||||
PUSH_DATA (push, 0x10);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x12d8), 2);
|
||||
PUSH_DATA (push, 0x10);
|
||||
PUSH_DATA (push, 0x10);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x06d4), 1);
|
||||
PUSH_DATA (push, 8);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1140), 1);
|
||||
PUSH_DATA (push, 0x10);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1610), 1);
|
||||
PUSH_DATA (push, 0xe);
|
||||
|
||||
BEGIN_RING(chan, RING_3D_(0x164c), 1);
|
||||
OUT_RING (chan, 1 << 12);
|
||||
BEGIN_RING(chan, RING_3D_(0x151c), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D_(0x030c), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D_(0x0300), 1);
|
||||
OUT_RING (chan, 3);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x164c), 1);
|
||||
PUSH_DATA (push, 1 << 12);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x151c), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x030c), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x0300), 1);
|
||||
PUSH_DATA (push, 3);
|
||||
#if 0 /* software method */
|
||||
BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x1280), 1); /* PGRAPH poke */
|
||||
PUSH_DATA (push, 0);
|
||||
#endif
|
||||
BEGIN_RING(chan, RING_3D_(0x02d0), 1);
|
||||
OUT_RING (chan, 0x1f40);
|
||||
BEGIN_RING(chan, RING_3D_(0x00fdc), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D_(0x19c0), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D_(0x075c), 1);
|
||||
OUT_RING (chan, 3);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x02d0), 1);
|
||||
PUSH_DATA (push, 0x1f40);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x0fdc), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x19c0), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x075c), 1);
|
||||
PUSH_DATA (push, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0_screen(pscreen);
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
|
||||
MARK_RING (chan, 5, 2);
|
||||
struct nouveau_pushbuf *push = screen->base.pushbuf;
|
||||
|
||||
/* we need to do it after possible flush in MARK_RING */
|
||||
*sequence = ++screen->base.fence.sequence;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, *sequence);
|
||||
OUT_RING (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
|
||||
BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4);
|
||||
PUSH_DATAh(push, screen->fence.bo->offset);
|
||||
PUSH_DATA (push, screen->fence.bo->offset);
|
||||
PUSH_DATA (push, *sequence);
|
||||
PUSH_DATA (push, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
|
||||
(0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
|
||||
}
|
||||
|
||||
|
|
@ -388,10 +386,12 @@ struct pipe_screen *
|
|||
nvc0_screen_create(struct nouveau_device *dev)
|
||||
{
|
||||
struct nvc0_screen *screen;
|
||||
struct nouveau_channel *chan;
|
||||
struct pipe_screen *pscreen;
|
||||
struct nouveau_object *chan;
|
||||
struct nouveau_pushbuf *push;
|
||||
int ret;
|
||||
unsigned i;
|
||||
union nouveau_bo_config mm_config;
|
||||
|
||||
screen = CALLOC_STRUCT(nvc0_screen);
|
||||
if (!screen)
|
||||
|
|
@ -406,7 +406,8 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
return NULL;
|
||||
}
|
||||
chan = screen->base.channel;
|
||||
chan->user_private = screen;
|
||||
push = screen->base.pushbuf;
|
||||
push->user_priv = screen;
|
||||
|
||||
pscreen->destroy = nvc0_screen_destroy;
|
||||
pscreen->context_create = nvc0_create;
|
||||
|
|
@ -419,203 +420,210 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
|
||||
nouveau_screen_init_vdec(&screen->base);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, NULL,
|
||||
&screen->fence.bo);
|
||||
if (ret)
|
||||
goto fail;
|
||||
nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
|
||||
nouveau_bo_map(screen->fence.bo, 0, NULL);
|
||||
screen->fence.map = screen->fence.bo->map;
|
||||
nouveau_bo_unmap(screen->fence.bo);
|
||||
screen->base.fence.emit = nvc0_screen_fence_emit;
|
||||
screen->base.fence.update = nvc0_screen_fence_update;
|
||||
|
||||
for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) {
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, NULL,
|
||||
&screen->scratch.bo[i]);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef9039, NVC0_M2MF, &screen->m2mf);
|
||||
ret = nouveau_object_new(chan, 0xbeef9039, NVC0_M2MF_CLASS, NULL, 0,
|
||||
&screen->m2mf);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
|
||||
|
||||
BIND_RING (chan, screen->m2mf, NVC0_SUBCH_MF);
|
||||
BEGIN_RING(chan, RING_MF(NOTIFY_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, screen->m2mf->oclass);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(NOTIFY_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->fence.bo->offset + 16);
|
||||
PUSH_DATA (push, screen->fence.bo->offset + 16);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef902d, NVC0_2D, &screen->eng2d);
|
||||
ret = nouveau_object_new(chan, 0xbeef902d, NVC0_2D_CLASS, NULL, 0,
|
||||
&screen->eng2d);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
|
||||
|
||||
BIND_RING (chan, screen->eng2d, NVC0_SUBCH_2D);
|
||||
BEGIN_RING(chan, RING_2D(OPERATION), 1);
|
||||
OUT_RING (chan, NVC0_2D_OPERATION_SRCCOPY);
|
||||
BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_2D_(0x0884), 1);
|
||||
OUT_RING (chan, 0x3f);
|
||||
BEGIN_RING(chan, RING_2D_(0x0888), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, screen->eng2d->oclass);
|
||||
BEGIN_NVC0(push, NVC0_2D(OPERATION), 1);
|
||||
PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY);
|
||||
BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_2D(COLOR_KEY_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, SUBC_2D(0x0884), 1);
|
||||
PUSH_DATA (push, 0x3f);
|
||||
BEGIN_NVC0(push, SUBC_2D(0x0888), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
ret = nouveau_grobj_alloc(chan, 0xbeef9097, NVC0_3D, &screen->fermi);
|
||||
ret = nouveau_object_new(chan, 0xbeef9097, NVC0_3D_CLASS, NULL, 0,
|
||||
&screen->fermi);
|
||||
if (ret)
|
||||
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
|
||||
|
||||
BIND_RING (chan, screen->fermi, NVC0_SUBCH_3D);
|
||||
BEGIN_RING(chan, RING_3D(NOTIFY_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
|
||||
PUSH_DATA (push, screen->fermi->oclass);
|
||||
BEGIN_NVC0(push, NVC0_3D(NOTIFY_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->fence.bo->offset + 32);
|
||||
PUSH_DATA (push, screen->fence.bo->offset + 32);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(COND_MODE), 1);
|
||||
OUT_RING (chan, NVC0_3D_COND_MODE_ALWAYS);
|
||||
BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1);
|
||||
PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS);
|
||||
|
||||
if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
|
||||
/* kill shaders after about 1 second (at 100 MHz) */
|
||||
BEGIN_RING(chan, RING_3D(WATCHDOG_TIMER), 1);
|
||||
OUT_RING (chan, 0x17);
|
||||
BEGIN_NVC0(push, NVC0_3D(WATCHDOG_TIMER), 1);
|
||||
PUSH_DATA (push, 0x17);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
|
||||
OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_MS1);
|
||||
BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(LINE_WIDTH_SEPARATE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(TEX_MISC), 1);
|
||||
OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
|
||||
BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1);
|
||||
PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1);
|
||||
BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(LINE_WIDTH_SEPARATE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(LINE_LAST_PIXEL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(TEX_MISC), 1);
|
||||
PUSH_DATA (push, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
|
||||
|
||||
nvc0_magic_3d_init(chan);
|
||||
nvc0_magic_3d_init(push);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, &screen->text);
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
|
||||
&screen->text);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* XXX: getting a page fault at the end of the code buffer every few
|
||||
* launches, don't use the last 256 bytes to work around them - prefetch ?
|
||||
*/
|
||||
nouveau_resource_init(&screen->text_heap, 0, (1 << 20) - 0x100);
|
||||
nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL,
|
||||
&screen->uniforms);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* auxiliary constants (6 user clip planes, base instance id) */
|
||||
BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
|
||||
OUT_RING (chan, 256);
|
||||
OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
|
||||
PUSH_DATA (push, 256);
|
||||
PUSH_DATAh(push, screen->uniforms->offset + (5 << 16));
|
||||
PUSH_DATA (push, screen->uniforms->offset + (5 << 16));
|
||||
for (i = 0; i < 5; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1);
|
||||
OUT_RING (chan, (15 << 4) | 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1);
|
||||
PUSH_DATA (push, (15 << 4) | 1);
|
||||
}
|
||||
|
||||
screen->tls_size = (16 * 32) * (NVC0_CAP_MAX_PROGRAM_TEMPS * 16);
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17,
|
||||
screen->tls_size, &screen->tls);
|
||||
screen->tls_size, NULL, &screen->tls);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CODE_ADDRESS_HIGH), 2);
|
||||
OUT_RELOCh(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 4);
|
||||
OUT_RELOCh(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, screen->tls_size >> 32);
|
||||
OUT_RING (chan, screen->tls_size);
|
||||
BEGIN_RING(chan, RING_3D_(0x07a0), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2);
|
||||
PUSH_DATAh(push, screen->text->offset);
|
||||
PUSH_DATA (push, screen->text->offset);
|
||||
BEGIN_NVC0(push, NVC0_3D(TEMP_ADDRESS_HIGH), 4);
|
||||
PUSH_DATAh(push, screen->tls->offset);
|
||||
PUSH_DATA (push, screen->tls->offset);
|
||||
PUSH_DATA (push, screen->tls_size >> 32);
|
||||
PUSH_DATA (push, screen->tls_size);
|
||||
BEGIN_NVC0(push, NVC0_3D(WARP_TEMP_ALLOC), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(LOCAL_BASE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
|
||||
OUT_RING (chan, 0x54);
|
||||
BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1);
|
||||
PUSH_DATA (push, 0x54);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20,
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
|
||||
&screen->vfetch_cache);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, 3);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->vfetch_cache->offset);
|
||||
PUSH_DATA (push, screen->vfetch_cache->offset);
|
||||
PUSH_DATA (push, 3);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc);
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL,
|
||||
&screen->txc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, NVC0_TIC_MAX_ENTRIES - 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->txc->offset);
|
||||
PUSH_DATA (push, screen->txc->offset);
|
||||
PUSH_DATA (push, NVC0_TIC_MAX_ENTRIES - 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3);
|
||||
OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, NVC0_TSC_MAX_ENTRIES - 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, screen->txc->offset + 65536);
|
||||
PUSH_DATA (push, screen->txc->offset + 65536);
|
||||
PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D_(0x1590), 1); /* deactivate ZCULL */
|
||||
OUT_RING (chan, 0x3f);
|
||||
BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
|
||||
PUSH_DATA (push, 0x3f);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
|
||||
OUT_RING (chan, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
|
||||
BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_MODE), 1);
|
||||
PUSH_DATA (push, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
|
||||
for (i = 0; i < 8 * 2; ++i)
|
||||
OUT_RING(chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
PUSH_DATA(push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
/* neither scissors, viewport nor stencil mask should affect clears */
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_FLAGS), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
OUT_RINGf (chan, 1.0f);
|
||||
BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
|
||||
OUT_RING (chan, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
|
||||
BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
PUSH_DATAf(push, 1.0f);
|
||||
BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
|
||||
PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
|
||||
|
||||
/* We use scissors instead of exact view volume clipping,
|
||||
* so they're always enabled.
|
||||
*/
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 8192 << 16);
|
||||
OUT_RING (chan, 8192 << 16);
|
||||
BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 3);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 8192 << 16);
|
||||
PUSH_DATA (push, 8192 << 16);
|
||||
|
||||
#define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n);
|
||||
|
||||
|
|
@ -627,41 +635,42 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
MK_MACRO(NVC0_3D_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front);
|
||||
MK_MACRO(NVC0_3D_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(RT_SEPARATE_FRAG_DATA), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
|
||||
OUT_RING (chan, 0x40);
|
||||
BEGIN_RING(chan, RING_3D(LAYER), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
|
||||
OUT_RING (chan, 0x30);
|
||||
BEGIN_RING(chan, RING_3D(PATCH_VERTICES), 1);
|
||||
OUT_RING (chan, 3);
|
||||
BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1);
|
||||
OUT_RING (chan, 0x20);
|
||||
BEGIN_RING(chan, RING_3D(SP_SELECT(0)), 1);
|
||||
OUT_RING (chan, 0x00);
|
||||
BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
|
||||
PUSH_DATA (push, 0x40);
|
||||
BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
|
||||
PUSH_DATA (push, 0x30);
|
||||
BEGIN_NVC0(push, NVC0_3D(PATCH_VERTICES), 1);
|
||||
PUSH_DATA (push, 3);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
|
||||
PUSH_DATA (push, 0x20);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1);
|
||||
PUSH_DATA (push, 0x00);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
|
||||
OUT_RING (chan, NVC0_3D_POINT_RASTER_RULES_OGL);
|
||||
BEGIN_NVC0(push, NVC0_3D(POINT_COORD_REPLACE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(POINT_RASTER_RULES), 1);
|
||||
PUSH_DATA (push, NVC0_3D_POINT_RASTER_RULES_OGL);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
|
||||
OUT_RING (chan, 0xab);
|
||||
OUT_RING (chan, 0x00000000);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
|
||||
PUSH_DATA (push, 0xab);
|
||||
PUSH_DATA (push, 0x00000000);
|
||||
|
||||
FIRE_RING (chan);
|
||||
PUSH_KICK (push);
|
||||
|
||||
screen->tic.entries = CALLOC(4096, sizeof(void *));
|
||||
screen->tsc.entries = screen->tic.entries + 2048;
|
||||
|
||||
screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
|
||||
mm_config.nvc0.tile_mode = 0;
|
||||
mm_config.nvc0.memtype = 0xfe0;
|
||||
screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
|
||||
|
||||
if (!nvc0_blitctx_create(screen))
|
||||
goto fail;
|
||||
|
|
@ -675,23 +684,6 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_screen_make_buffers_resident(struct nvc0_screen *screen)
|
||||
{
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
|
||||
const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
|
||||
|
||||
MARK_RING(chan, 0, 5);
|
||||
nouveau_bo_validate(chan, screen->text, flags);
|
||||
nouveau_bo_validate(chan, screen->uniforms, flags);
|
||||
nouveau_bo_validate(chan, screen->txc, flags);
|
||||
nouveau_bo_validate(chan, screen->vfetch_cache, flags);
|
||||
|
||||
if (screen->cur_ctx && screen->cur_ctx->state.tls_required)
|
||||
nouveau_bo_validate(chan, screen->tls, flags);
|
||||
}
|
||||
|
||||
int
|
||||
nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#ifndef __NVC0_SCREEN_H__
|
||||
#define __NVC0_SCREEN_H__
|
||||
|
||||
#define NOUVEAU_NVC0
|
||||
#include "nouveau/nouveau_screen.h"
|
||||
#include "nouveau/nouveau_mm.h"
|
||||
#include "nouveau/nouveau_fence.h"
|
||||
#undef NOUVEAU_NVC0
|
||||
#include "nouveau/nouveau_heap.h"
|
||||
|
||||
#include "nvc0_winsys.h"
|
||||
#include "nvc0_stateobj.h"
|
||||
|
||||
|
|
@ -36,8 +36,8 @@ struct nvc0_screen {
|
|||
|
||||
uint64_t tls_size;
|
||||
|
||||
struct nouveau_resource *text_heap;
|
||||
struct nouveau_resource *lib_code; /* allocated from text_heap */
|
||||
struct nouveau_heap *text_heap;
|
||||
struct nouveau_heap *lib_code; /* allocated from text_heap */
|
||||
|
||||
struct nvc0_blitctx *blitctx;
|
||||
|
||||
|
|
@ -67,9 +67,10 @@ struct nvc0_screen {
|
|||
|
||||
struct nouveau_mman *mm_VRAM_fe0;
|
||||
|
||||
struct nouveau_grobj *fermi;
|
||||
struct nouveau_grobj *eng2d;
|
||||
struct nouveau_grobj *m2mf;
|
||||
struct nouveau_object *fermi;
|
||||
struct nouveau_object *eng2d;
|
||||
struct nouveau_object *m2mf;
|
||||
struct nouveau_object *dijkstra;
|
||||
};
|
||||
|
||||
static INLINE struct nvc0_screen *
|
||||
|
|
@ -92,7 +93,6 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
|
|||
|
||||
if (res->mm) {
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence);
|
||||
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
|
||||
}
|
||||
|
|
@ -101,11 +101,7 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
|
|||
static INLINE void
|
||||
nvc0_resource_validate(struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0_screen(res->base.screen);
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -31,29 +31,33 @@ static INLINE void
|
|||
nvc0_program_update_context_state(struct nvc0_context *nvc0,
|
||||
struct nvc0_program *prog, int stage)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
if (prog->hdr[1])
|
||||
if (prog && prog->need_tls) {
|
||||
const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
|
||||
if (!nvc0->state.tls_required)
|
||||
BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls);
|
||||
nvc0->state.tls_required |= 1 << stage;
|
||||
else
|
||||
} else {
|
||||
if (nvc0->state.tls_required == (1 << stage))
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TLS);
|
||||
nvc0->state.tls_required &= ~(1 << stage);
|
||||
}
|
||||
|
||||
if (prog->immd_size) {
|
||||
const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
|
||||
if (prog && prog->immd_size) {
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
|
||||
/* NOTE: may overlap code of a different shader */
|
||||
OUT_RING (chan, align(prog->immd_size, 0x100));
|
||||
OUT_RELOCh(chan, nvc0->screen->text, prog->immd_base, rl);
|
||||
OUT_RELOCl(chan, nvc0->screen->text, prog->immd_base, rl);
|
||||
BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
|
||||
OUT_RING (chan, (14 << 4) | 1);
|
||||
PUSH_DATA (push, align(prog->immd_size, 0x100));
|
||||
PUSH_DATAh(push, nvc0->screen->text->offset + prog->immd_base);
|
||||
PUSH_DATA (push, nvc0->screen->text->offset + prog->immd_base);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
|
||||
PUSH_DATA (push, (14 << 4) | 1);
|
||||
|
||||
nvc0->state.c14_bound |= 1 << stage;
|
||||
} else
|
||||
if (nvc0->state.c14_bound & (1 << stage)) {
|
||||
BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
|
||||
OUT_RING (chan, (14 << 4) | 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
|
||||
PUSH_DATA (push, (14 << 4) | 0);
|
||||
|
||||
nvc0->state.c14_bound &= ~(1 << stage);
|
||||
}
|
||||
|
|
@ -62,7 +66,7 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0,
|
|||
static INLINE boolean
|
||||
nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
|
||||
{
|
||||
if (prog->res)
|
||||
if (prog->mem)
|
||||
return TRUE;
|
||||
|
||||
if (!prog->translated) {
|
||||
|
|
@ -79,133 +83,129 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
|
|||
void
|
||||
nvc0_vertprog_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_program *vp = nvc0->vertprog;
|
||||
|
||||
if (!nvc0_program_validate(nvc0, vp))
|
||||
return;
|
||||
nvc0_program_update_context_state(nvc0, vp, 0);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SP_SELECT(1)), 2);
|
||||
OUT_RING (chan, 0x11);
|
||||
OUT_RING (chan, vp->code_base);
|
||||
BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(1)), 1);
|
||||
OUT_RING (chan, vp->max_gpr);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2);
|
||||
PUSH_DATA (push, 0x11);
|
||||
PUSH_DATA (push, vp->code_base);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1);
|
||||
PUSH_DATA (push, vp->max_gpr);
|
||||
|
||||
// BEGIN_RING(chan, RING_3D_(0x163c), 1);
|
||||
// OUT_RING (chan, 0);
|
||||
// BEGIN_NVC0(push, NVC0_3D_(0x163c), 1);
|
||||
// PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_fragprog_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_program *fp = nvc0->fragprog;
|
||||
|
||||
if (!nvc0_program_validate(nvc0, fp))
|
||||
return;
|
||||
nvc0_program_update_context_state(nvc0, fp, 4);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2);
|
||||
OUT_RING (chan, 0x51);
|
||||
OUT_RING (chan, fp->code_base);
|
||||
BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(5)), 1);
|
||||
OUT_RING (chan, fp->max_gpr);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2);
|
||||
PUSH_DATA (push, 0x51);
|
||||
PUSH_DATA (push, fp->code_base);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1);
|
||||
PUSH_DATA (push, fp->max_gpr);
|
||||
|
||||
BEGIN_RING(chan, RING_3D_(0x0360), 2);
|
||||
OUT_RING (chan, 0x20164010);
|
||||
OUT_RING (chan, 0x20);
|
||||
BEGIN_RING(chan, RING_3D_(0x196c), 1);
|
||||
OUT_RING (chan, fp->flags[0]);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x0360), 2);
|
||||
PUSH_DATA (push, 0x20164010);
|
||||
PUSH_DATA (push, 0x20);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1);
|
||||
PUSH_DATA (push, fp->flags[0]);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_tctlprog_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_program *tp = nvc0->tctlprog;
|
||||
|
||||
if (!tp) {
|
||||
BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1);
|
||||
OUT_RING (chan, 0x20);
|
||||
return;
|
||||
if (tp && nvc0_program_validate(nvc0, tp)) {
|
||||
if (tp->tp.tess_mode != ~0) {
|
||||
BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
|
||||
PUSH_DATA (push, tp->tp.tess_mode);
|
||||
}
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
|
||||
PUSH_DATA (push, 0x21);
|
||||
PUSH_DATA (push, tp->code_base);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1);
|
||||
PUSH_DATA (push, tp->max_gpr);
|
||||
|
||||
if (tp->tp.input_patch_size <= 32)
|
||||
IMMED_NVC0(push, NVC0_3D(PATCH_VERTICES), tp->tp.input_patch_size);
|
||||
} else {
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
|
||||
PUSH_DATA (push, 0x20);
|
||||
}
|
||||
if (!nvc0_program_validate(nvc0, tp))
|
||||
return;
|
||||
nvc0_program_update_context_state(nvc0, tp, 1);
|
||||
|
||||
if (tp->tp.tess_mode != ~0) {
|
||||
BEGIN_RING(chan, RING_3D(TESS_MODE), 1);
|
||||
OUT_RING (chan, tp->tp.tess_mode);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 2);
|
||||
OUT_RING (chan, 0x21);
|
||||
OUT_RING (chan, tp->code_base);
|
||||
BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(2)), 1);
|
||||
OUT_RING (chan, tp->max_gpr);
|
||||
|
||||
if (tp->tp.input_patch_size <= 32)
|
||||
IMMED_RING(chan, RING_3D(PATCH_VERTICES), tp->tp.input_patch_size);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_tevlprog_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_program *tp = nvc0->tevlprog;
|
||||
|
||||
if (!tp) {
|
||||
BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
|
||||
OUT_RING (chan, 0x30);
|
||||
return;
|
||||
if (tp && nvc0_program_validate(nvc0, tp)) {
|
||||
if (tp->tp.tess_mode != ~0) {
|
||||
BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
|
||||
PUSH_DATA (push, tp->tp.tess_mode);
|
||||
}
|
||||
BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
|
||||
PUSH_DATA (push, 0x31);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_START_ID(3)), 1);
|
||||
PUSH_DATA (push, tp->code_base);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(3)), 1);
|
||||
PUSH_DATA (push, tp->max_gpr);
|
||||
} else {
|
||||
BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
|
||||
PUSH_DATA (push, 0x30);
|
||||
}
|
||||
if (!nvc0_program_validate(nvc0, tp))
|
||||
return;
|
||||
nvc0_program_update_context_state(nvc0, tp, 2);
|
||||
|
||||
if (tp->tp.tess_mode != ~0) {
|
||||
BEGIN_RING(chan, RING_3D(TESS_MODE), 1);
|
||||
OUT_RING (chan, tp->tp.tess_mode);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
|
||||
OUT_RING (chan, 0x31);
|
||||
BEGIN_RING(chan, RING_3D(SP_START_ID(3)), 1);
|
||||
OUT_RING (chan, tp->code_base);
|
||||
BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(3)), 1);
|
||||
OUT_RING (chan, tp->max_gpr);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_gmtyprog_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_program *gp = nvc0->gmtyprog;
|
||||
|
||||
if (gp)
|
||||
nvc0_program_validate(nvc0, gp);
|
||||
|
||||
/* we allow GPs with no code for specifying stream output state only */
|
||||
if (!gp || !gp->code_size) {
|
||||
BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
|
||||
OUT_RING (chan, 0x40);
|
||||
IMMED_RING(chan, RING_3D(LAYER), 0);
|
||||
return;
|
||||
if (gp && gp->code_size) {
|
||||
const boolean gp_selects_layer = gp->hdr[13] & (1 << 9);
|
||||
|
||||
BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
|
||||
PUSH_DATA (push, 0x41);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1);
|
||||
PUSH_DATA (push, gp->code_base);
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1);
|
||||
PUSH_DATA (push, gp->max_gpr);
|
||||
BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
|
||||
PUSH_DATA (push, gp_selects_layer ? NVC0_3D_LAYER_USE_GP : 0);
|
||||
} else {
|
||||
IMMED_NVC0(push, NVC0_3D(LAYER), 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
|
||||
PUSH_DATA (push, 0x40);
|
||||
}
|
||||
nvc0_program_update_context_state(nvc0, gp, 3);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
|
||||
OUT_RING (chan, 0x41);
|
||||
BEGIN_RING(chan, RING_3D(SP_START_ID(4)), 1);
|
||||
OUT_RING (chan, gp->code_base);
|
||||
BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(4)), 1);
|
||||
OUT_RING (chan, gp->max_gpr);
|
||||
BEGIN_RING(chan, RING_3D(LAYER), 1);
|
||||
OUT_RING (chan, (gp->hdr[13] & (1 << 9)) ? NVC0_3D_LAYER_USE_GP : 0);
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_tfb_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_transform_feedback_state *tfb;
|
||||
unsigned b;
|
||||
|
||||
|
|
@ -215,24 +215,24 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
|
|||
else
|
||||
tfb = nvc0->vertprog->tfb;
|
||||
|
||||
IMMED_RING(chan, RING_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
|
||||
IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
|
||||
|
||||
if (tfb && tfb != nvc0->state.tfb) {
|
||||
for (b = 0; b < 4; ++b) {
|
||||
if (tfb->varying_count[b]) {
|
||||
unsigned n = (tfb->varying_count[b] + 3) / 4;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(TFB_STREAM(b)), 3);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, tfb->varying_count[b]);
|
||||
OUT_RING (chan, tfb->stride[b]);
|
||||
BEGIN_RING(chan, RING_3D(TFB_VARYING_LOCS(b, 0)), n);
|
||||
OUT_RINGp (chan, tfb->varying_index[b], n);
|
||||
BEGIN_NVC0(push, NVC0_3D(TFB_STREAM(b)), 3);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, tfb->varying_count[b]);
|
||||
PUSH_DATA (push, tfb->stride[b]);
|
||||
BEGIN_NVC0(push, NVC0_3D(TFB_VARYING_LOCS(b, 0)), n);
|
||||
PUSH_DATAp(push, tfb->varying_index[b], n);
|
||||
|
||||
if (nvc0->tfbbuf[b])
|
||||
nvc0_so_target(nvc0->tfbbuf[b])->stride = tfb->stride[b];
|
||||
} else {
|
||||
IMMED_RING(chan, RING_3D(TFB_VARYING_COUNT(b)), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(TFB_VARYING_COUNT(b)), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -240,7 +240,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
|
|||
|
||||
if (!(nvc0->dirty & NVC0_NEW_TFB_TARGETS))
|
||||
return;
|
||||
nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TFB);
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TFB);
|
||||
|
||||
for (b = 0; b < nvc0->num_tfbbufs; ++b) {
|
||||
struct nvc0_so_target *targ = nvc0_so_target(nvc0->tfbbuf[b]);
|
||||
|
|
@ -253,20 +253,20 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
|
|||
continue;
|
||||
|
||||
if (!targ->clean)
|
||||
nvc0_query_fifo_wait(chan, targ->pq);
|
||||
BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 5);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RESRCh(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR);
|
||||
OUT_RESRCl(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, targ->pipe.buffer_size);
|
||||
nvc0_query_fifo_wait(push, targ->pq);
|
||||
BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset);
|
||||
PUSH_DATA (push, buf->address + targ->pipe.buffer_offset);
|
||||
PUSH_DATA (push, targ->pipe.buffer_size);
|
||||
if (!targ->clean) {
|
||||
nvc0_query_pushbuf_submit(chan, targ->pq, 0x4);
|
||||
nvc0_query_pushbuf_submit(push, targ->pq, 0x4);
|
||||
} else {
|
||||
OUT_RING(chan, 0); /* TFB_BUFFER_OFFSET */
|
||||
PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */
|
||||
targ->clean = FALSE;
|
||||
}
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TFB, buf, NOUVEAU_BO_WR);
|
||||
BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR);
|
||||
}
|
||||
for (; b < 4; ++b)
|
||||
IMMED_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -489,7 +489,7 @@ nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
|
|||
|
||||
nvc0->num_textures[s] = nr;
|
||||
|
||||
nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES);
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX);
|
||||
|
||||
nvc0->dirty |= NVC0_NEW_TEXTURES;
|
||||
}
|
||||
|
|
@ -621,8 +621,7 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|||
}
|
||||
|
||||
if (nvc0->constbuf[shader][index])
|
||||
nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT,
|
||||
nv04_resource(nvc0->constbuf[shader][index]));
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index));
|
||||
|
||||
pipe_resource_reference(&nvc0->constbuf[shader][index], res);
|
||||
|
||||
|
|
@ -681,6 +680,8 @@ nvc0_set_framebuffer_state(struct pipe_context *pipe,
|
|||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
|
||||
|
||||
nvc0->framebuffer = *fb;
|
||||
nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
|
@ -731,7 +732,7 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
|
|||
memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count);
|
||||
nvc0->num_vtxbufs = count;
|
||||
|
||||
nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
|
||||
|
||||
nvc0->dirty |= NVC0_NEW_ARRAYS;
|
||||
}
|
||||
|
|
@ -742,11 +743,16 @@ nvc0_set_index_buffer(struct pipe_context *pipe,
|
|||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
|
||||
if (ib) {
|
||||
pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
|
||||
if (nvc0->idxbuf.buffer)
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX);
|
||||
|
||||
memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
|
||||
if (ib && ib->buffer) {
|
||||
nvc0->dirty |= NVC0_NEW_IDXBUF;
|
||||
pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
|
||||
nvc0->idxbuf.offset = ib->offset;
|
||||
nvc0->idxbuf.index_size = ib->index_size;
|
||||
} else {
|
||||
nvc0->dirty &= ~NVC0_NEW_IDXBUF;
|
||||
pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
static void
|
||||
nvc0_validate_zcull(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
|
||||
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
|
||||
struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
|
||||
|
|
@ -26,89 +26,85 @@ nvc0_validate_zcull(struct nvc0_context *nvc0)
|
|||
else
|
||||
width = fb->width;
|
||||
|
||||
MARK_RING (chan, 23, 4);
|
||||
BEGIN_RING(chan, RING_3D_(0x1590), 1); /* ZCULL_REGION_INDEX (bits 0x3f) */
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D_(0x07e8), 2); /* ZCULL_ADDRESS_A_HIGH */
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_ADDRESS_HIGH), 2);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
offset += 1 << 17;
|
||||
BEGIN_RING(chan, RING_3D_(0x07f0), 2); /* ZCULL_ADDRESS_B_HIGH */
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
BEGIN_RING(chan, RING_3D_(0x07e0), 2);
|
||||
OUT_RING (chan, size);
|
||||
OUT_RING (chan, size >> 16);
|
||||
BEGIN_RING(chan, RING_3D_(0x15c8), 1); /* bits 0x3 */
|
||||
OUT_RING (chan, 2);
|
||||
BEGIN_RING(chan, RING_3D_(0x07c0), 4); /* ZCULL dimensions */
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D_(0x15fc), 2);
|
||||
OUT_RING (chan, 0); /* bits 0xffff */
|
||||
OUT_RING (chan, 0); /* bits 0xffff */
|
||||
BEGIN_RING(chan, RING_3D_(0x1958), 1);
|
||||
OUT_RING (chan, 0); /* bits ~0 */
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_LIMIT_HIGH), 2);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x07e0), 2);
|
||||
PUSH_DATA (push, size);
|
||||
PUSH_DATA (push, size >> 16);
|
||||
BEGIN_NVC0(push, SUBC_3D(0x15c8), 1); /* bits 0x3 */
|
||||
PUSH_DATA (push, 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_WIDTH), 4);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_WINDOW_OFFSET_X), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZCULL_INVALIDATE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_fb(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
|
||||
unsigned i;
|
||||
unsigned ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1;
|
||||
boolean serialize = FALSE;
|
||||
|
||||
nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_FRAME);
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs);
|
||||
BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
OUT_RING (chan, fb->width << 16);
|
||||
OUT_RING (chan, fb->height << 16);
|
||||
|
||||
MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
|
||||
BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
|
||||
BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
PUSH_DATA (push, fb->width << 16);
|
||||
PUSH_DATA (push, fb->height << 16);
|
||||
|
||||
for (i = 0; i < fb->nr_cbufs; ++i) {
|
||||
struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
|
||||
struct nv04_resource *res = nv04_resource(sf->base.texture);
|
||||
struct nouveau_bo *bo = res->bo;
|
||||
uint32_t offset = sf->offset + res->offset;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 9);
|
||||
OUT_RELOCh(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR);
|
||||
if (likely(nouveau_bo_tile_layout(bo))) {
|
||||
BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 9);
|
||||
PUSH_DATAh(push, res->address + sf->offset);
|
||||
PUSH_DATA (push, res->address + sf->offset);
|
||||
if (likely(nouveau_bo_memtype(bo))) {
|
||||
struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
|
||||
|
||||
assert(sf->base.texture->target != PIPE_BUFFER);
|
||||
|
||||
OUT_RING(chan, sf->width);
|
||||
OUT_RING(chan, sf->height);
|
||||
OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
|
||||
OUT_RING(chan, (mt->layout_3d << 16) |
|
||||
PUSH_DATA(push, sf->width);
|
||||
PUSH_DATA(push, sf->height);
|
||||
PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
|
||||
PUSH_DATA(push, (mt->layout_3d << 16) |
|
||||
mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING(chan, sf->base.u.tex.first_layer + sf->depth);
|
||||
OUT_RING(chan, mt->layer_stride >> 2);
|
||||
OUT_RING(chan, sf->base.u.tex.first_layer);
|
||||
PUSH_DATA(push, sf->base.u.tex.first_layer + sf->depth);
|
||||
PUSH_DATA(push, mt->layer_stride >> 2);
|
||||
PUSH_DATA(push, sf->base.u.tex.first_layer);
|
||||
|
||||
ms_mode = mt->ms_mode;
|
||||
} else {
|
||||
if (res->base.target == PIPE_BUFFER) {
|
||||
OUT_RING(chan, 262144);
|
||||
OUT_RING(chan, 1);
|
||||
PUSH_DATA(push, 262144);
|
||||
PUSH_DATA(push, 1);
|
||||
} else {
|
||||
OUT_RING(chan, nv50_miptree(sf->base.texture)->level[0].pitch);
|
||||
OUT_RING(chan, sf->height);
|
||||
PUSH_DATA(push, nv50_miptree(sf->base.texture)->level[0].pitch);
|
||||
PUSH_DATA(push, sf->height);
|
||||
}
|
||||
OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
|
||||
OUT_RING(chan, 1 << 12);
|
||||
OUT_RING(chan, 1);
|
||||
OUT_RING(chan, 0);
|
||||
OUT_RING(chan, 0);
|
||||
PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
|
||||
PUSH_DATA(push, 1 << 12);
|
||||
PUSH_DATA(push, 1);
|
||||
PUSH_DATA(push, 0);
|
||||
PUSH_DATA(push, 0);
|
||||
|
||||
nvc0_resource_fence(res, NOUVEAU_BO_WR);
|
||||
|
||||
|
|
@ -121,33 +117,29 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
|
|||
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
/* only register for writing, otherwise we'd always serialize here */
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, res,
|
||||
res->domain | NOUVEAU_BO_WR);
|
||||
BCTX_REFN(nvc0->bufctx_3d, FB, res, WR);
|
||||
}
|
||||
|
||||
if (fb->zsbuf) {
|
||||
struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
|
||||
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
|
||||
uint32_t offset = sf->offset;
|
||||
|
||||
MARK_RING (chan, 12, 2);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
|
||||
OUT_RING (chan, nvc0_format_table[fb->zsbuf->format].rt);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING (chan, mt->layer_stride >> 2);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, (unk << 16) |
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
PUSH_DATAh(push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, nvc0_format_table[fb->zsbuf->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
|
||||
PUSH_DATA (push, sf->width);
|
||||
PUSH_DATA (push, sf->height);
|
||||
PUSH_DATA (push, (unk << 16) |
|
||||
(sf->base.u.tex.first_layer + sf->depth));
|
||||
BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1);
|
||||
OUT_RING (chan, sf->base.u.tex.first_layer);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
|
||||
PUSH_DATA (push, sf->base.u.tex.first_layer);
|
||||
|
||||
ms_mode = mt->ms_mode;
|
||||
|
||||
|
|
@ -156,58 +148,55 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
|
|||
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
|
||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
BCTX_REFN(nvc0->bufctx_3d, FB, &mt->base, WR);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
IMMED_RING(chan, RING_3D(MULTISAMPLE_MODE), ms_mode);
|
||||
IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), ms_mode);
|
||||
|
||||
if (serialize) {
|
||||
BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
}
|
||||
if (serialize)
|
||||
IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_blend_colour(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
|
||||
OUT_RINGf (chan, nvc0->blend_colour.color[0]);
|
||||
OUT_RINGf (chan, nvc0->blend_colour.color[1]);
|
||||
OUT_RINGf (chan, nvc0->blend_colour.color[2]);
|
||||
OUT_RINGf (chan, nvc0->blend_colour.color[3]);
|
||||
BEGIN_NVC0(push, NVC0_3D(BLEND_COLOR(0)), 4);
|
||||
PUSH_DATAf(push, nvc0->blend_colour.color[0]);
|
||||
PUSH_DATAf(push, nvc0->blend_colour.color[1]);
|
||||
PUSH_DATAf(push, nvc0->blend_colour.color[2]);
|
||||
PUSH_DATAf(push, nvc0->blend_colour.color[3]);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_stencil_ref(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
const ubyte *ref = &nvc0->stencil_ref.ref_value[0];
|
||||
|
||||
IMMED_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), ref[0]);
|
||||
IMMED_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), ref[1]);
|
||||
IMMED_NVC0(push, NVC0_3D(STENCIL_FRONT_FUNC_REF), ref[0]);
|
||||
IMMED_NVC0(push, NVC0_3D(STENCIL_BACK_FUNC_REF), ref[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_stipple(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
unsigned i;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
|
||||
BEGIN_NVC0(push, NVC0_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
|
||||
for (i = 0; i < 32; ++i)
|
||||
OUT_RING(chan, util_bswap32(nvc0->stipple.stipple[i]));
|
||||
PUSH_DATA(push, util_bswap32(nvc0->stipple.stipple[i]));
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_scissor(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct pipe_scissor_state *s = &nvc0->scissor;
|
||||
|
||||
if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
|
||||
|
|
@ -215,32 +204,32 @@ nvc0_validate_scissor(struct nvc0_context *nvc0)
|
|||
return;
|
||||
nvc0->state.scissor = nvc0->rast->pipe.scissor;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
|
||||
if (nvc0->rast->pipe.scissor) {
|
||||
OUT_RING(chan, (s->maxx << 16) | s->minx);
|
||||
OUT_RING(chan, (s->maxy << 16) | s->miny);
|
||||
PUSH_DATA(push, (s->maxx << 16) | s->minx);
|
||||
PUSH_DATA(push, (s->maxy << 16) | s->miny);
|
||||
} else {
|
||||
OUT_RING(chan, (0xffff << 16) | 0);
|
||||
OUT_RING(chan, (0xffff << 16) | 0);
|
||||
PUSH_DATA(push, (0xffff << 16) | 0);
|
||||
PUSH_DATA(push, (0xffff << 16) | 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_viewport(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct pipe_viewport_state *vp = &nvc0->viewport;
|
||||
int x, y, w, h;
|
||||
float zmin, zmax;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
|
||||
OUT_RINGf (chan, vp->translate[0]);
|
||||
OUT_RINGf (chan, vp->translate[1]);
|
||||
OUT_RINGf (chan, vp->translate[2]);
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
|
||||
OUT_RINGf (chan, vp->scale[0]);
|
||||
OUT_RINGf (chan, vp->scale[1]);
|
||||
OUT_RINGf (chan, vp->scale[2]);
|
||||
BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSLATE_X(0)), 3);
|
||||
PUSH_DATAf(push, vp->translate[0]);
|
||||
PUSH_DATAf(push, vp->translate[1]);
|
||||
PUSH_DATAf(push, vp->translate[2]);
|
||||
BEGIN_NVC0(push, NVC0_3D(VIEWPORT_SCALE_X(0)), 3);
|
||||
PUSH_DATAf(push, vp->scale[0]);
|
||||
PUSH_DATAf(push, vp->scale[1]);
|
||||
PUSH_DATAf(push, vp->scale[2]);
|
||||
|
||||
/* now set the viewport rectangle to viewport dimensions for clipping */
|
||||
|
||||
|
|
@ -252,28 +241,27 @@ nvc0_validate_viewport(struct nvc0_context *nvc0)
|
|||
zmin = vp->translate[2] - fabsf(vp->scale[2]);
|
||||
zmax = vp->translate[2] + fabsf(vp->scale[2]);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (w << 16) | x);
|
||||
OUT_RING (chan, (h << 16) | y);
|
||||
BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
OUT_RINGf (chan, zmin);
|
||||
OUT_RINGf (chan, zmax);
|
||||
BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (w << 16) | x);
|
||||
PUSH_DATA (push, (h << 16) | y);
|
||||
BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
|
||||
PUSH_DATAf(push, zmin);
|
||||
PUSH_DATAf(push, zmax);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
nvc0_upload_uclip_planes(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nouveau_bo *bo = nvc0->screen->uniforms;
|
||||
|
||||
MARK_RING (chan, 6 + PIPE_MAX_CLIP_PLANES * 4, 2);
|
||||
BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
|
||||
OUT_RING (chan, 256);
|
||||
OUT_RELOCh(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
BEGIN_RING_1I(chan, RING_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RINGp (chan, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
|
||||
PUSH_DATA (push, 256);
|
||||
PUSH_DATAh(push, bo->offset + (5 << 16));
|
||||
PUSH_DATA (push, bo->offset + (5 << 16));
|
||||
BEGIN_1IC0(push, NVC0_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATAp(push, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
|
|
@ -299,7 +287,7 @@ nvc0_check_program_ucps(struct nvc0_context *nvc0,
|
|||
static void
|
||||
nvc0_validate_clip(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_program *vp;
|
||||
uint8_t clip_enable = nvc0->rast->pipe.clip_plane_enable;
|
||||
|
||||
|
|
@ -320,46 +308,46 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
|
|||
|
||||
if (nvc0->state.clip_enable != clip_enable) {
|
||||
nvc0->state.clip_enable = clip_enable;
|
||||
IMMED_RING(chan, RING_3D(CLIP_DISTANCE_ENABLE), clip_enable);
|
||||
IMMED_NVC0(push, NVC0_3D(CLIP_DISTANCE_ENABLE), clip_enable);
|
||||
}
|
||||
if (nvc0->state.clip_mode != vp->vp.clip_mode) {
|
||||
nvc0->state.clip_mode = vp->vp.clip_mode;
|
||||
BEGIN_RING(chan, RING_3D(CLIP_DISTANCE_MODE), 1);
|
||||
OUT_RING (chan, vp->vp.clip_mode);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLIP_DISTANCE_MODE), 1);
|
||||
PUSH_DATA (push, vp->vp.clip_mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_blend(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
WAIT_RING(chan, nvc0->blend->size);
|
||||
OUT_RINGp(chan, nvc0->blend->state, nvc0->blend->size);
|
||||
PUSH_SPACE(push, nvc0->blend->size);
|
||||
PUSH_DATAp(push, nvc0->blend->state, nvc0->blend->size);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_zsa(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
WAIT_RING(chan, nvc0->zsa->size);
|
||||
OUT_RINGp(chan, nvc0->zsa->state, nvc0->zsa->size);
|
||||
PUSH_SPACE(push, nvc0->zsa->size);
|
||||
PUSH_DATAp(push, nvc0->zsa->state, nvc0->zsa->size);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_rasterizer(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
WAIT_RING(chan, nvc0->rast->size);
|
||||
OUT_RINGp(chan, nvc0->rast->state, nvc0->rast->size);
|
||||
PUSH_SPACE(push, nvc0->rast->size);
|
||||
PUSH_DATAp(push, nvc0->rast->state, nvc0->rast->size);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_constbufs_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nouveau_bo *bo;
|
||||
unsigned s;
|
||||
|
||||
|
|
@ -377,8 +365,8 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
|
|||
|
||||
res = nv04_resource(nvc0->constbuf[s][i]);
|
||||
if (!res) {
|
||||
BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
|
||||
OUT_RING (chan, (i << 4) | 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 0);
|
||||
if (i == 0)
|
||||
nvc0->state.uniform_buffer_bound[s] = 0;
|
||||
continue;
|
||||
|
|
@ -409,17 +397,15 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
|
|||
}
|
||||
|
||||
if (bo != nvc0->screen->uniforms)
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_CONSTANT, res,
|
||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
|
||||
|
||||
if (rebind) {
|
||||
MARK_RING (chan, 4, 2);
|
||||
BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
|
||||
OUT_RING (chan, align(res->base.width0, 0x100));
|
||||
OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
|
||||
BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
|
||||
OUT_RING (chan, (i << 4) | 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
|
||||
PUSH_DATA (push, align(res->base.width0, 0x100));
|
||||
PUSH_DATAh(push, bo->offset + base);
|
||||
PUSH_DATA (push, bo->offset + base);
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 1);
|
||||
}
|
||||
|
||||
if (words)
|
||||
|
|
@ -433,7 +419,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
|
|||
static void
|
||||
nvc0_validate_sample_mask(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
unsigned mask[4] =
|
||||
{
|
||||
|
|
@ -443,19 +429,19 @@ nvc0_validate_sample_mask(struct nvc0_context *nvc0)
|
|||
nvc0->sample_mask & 0xffff
|
||||
};
|
||||
|
||||
BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
|
||||
OUT_RING (chan, mask[0]);
|
||||
OUT_RING (chan, mask[1]);
|
||||
OUT_RING (chan, mask[2]);
|
||||
OUT_RING (chan, mask[3]);
|
||||
BEGIN_RING(chan, RING_3D(SAMPLE_SHADING), 1);
|
||||
OUT_RING (chan, 0x01);
|
||||
BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4);
|
||||
PUSH_DATA (push, mask[0]);
|
||||
PUSH_DATA (push, mask[1]);
|
||||
PUSH_DATA (push, mask[2]);
|
||||
PUSH_DATA (push, mask[3]);
|
||||
BEGIN_NVC0(push, NVC0_3D(SAMPLE_SHADING), 1);
|
||||
PUSH_DATA (push, 0x01);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_validate_derived_1(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
boolean early_z;
|
||||
boolean rasterizer_discard;
|
||||
|
||||
|
|
@ -463,7 +449,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0)
|
|||
|
||||
if (early_z != nvc0->state.early_z) {
|
||||
nvc0->state.early_z = early_z;
|
||||
IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z);
|
||||
IMMED_NVC0(push, NVC0_3D(EARLY_FRAGMENT_TESTS), early_z);
|
||||
}
|
||||
|
||||
rasterizer_discard = (!nvc0->fragprog || !nvc0->fragprog->hdr[18]) &&
|
||||
|
|
@ -473,7 +459,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0)
|
|||
|
||||
if (rasterizer_discard != nvc0->state.rasterizer_discard) {
|
||||
nvc0->state.rasterizer_discard = rasterizer_discard;
|
||||
IMMED_RING(chan, RING_3D(RASTERIZE_ENABLE), !rasterizer_discard);
|
||||
IMMED_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), !rasterizer_discard);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -534,6 +520,7 @@ static struct state_validate {
|
|||
{ nvc0_validate_textures, NVC0_NEW_TEXTURES },
|
||||
{ nvc0_validate_samplers, NVC0_NEW_SAMPLERS },
|
||||
{ nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS },
|
||||
{ nvc0_idxbuf_validate, NVC0_NEW_IDXBUF },
|
||||
{ nvc0_tfb_validate, NVC0_NEW_TFB_TARGETS | NVC0_NEW_GMTYPROG }
|
||||
};
|
||||
#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
|
||||
|
|
@ -542,6 +529,7 @@ boolean
|
|||
nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
|
||||
{
|
||||
uint32_t state_mask;
|
||||
int ret;
|
||||
unsigned i;
|
||||
|
||||
if (nvc0->screen->cur_ctx != nvc0)
|
||||
|
|
@ -557,11 +545,17 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
|
|||
validate->func(nvc0);
|
||||
}
|
||||
nvc0->dirty &= ~state_mask;
|
||||
|
||||
nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, FALSE);
|
||||
}
|
||||
|
||||
MARK_RING(nvc0->screen->base.channel, words, 0);
|
||||
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx_3d);
|
||||
ret = nouveau_pushbuf_validate(nvc0->base.pushbuf);
|
||||
if (unlikely(ret))
|
||||
return FALSE;
|
||||
|
||||
nvc0_bufctx_emit_relocs(nvc0);
|
||||
if (unlikely(nvc0->state.flushed))
|
||||
nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@
|
|||
#include "pipe/p_state.h"
|
||||
|
||||
#define SB_BEGIN_3D(so, m, s) \
|
||||
(so)->state[(so)->size++] = \
|
||||
(0x2 << 28) | ((s) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
|
||||
(so)->state[(so)->size++] = NVC0_FIFO_PKHDR_SQ(NVC0_3D(m), s)
|
||||
|
||||
#define SB_IMMED_3D(so, m, d) \
|
||||
(so)->state[(so)->size++] = \
|
||||
(0x8 << 28) | ((d) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
|
||||
(so)->state[(so)->size++] = NVC0_FIFO_PKHDR_IL(NVC0_3D(m), d)
|
||||
|
||||
#define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
|
||||
|
||||
|
|
|
|||
|
|
@ -73,14 +73,13 @@ nvc0_2d_format(enum pipe_format format)
|
|||
}
|
||||
|
||||
static int
|
||||
nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
|
||||
nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
|
||||
struct nv50_miptree *mt, unsigned level, unsigned layer)
|
||||
{
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t width, height, depth;
|
||||
uint32_t format;
|
||||
uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
|
||||
uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
|
||||
uint32_t offset = mt->level[level].offset;
|
||||
|
||||
format = nvc0_2d_format(mt->base.base.format);
|
||||
|
|
@ -106,44 +105,44 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
|
|||
layer = 0;
|
||||
}
|
||||
|
||||
if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
|
||||
BEGIN_RING(chan, RING_2D_(mthd), 2);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
|
||||
OUT_RING (chan, mt->level[level].pitch);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RELOCh(chan, bo, offset, flags);
|
||||
OUT_RELOCl(chan, bo, offset, flags);
|
||||
if (nouveau_bo_memtype(bo)) {
|
||||
BEGIN_NVC0(push, SUBC_2D(mthd), 2);
|
||||
PUSH_DATA (push, format);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, SUBC_2D(mthd + 0x14), 5);
|
||||
PUSH_DATA (push, mt->level[level].pitch);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
} else {
|
||||
BEGIN_RING(chan, RING_2D_(mthd), 5);
|
||||
OUT_RING (chan, format);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, mt->level[level].tile_mode);
|
||||
OUT_RING (chan, depth);
|
||||
OUT_RING (chan, layer);
|
||||
BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
OUT_RELOCh(chan, bo, offset, flags);
|
||||
OUT_RELOCl(chan, bo, offset, flags);
|
||||
BEGIN_NVC0(push, SUBC_2D(mthd), 5);
|
||||
PUSH_DATA (push, format);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, mt->level[level].tile_mode);
|
||||
PUSH_DATA (push, depth);
|
||||
PUSH_DATA (push, layer);
|
||||
BEGIN_NVC0(push, SUBC_2D(mthd + 0x18), 4);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (dst) {
|
||||
BEGIN_RING(chan, RING_2D_(NVC0_2D_CLIP_X), 4);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, width);
|
||||
OUT_RING (chan, height);
|
||||
BEGIN_NVC0(push, SUBC_2D(NVC0_2D_CLIP_X), 4);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
|
||||
nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push,
|
||||
struct nv50_miptree *dst, unsigned dst_level,
|
||||
unsigned dx, unsigned dy, unsigned dz,
|
||||
struct nv50_miptree *src, unsigned src_level,
|
||||
|
|
@ -158,15 +157,15 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
|
|||
int ret;
|
||||
uint32_t ctrl = 0x00;
|
||||
|
||||
ret = MARK_RING(chan, 2 * 16 + 32, 4);
|
||||
ret = PUSH_SPACE(push, 2 * 16 + 32);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvc0_2d_texture_set(chan, 1, dst, dst_level, dz);
|
||||
ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvc0_2d_texture_set(chan, 0, src, src_level, sz);
|
||||
ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -175,23 +174,23 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
|
|||
ctrl = 0x11;
|
||||
|
||||
/* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */
|
||||
BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
|
||||
OUT_RING (chan, ctrl);
|
||||
BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
|
||||
OUT_RING (chan, dx << dst->ms_x);
|
||||
OUT_RING (chan, dy << dst->ms_y);
|
||||
OUT_RING (chan, w << dst->ms_x);
|
||||
OUT_RING (chan, h << dst->ms_y);
|
||||
BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
|
||||
OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
|
||||
BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sx << src->ms_x);
|
||||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, sy << src->ms_x);
|
||||
BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1);
|
||||
PUSH_DATA (push, ctrl);
|
||||
BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4);
|
||||
PUSH_DATA (push, dx << dst->ms_x);
|
||||
PUSH_DATA (push, dy << dst->ms_y);
|
||||
PUSH_DATA (push, w << dst->ms_x);
|
||||
PUSH_DATA (push, h << dst->ms_y);
|
||||
BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
|
||||
PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
|
||||
BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, sx << src->ms_x);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, sy << src->ms_x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -203,7 +202,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
|
|||
struct pipe_resource *src, unsigned src_level,
|
||||
const struct pipe_box *src_box)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0_context(pipe)->screen;
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
int ret;
|
||||
boolean m2mf;
|
||||
unsigned dst_layer = dstz, src_layer = src_box->z;
|
||||
|
|
@ -234,7 +233,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
|
|||
src_box->x, src_box->y, src_box->z);
|
||||
|
||||
for (i = 0; i < src_box->depth; ++i) {
|
||||
nvc0_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
|
||||
nvc0_m2mf_transfer_rect(nvc0, &drect, &srect, nx, ny);
|
||||
|
||||
if (nv50_miptree(dst)->layout_3d)
|
||||
drect.z++;
|
||||
|
|
@ -252,16 +251,22 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
|
|||
assert(nvc0_2d_format_faithful(src->format));
|
||||
assert(nvc0_2d_format_faithful(dst->format));
|
||||
|
||||
BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
|
||||
BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
|
||||
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
|
||||
nouveau_pushbuf_validate(nvc0->base.pushbuf);
|
||||
|
||||
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
|
||||
ret = nvc0_2d_texture_do_copy(screen->base.channel,
|
||||
ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf,
|
||||
nv50_miptree(dst), dst_level,
|
||||
dstx, dsty, dst_layer,
|
||||
nv50_miptree(src), src_level,
|
||||
src_box->x, src_box->y, src_layer,
|
||||
src_box->width, src_box->height);
|
||||
if (ret)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
nouveau_bufctx_reset(nvc0->bufctx, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -271,69 +276,65 @@ nvc0_clear_render_target(struct pipe_context *pipe,
|
|||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct nvc0_context *nv50 = nvc0_context(pipe);
|
||||
struct nvc0_screen *screen = nv50->screen;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nv50_surface *sf = nv50_surface(dst);
|
||||
struct nv04_resource *res = nv04_resource(sf->base.texture);
|
||||
unsigned z;
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
|
||||
OUT_RINGf (chan, color->f[0]);
|
||||
OUT_RINGf (chan, color->f[1]);
|
||||
OUT_RINGf (chan, color->f[2]);
|
||||
OUT_RINGf (chan, color->f[3]);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
|
||||
PUSH_DATAf(push, color->f[0]);
|
||||
PUSH_DATAf(push, color->f[1]);
|
||||
PUSH_DATAf(push, color->f[2]);
|
||||
PUSH_DATAf(push, color->f[3]);
|
||||
|
||||
if (MARK_RING(chan, 18, 2))
|
||||
return;
|
||||
BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
PUSH_DATA (push, ( width << 16) | dstx);
|
||||
PUSH_DATA (push, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
OUT_RING (chan, ( width << 16) | dstx);
|
||||
OUT_RING (chan, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 9);
|
||||
OUT_RESRCh(chan, res, sf->offset, NOUVEAU_BO_WR);
|
||||
OUT_RESRCl(chan, res, sf->offset, NOUVEAU_BO_WR);
|
||||
if (likely(nouveau_bo_tile_layout(res->bo))) {
|
||||
BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9);
|
||||
PUSH_DATAh(push, res->address + sf->offset);
|
||||
PUSH_DATA (push, res->address + sf->offset);
|
||||
if (likely(nouveau_bo_memtype(res->bo))) {
|
||||
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||
|
||||
OUT_RING(chan, sf->width);
|
||||
OUT_RING(chan, sf->height);
|
||||
OUT_RING(chan, nvc0_format_table[dst->format].rt);
|
||||
OUT_RING(chan, (mt->layout_3d << 16) |
|
||||
PUSH_DATA(push, sf->width);
|
||||
PUSH_DATA(push, sf->height);
|
||||
PUSH_DATA(push, nvc0_format_table[dst->format].rt);
|
||||
PUSH_DATA(push, (mt->layout_3d << 16) |
|
||||
mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING(chan, dst->u.tex.first_layer + sf->depth);
|
||||
OUT_RING(chan, mt->layer_stride >> 2);
|
||||
OUT_RING(chan, dst->u.tex.first_layer);
|
||||
PUSH_DATA(push, dst->u.tex.first_layer + sf->depth);
|
||||
PUSH_DATA(push, mt->layer_stride >> 2);
|
||||
PUSH_DATA(push, dst->u.tex.first_layer);
|
||||
} else {
|
||||
if (res->base.target == PIPE_BUFFER) {
|
||||
OUT_RING(chan, 262144);
|
||||
OUT_RING(chan, 1);
|
||||
PUSH_DATA(push, 262144);
|
||||
PUSH_DATA(push, 1);
|
||||
} else {
|
||||
OUT_RING(chan, nv50_miptree(&res->base)->level[0].pitch);
|
||||
OUT_RING(chan, sf->height);
|
||||
PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch);
|
||||
PUSH_DATA(push, sf->height);
|
||||
}
|
||||
OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
|
||||
OUT_RING(chan, 1 << 12);
|
||||
OUT_RING(chan, 1);
|
||||
OUT_RING(chan, 0);
|
||||
OUT_RING(chan, 0);
|
||||
PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
|
||||
PUSH_DATA(push, 1 << 12);
|
||||
PUSH_DATA(push, 1);
|
||||
PUSH_DATA(push, 0);
|
||||
PUSH_DATA(push, 0);
|
||||
|
||||
IMMED_RING(chan, RING_3D(ZETA_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);
|
||||
|
||||
/* tiled textures don't have to be fenced, they're not mapped directly */
|
||||
nvc0_resource_fence(res, NOUVEAU_BO_WR);
|
||||
}
|
||||
|
||||
for (z = 0; z < sf->depth; ++z) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, 0x3c |
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, 0x3c |
|
||||
(z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
|
||||
}
|
||||
|
||||
nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
|
||||
nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -345,57 +346,52 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
|
|||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct nvc0_context *nv50 = nvc0_context(pipe);
|
||||
struct nvc0_screen *screen = nv50->screen;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||
struct nv50_surface *sf = nv50_surface(dst);
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
uint32_t mode = 0;
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
|
||||
unsigned z;
|
||||
|
||||
if (clear_flags & PIPE_CLEAR_DEPTH) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
|
||||
OUT_RINGf (chan, depth);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
|
||||
PUSH_DATAf(push, depth);
|
||||
mode |= NVC0_3D_CLEAR_BUFFERS_Z;
|
||||
}
|
||||
|
||||
if (clear_flags & PIPE_CLEAR_STENCIL) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
|
||||
OUT_RING (chan, stencil & 0xff);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
|
||||
PUSH_DATA (push, stencil & 0xff);
|
||||
mode |= NVC0_3D_CLEAR_BUFFERS_S;
|
||||
}
|
||||
|
||||
if (MARK_RING(chan, 20, 2))
|
||||
return;
|
||||
BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
PUSH_DATA (push, ( width << 16) | dstx);
|
||||
PUSH_DATA (push, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
|
||||
OUT_RING (chan, ( width << 16) | dstx);
|
||||
OUT_RING (chan, (height << 16) | dsty);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RING (chan, nvc0_format_table[dst->format].rt);
|
||||
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
OUT_RING (chan, mt->layer_stride >> 2);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
|
||||
OUT_RING (chan, sf->width);
|
||||
OUT_RING (chan, sf->height);
|
||||
OUT_RING (chan, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
|
||||
BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1);
|
||||
OUT_RING (chan, dst->u.tex.first_layer);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
PUSH_DATAh(push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, nvc0_format_table[dst->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
|
||||
PUSH_DATA (push, sf->width);
|
||||
PUSH_DATA (push, sf->height);
|
||||
PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
|
||||
BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
|
||||
PUSH_DATA (push, dst->u.tex.first_layer);
|
||||
|
||||
for (z = 0; z < sf->depth; ++z) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, mode |
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, mode |
|
||||
(z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
|
||||
}
|
||||
|
||||
nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
|
||||
nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -404,7 +400,7 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
|
|||
double depth, unsigned stencil)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
|
||||
unsigned i;
|
||||
uint32_t mode = 0;
|
||||
|
|
@ -414,34 +410,34 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
|
|||
return;
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
|
||||
OUT_RINGf (chan, color->f[0]);
|
||||
OUT_RINGf (chan, color->f[1]);
|
||||
OUT_RINGf (chan, color->f[2]);
|
||||
OUT_RINGf (chan, color->f[3]);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
|
||||
PUSH_DATAf(push, color->f[0]);
|
||||
PUSH_DATAf(push, color->f[1]);
|
||||
PUSH_DATAf(push, color->f[2]);
|
||||
PUSH_DATAf(push, color->f[3]);
|
||||
mode =
|
||||
NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G |
|
||||
NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A;
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_DEPTH) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
|
||||
OUT_RING (chan, fui(depth));
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
|
||||
PUSH_DATA (push, fui(depth));
|
||||
mode |= NVC0_3D_CLEAR_BUFFERS_Z;
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_STENCIL) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
|
||||
OUT_RING (chan, stencil & 0xff);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
|
||||
PUSH_DATA (push, stencil & 0xff);
|
||||
mode |= NVC0_3D_CLEAR_BUFFERS_S;
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, mode);
|
||||
|
||||
for (i = 1; i < fb->nr_cbufs; i++) {
|
||||
BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
|
||||
OUT_RING (chan, (i << 6) | 0x3c);
|
||||
BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
|
||||
PUSH_DATA (push, (i << 6) | 0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,42 +705,42 @@ nvc0_blit_set_src(struct nvc0_context *nvc0,
|
|||
static void
|
||||
nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit)
|
||||
{
|
||||
struct nouveau_channel *chan = blit->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
|
||||
|
||||
/* TODO: maybe make this a MACRO (if we need more logic) ? */
|
||||
|
||||
/* blend state */
|
||||
BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1);
|
||||
OUT_RING (chan, blit->color_mask);
|
||||
BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
IMMED_RING(chan, RING_3D(LOGIC_OP_ENABLE), 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1);
|
||||
PUSH_DATA (push, blit->color_mask);
|
||||
BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0);
|
||||
|
||||
/* rasterizer state */
|
||||
BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
|
||||
OUT_RING (chan, 0);
|
||||
IMMED_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 0);
|
||||
BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
|
||||
OUT_RING (chan, 0xffff);
|
||||
OUT_RING (chan, 0xffff);
|
||||
OUT_RING (chan, 0xffff);
|
||||
OUT_RING (chan, 0xffff);
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 1);
|
||||
OUT_RING (chan, NVC0_3D_POLYGON_MODE_FRONT_FILL);
|
||||
BEGIN_RING(chan, RING_3D(POLYGON_MODE_BACK), 1);
|
||||
OUT_RING (chan, NVC0_3D_POLYGON_MODE_BACK_FILL);
|
||||
IMMED_RING(chan, RING_3D(POLYGON_SMOOTH_ENABLE), 0);
|
||||
IMMED_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
|
||||
IMMED_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 0);
|
||||
IMMED_RING(chan, RING_3D(CULL_FACE_ENABLE), 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
PUSH_DATA (push, 0xffff);
|
||||
BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_FRONT), 1);
|
||||
PUSH_DATA (push, NVC0_3D_POLYGON_MODE_FRONT_FILL);
|
||||
BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_BACK), 1);
|
||||
PUSH_DATA (push, NVC0_3D_POLYGON_MODE_BACK_FILL);
|
||||
IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0);
|
||||
|
||||
/* zsa state */
|
||||
IMMED_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 0);
|
||||
IMMED_RING(chan, RING_3D(STENCIL_ENABLE), 0);
|
||||
IMMED_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0);
|
||||
|
||||
/* disable transform feedback */
|
||||
IMMED_RING(chan, RING_3D(TFB_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -835,7 +831,7 @@ nvc0_resource_resolve(struct pipe_context *pipe,
|
|||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nvc0_screen *screen = nvc0->screen;
|
||||
struct nvc0_blitctx *blit = screen->blitctx;
|
||||
struct nouveau_channel *chan = screen->base.channel;
|
||||
struct nouveau_pushbuf *push = screen->base.pushbuf;
|
||||
struct pipe_resource *src = info->src.res;
|
||||
struct pipe_resource *dst = info->dst.res;
|
||||
float x0, x1, y0, y1;
|
||||
|
|
@ -878,11 +874,11 @@ nvc0_resource_resolve(struct pipe_context *pipe,
|
|||
y0 *= (float)(1 << nv50_miptree(src)->ms_y);
|
||||
y1 *= (float)(1 << nv50_miptree(src)->ms_y);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SP_START_ID(5)), 1);
|
||||
OUT_RING (chan,
|
||||
BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1);
|
||||
PUSH_DATA (push,
|
||||
blit->fp.code_base + blit->fp_offset);
|
||||
|
||||
IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
|
||||
|
||||
/* Draw a large triangle in screen coordinates covering the whole
|
||||
* render target, with scissors defining the destination region.
|
||||
|
|
@ -890,43 +886,43 @@ nvc0_resource_resolve(struct pipe_context *pipe,
|
|||
* arranged in a way to yield the desired offset and scale.
|
||||
*/
|
||||
|
||||
BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
|
||||
OUT_RING (chan, (info->dst.x1 << 16) | info->dst.x0);
|
||||
OUT_RING (chan, (info->dst.y1 << 16) | info->dst.y0);
|
||||
BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
|
||||
PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0);
|
||||
PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0);
|
||||
|
||||
IMMED_RING(chan, RING_3D(VERTEX_BEGIN_GL),
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL),
|
||||
NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
|
||||
OUT_RING (chan, 0x74201);
|
||||
OUT_RINGf (chan, x0);
|
||||
OUT_RINGf (chan, y0);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
|
||||
OUT_RING (chan, 0x74200);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
|
||||
OUT_RING (chan, 0x74201);
|
||||
OUT_RINGf (chan, x1);
|
||||
OUT_RINGf (chan, y0);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
|
||||
OUT_RING (chan, 0x74200);
|
||||
OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
|
||||
OUT_RING (chan, 0x74201);
|
||||
OUT_RINGf (chan, x0);
|
||||
OUT_RINGf (chan, y1);
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
|
||||
OUT_RING (chan, 0x74200);
|
||||
OUT_RINGf (chan, 0.0f);
|
||||
OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
|
||||
PUSH_DATA (push, 0x74201);
|
||||
PUSH_DATAf(push, x0);
|
||||
PUSH_DATAf(push, y0);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
|
||||
PUSH_DATA (push, 0x74200);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
|
||||
PUSH_DATA (push, 0x74201);
|
||||
PUSH_DATAf(push, x1);
|
||||
PUSH_DATAf(push, y0);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
|
||||
PUSH_DATA (push, 0x74200);
|
||||
PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
|
||||
PUSH_DATA (push, 0x74201);
|
||||
PUSH_DATAf(push, x0);
|
||||
PUSH_DATAf(push, y1);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
|
||||
PUSH_DATA (push, 0x74200);
|
||||
PUSH_DATAf(push, 0.0f);
|
||||
PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
|
||||
|
||||
IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
|
||||
|
||||
/* re-enable normally constant state */
|
||||
|
||||
IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
|
||||
|
||||
nvc0_blitctx_post_blit(nvc0, blit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
const struct pipe_sampler_view *templ)
|
||||
{
|
||||
const struct util_format_description *desc;
|
||||
uint64_t address;
|
||||
uint32_t *tic;
|
||||
uint32_t swz[4];
|
||||
uint32_t depth;
|
||||
|
|
@ -66,6 +67,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
view = MALLOC_STRUCT(nv50_tic_entry);
|
||||
if (!view)
|
||||
return NULL;
|
||||
mt = nv50_miptree(texture);
|
||||
|
||||
view->pipe = *templ;
|
||||
view->pipe.reference.count = 1;
|
||||
|
|
@ -80,8 +82,6 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
|
||||
desc = util_format_description(view->pipe.format);
|
||||
|
||||
/* TIC[0] */
|
||||
|
||||
tic[0] = nvc0_format_table[view->pipe.format].tic;
|
||||
|
||||
tex_int = util_format_is_pure_integer(view->pipe.format);
|
||||
|
|
@ -96,26 +96,24 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
(swz[2] << NV50_TIC_0_MAPB__SHIFT) |
|
||||
(swz[3] << NV50_TIC_0_MAPA__SHIFT);
|
||||
|
||||
tic[1] = /* mt->base.bo->offset; */ 0;
|
||||
tic[2] = /* mt->base.bo->offset >> 32 */ 0;
|
||||
address = mt->base.address;
|
||||
|
||||
tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
|
||||
tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER;
|
||||
|
||||
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
|
||||
tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
|
||||
|
||||
/* check for linear storage type */
|
||||
if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
|
||||
if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
|
||||
if (texture->target == PIPE_BUFFER) {
|
||||
tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
|
||||
tic[1] = /* address offset */
|
||||
address +=
|
||||
view->pipe.u.buf.first_element * desc->block.bits / 8;
|
||||
tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
|
||||
tic[3] = 0;
|
||||
tic[4] = /* width */
|
||||
view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
|
||||
tic[5] = 0;
|
||||
tic[5] = 0;
|
||||
} else {
|
||||
mt = nv50_miptree(texture);
|
||||
/* must be 2D texture without mip maps */
|
||||
tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
|
||||
if (texture->target != PIPE_TEXTURE_RECT)
|
||||
|
|
@ -126,24 +124,27 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
}
|
||||
tic[6] =
|
||||
tic[7] = 0;
|
||||
tic[1] = address;
|
||||
tic[2] |= address >> 32;
|
||||
return &view->pipe;
|
||||
}
|
||||
mt = nv50_miptree(texture);
|
||||
|
||||
if (mt->base.base.target != PIPE_TEXTURE_RECT)
|
||||
tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
|
||||
|
||||
tic[2] |=
|
||||
((mt->base.bo->tile_mode & 0x0f0) << (22 - 4)) |
|
||||
((mt->base.bo->tile_mode & 0xf00) << (25 - 8));
|
||||
((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
|
||||
((mt->level[0].tile_mode & 0xf00) << (25 - 8));
|
||||
|
||||
depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
|
||||
|
||||
if (mt->base.base.array_size > 1) {
|
||||
/* there doesn't seem to be a base layer field in TIC */
|
||||
tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride;
|
||||
address += view->pipe.u.tex.first_layer * mt->layer_stride;
|
||||
depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
|
||||
}
|
||||
tic[1] = address;
|
||||
tic[2] |= address >> 32;
|
||||
|
||||
switch (mt->base.base.target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
|
|
@ -205,7 +206,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
|
|||
static boolean
|
||||
nvc0_validate_tic(struct nvc0_context *nvc0, int s)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nouveau_bo *txc = nvc0->screen->txc;
|
||||
unsigned i;
|
||||
boolean need_flush = FALSE;
|
||||
|
|
@ -215,53 +216,46 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
|
|||
struct nv04_resource *res;
|
||||
|
||||
if (!tic) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
|
||||
OUT_RING (chan, (i << 1) | 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
|
||||
PUSH_DATA (push, (i << 1) | 0);
|
||||
continue;
|
||||
}
|
||||
res = nv04_resource(tic->pipe.texture);
|
||||
|
||||
if (tic->id < 0) {
|
||||
uint32_t offset = res->offset + tic->tic[1];
|
||||
|
||||
tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
|
||||
|
||||
MARK_RING (chan, 9 + 8, 4);
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
|
||||
OUT_RELOCh(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
|
||||
OUT_RING (chan, 32);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_MF(EXEC), 1);
|
||||
OUT_RING (chan, 0x100111);
|
||||
BEGIN_RING_NI(chan, RING_MF(DATA), 8);
|
||||
OUT_RING (chan, tic->tic[0]);
|
||||
OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RD);
|
||||
OUT_RELOC (chan, res->bo, offset, res->domain | NOUVEAU_BO_RD |
|
||||
NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
|
||||
OUT_RINGp (chan, &tic->tic[3], 5);
|
||||
PUSH_SPACE(push, 17);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
|
||||
PUSH_DATAh(push, txc->offset + (tic->id * 32));
|
||||
PUSH_DATA (push, txc->offset + (tic->id * 32));
|
||||
BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
|
||||
PUSH_DATA (push, 32);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
|
||||
PUSH_DATA (push, 0x100111);
|
||||
BEGIN_NIC0(push, NVC0_M2MF(DATA), 8);
|
||||
PUSH_DATAp(push, &tic->tic[0], 8);
|
||||
|
||||
need_flush = TRUE;
|
||||
} else
|
||||
if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
|
||||
BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
|
||||
OUT_RING (chan, (tic->id << 4) | 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
|
||||
PUSH_DATA (push, (tic->id << 4) | 1);
|
||||
}
|
||||
nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
|
||||
|
||||
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res,
|
||||
res->domain | NOUVEAU_BO_RD);
|
||||
BCTX_REFN(nvc0->bufctx_3d, TEX, res, RD);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
|
||||
OUT_RING (chan, (tic->id << 9) | (i << 1) | 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
|
||||
PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
|
||||
}
|
||||
for (; i < nvc0->state.num_textures[s]; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
|
||||
OUT_RING (chan, (i << 1) | 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
|
||||
PUSH_DATA (push, (i << 1) | 0);
|
||||
}
|
||||
nvc0->state.num_textures[s] = nvc0->num_textures[s];
|
||||
|
||||
|
|
@ -277,15 +271,15 @@ void nvc0_validate_textures(struct nvc0_context *nvc0)
|
|||
need_flush |= nvc0_validate_tic(nvc0, 4);
|
||||
|
||||
if (need_flush) {
|
||||
BEGIN_RING(nvc0->screen->base.channel, RING_3D(TIC_FLUSH), 1);
|
||||
OUT_RING (nvc0->screen->base.channel, 0);
|
||||
BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
|
||||
PUSH_DATA (nvc0->base.pushbuf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
unsigned i;
|
||||
boolean need_flush = FALSE;
|
||||
|
||||
|
|
@ -293,8 +287,8 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
|
|||
struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
|
||||
|
||||
if (!tsc) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
|
||||
OUT_RING (chan, (i << 4) | 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 0);
|
||||
continue;
|
||||
}
|
||||
if (tsc->id < 0) {
|
||||
|
|
@ -307,12 +301,12 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
|
|||
}
|
||||
nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
|
||||
OUT_RING (chan, (tsc->id << 12) | (i << 4) | 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
|
||||
PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
|
||||
}
|
||||
for (; i < nvc0->state.num_samplers[s]; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
|
||||
OUT_RING (chan, (i << 4) | 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 0);
|
||||
}
|
||||
nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
|
||||
|
||||
|
|
@ -328,7 +322,7 @@ void nvc0_validate_samplers(struct nvc0_context *nvc0)
|
|||
need_flush |= nvc0_validate_tsc(nvc0, 4);
|
||||
|
||||
if (need_flush) {
|
||||
BEGIN_RING(nvc0->screen->base.channel, RING_3D(TSC_FLUSH), 1);
|
||||
OUT_RING (nvc0->screen->base.channel, 0);
|
||||
BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
|
||||
PUSH_DATA (nvc0->base.pushbuf, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@ struct nvc0_transfer {
|
|||
};
|
||||
|
||||
void
|
||||
nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
||||
nvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
|
||||
const struct nv50_m2mf_rect *dst,
|
||||
const struct nv50_m2mf_rect *src,
|
||||
uint32_t nblocksx, uint32_t nblocksy)
|
||||
{
|
||||
struct nouveau_channel *chan = nouveau_screen(pscreen)->channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nouveau_bufctx *bctx = nvc0->bufctx;
|
||||
const int cpp = dst->cpp;
|
||||
uint32_t src_ofst = src->base;
|
||||
uint32_t dst_ofst = dst->base;
|
||||
|
|
@ -30,34 +31,39 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
|||
|
||||
assert(dst->cpp == src->cpp);
|
||||
|
||||
if (nouveau_bo_tile_layout(src->bo)) {
|
||||
BEGIN_RING(chan, RING_MF(TILING_MODE_IN), 5);
|
||||
OUT_RING (chan, src->tile_mode);
|
||||
OUT_RING (chan, src->width * cpp);
|
||||
OUT_RING (chan, src->height);
|
||||
OUT_RING (chan, src->depth);
|
||||
OUT_RING (chan, src->z);
|
||||
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
|
||||
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
if (nouveau_bo_memtype(src->bo)) {
|
||||
BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
|
||||
PUSH_DATA (push, src->tile_mode);
|
||||
PUSH_DATA (push, src->width * cpp);
|
||||
PUSH_DATA (push, src->height);
|
||||
PUSH_DATA (push, src->depth);
|
||||
PUSH_DATA (push, src->z);
|
||||
} else {
|
||||
src_ofst += src->y * src->pitch + src->x * cpp;
|
||||
|
||||
BEGIN_RING(chan, RING_MF(PITCH_IN), 1);
|
||||
OUT_RING (chan, src->width * cpp);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1);
|
||||
PUSH_DATA (push, src->width * cpp);
|
||||
|
||||
exec |= NVC0_M2MF_EXEC_LINEAR_IN;
|
||||
}
|
||||
|
||||
if (nouveau_bo_tile_layout(dst->bo)) {
|
||||
BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5);
|
||||
OUT_RING (chan, dst->tile_mode);
|
||||
OUT_RING (chan, dst->width * cpp);
|
||||
OUT_RING (chan, dst->height);
|
||||
OUT_RING (chan, dst->depth);
|
||||
OUT_RING (chan, dst->z);
|
||||
if (nouveau_bo_memtype(dst->bo)) {
|
||||
BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5);
|
||||
PUSH_DATA (push, dst->tile_mode);
|
||||
PUSH_DATA (push, dst->width * cpp);
|
||||
PUSH_DATA (push, dst->height);
|
||||
PUSH_DATA (push, dst->depth);
|
||||
PUSH_DATA (push, dst->z);
|
||||
} else {
|
||||
dst_ofst += dst->y * dst->pitch + dst->x * cpp;
|
||||
|
||||
BEGIN_RING(chan, RING_MF(PITCH_OUT), 1);
|
||||
OUT_RING (chan, dst->width * cpp);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1);
|
||||
PUSH_DATA (push, dst->width * cpp);
|
||||
|
||||
exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
|
||||
}
|
||||
|
|
@ -65,41 +71,41 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
|
|||
while (height) {
|
||||
int line_count = height > 2047 ? 2047 : height;
|
||||
|
||||
MARK_RING (chan, 17, 4);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
|
||||
PUSH_DATAh(push, src->bo->offset + src_ofst);
|
||||
PUSH_DATA (push, src->bo->offset + src_ofst);
|
||||
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
|
||||
OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
|
||||
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
|
||||
OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
|
||||
PUSH_DATAh(push, dst->bo->offset + dst_ofst);
|
||||
PUSH_DATA (push, dst->bo->offset + dst_ofst);
|
||||
|
||||
if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) {
|
||||
BEGIN_RING(chan, RING_MF(TILING_POSITION_IN_X), 2);
|
||||
OUT_RING (chan, src->x * cpp);
|
||||
OUT_RING (chan, sy);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2);
|
||||
PUSH_DATA (push, src->x * cpp);
|
||||
PUSH_DATA (push, sy);
|
||||
} else {
|
||||
src_ofst += line_count * src->pitch;
|
||||
}
|
||||
if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) {
|
||||
BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2);
|
||||
OUT_RING (chan, dst->x * cpp);
|
||||
OUT_RING (chan, dy);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2);
|
||||
PUSH_DATA (push, dst->x * cpp);
|
||||
PUSH_DATA (push, dy);
|
||||
} else {
|
||||
dst_ofst += line_count * dst->pitch;
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
|
||||
OUT_RING (chan, nblocksx * cpp);
|
||||
OUT_RING (chan, line_count);
|
||||
BEGIN_RING(chan, RING_MF(EXEC), 1);
|
||||
OUT_RING (chan, exec);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
|
||||
PUSH_DATA (push, nblocksx * cpp);
|
||||
PUSH_DATA (push, line_count);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
|
||||
PUSH_DATA (push, exec);
|
||||
|
||||
height -= line_count;
|
||||
sy += line_count;
|
||||
dy += line_count;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -107,36 +113,44 @@ nvc0_m2mf_push_linear(struct nouveau_context *nv,
|
|||
struct nouveau_bo *dst, unsigned offset, unsigned domain,
|
||||
unsigned size, const void *data)
|
||||
{
|
||||
struct nouveau_channel *chan = nv->screen->channel;
|
||||
struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
uint32_t *src = (uint32_t *)data;
|
||||
unsigned count = (size + 3) / 4;
|
||||
|
||||
nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
|
||||
nouveau_pushbuf_bufctx(push, nvc0->bufctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
while (count) {
|
||||
unsigned nr;
|
||||
|
||||
MARK_RING (chan, 16, 2);
|
||||
|
||||
nr = AVAIL_RING(chan) - 9;
|
||||
nr = MIN2(count, nr);
|
||||
if (!PUSH_SPACE(push, 16))
|
||||
break;
|
||||
nr = PUSH_AVAIL(push);
|
||||
assert(nr >= 16);
|
||||
nr = MIN2(count, nr - 9);
|
||||
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
|
||||
OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
|
||||
OUT_RING (chan, nr * 4);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_MF(EXEC), 1);
|
||||
OUT_RING (chan, 0x100111);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
|
||||
PUSH_DATAh(push, dst->offset + offset);
|
||||
PUSH_DATA (push, dst->offset + offset);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
|
||||
PUSH_DATA (push, nr * 4);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
|
||||
PUSH_DATA (push, 0x100111);
|
||||
|
||||
/* must not be interrupted (trap on QUERY fence, 0x50 works however) */
|
||||
BEGIN_RING_NI(chan, RING_MF(DATA), nr);
|
||||
OUT_RINGp (chan, src, nr);
|
||||
BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);
|
||||
PUSH_DATAp(push, src, nr);
|
||||
|
||||
count -= nr;
|
||||
src += nr;
|
||||
offset += nr * 4;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(nvc0->bufctx, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -145,89 +159,38 @@ nvc0_m2mf_copy_linear(struct nouveau_context *nv,
|
|||
struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
|
||||
unsigned size)
|
||||
{
|
||||
struct nouveau_channel *chan = nv->screen->channel;
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
|
||||
|
||||
nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
|
||||
nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
while (size) {
|
||||
unsigned bytes = MIN2(size, 1 << 17);
|
||||
|
||||
MARK_RING (chan, 11, 4);
|
||||
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
|
||||
OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
|
||||
OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
|
||||
OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
|
||||
BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
|
||||
OUT_RING (chan, bytes);
|
||||
OUT_RING (chan, 1);
|
||||
BEGIN_RING(chan, RING_MF(EXEC), 1);
|
||||
OUT_RING (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
|
||||
BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
|
||||
PUSH_DATAh(push, dst->offset + dstoff);
|
||||
PUSH_DATA (push, dst->offset + dstoff);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
|
||||
PUSH_DATAh(push, src->offset + srcoff);
|
||||
PUSH_DATA (push, src->offset + srcoff);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
|
||||
PUSH_DATA (push, bytes);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
|
||||
PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
|
||||
NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT);
|
||||
|
||||
srcoff += bytes;
|
||||
dstoff += bytes;
|
||||
size -= bytes;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
nvc0_m2mf_push_rect(struct pipe_screen *pscreen,
|
||||
const struct nv50_m2mf_rect *dst,
|
||||
const void *data,
|
||||
unsigned nblocksx, unsigned nblocksy)
|
||||
{
|
||||
struct nouveau_channel *chan;
|
||||
const uint8_t *src = (const uint8_t *)data;
|
||||
const int cpp = dst->cpp;
|
||||
const int line_len = nblocksx * cpp;
|
||||
int dy = dst->y;
|
||||
|
||||
assert(nouveau_bo_tile_layout(dst->bo));
|
||||
|
||||
BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5);
|
||||
OUT_RING (chan, dst->tile_mode);
|
||||
OUT_RING (chan, dst->width * cpp);
|
||||
OUT_RING (chan, dst->height);
|
||||
OUT_RING (chan, dst->depth);
|
||||
OUT_RING (chan, dst->z);
|
||||
|
||||
while (nblocksy) {
|
||||
int line_count, words;
|
||||
int size = MIN2(AVAIL_RING(chan), NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
if (size < (12 + words)) {
|
||||
FIRE_RING(chan);
|
||||
continue;
|
||||
}
|
||||
line_count = (size * 4) / line_len;
|
||||
words = (line_count * line_len + 3) / 4;
|
||||
|
||||
BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
|
||||
OUT_RELOCh(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR);
|
||||
|
||||
BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2);
|
||||
OUT_RING (chan, dst->x * cpp);
|
||||
OUT_RING (chan, dy);
|
||||
BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
|
||||
OUT_RING (chan, line_len);
|
||||
OUT_RING (chan, line_count);
|
||||
BEGIN_RING(chan, RING_MF(EXEC), 1);
|
||||
OUT_RING (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
|
||||
NVC0_M2MF_EXEC_PUSH | NVC0_M2MF_EXEC_LINEAR_IN);
|
||||
|
||||
BEGIN_RING_NI(chan, RING_MF(DATA), words);
|
||||
OUT_RINGp (chan, src, words);
|
||||
|
||||
dy += line_count;
|
||||
src += line_len * line_count;
|
||||
nblocksy -= line_count;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct pipe_transfer *
|
||||
nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
||||
struct pipe_resource *res,
|
||||
|
|
@ -236,7 +199,6 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
const struct pipe_box *box)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pctx);
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nouveau_device *dev = nvc0->screen->base.device;
|
||||
struct nv50_miptree *mt = nv50_miptree(res);
|
||||
struct nvc0_transfer *tx;
|
||||
|
|
@ -273,7 +235,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
size = tx->base.layer_stride;
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
|
||||
size * tx->nlayers, &tx->rect[1].bo);
|
||||
size * tx->nlayers, NULL, &tx->rect[1].bo);
|
||||
if (ret) {
|
||||
FREE(tx);
|
||||
return NULL;
|
||||
|
|
@ -291,7 +253,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
|
|||
unsigned z = tx->rect[0].z;
|
||||
unsigned i;
|
||||
for (i = 0; i < tx->nlayers; ++i) {
|
||||
nvc0_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
|
||||
nvc0_m2mf_transfer_rect(nvc0, &tx->rect[1], &tx->rect[0],
|
||||
tx->nblocksx, tx->nblocksy);
|
||||
if (mt->layout_3d)
|
||||
tx->rect[0].z++;
|
||||
|
|
@ -311,14 +273,14 @@ void
|
|||
nvc0_miptree_transfer_del(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct pipe_screen *pscreen = pctx->screen;
|
||||
struct nvc0_context *nvc0 = nvc0_context(pctx);
|
||||
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
|
||||
struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
|
||||
unsigned i;
|
||||
|
||||
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
|
||||
for (i = 0; i < tx->nlayers; ++i) {
|
||||
nvc0_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
|
||||
nvc0_m2mf_transfer_rect(nvc0, &tx->rect[0], &tx->rect[1],
|
||||
tx->nblocksx, tx->nblocksy);
|
||||
if (mt->layout_3d)
|
||||
tx->rect[0].z++;
|
||||
|
|
@ -338,6 +300,7 @@ void *
|
|||
nvc0_miptree_transfer_map(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pctx);
|
||||
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
|
||||
int ret;
|
||||
unsigned flags = 0;
|
||||
|
|
@ -350,7 +313,7 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
|
|||
if (transfer->usage & PIPE_TRANSFER_WRITE)
|
||||
flags |= NOUVEAU_BO_WR;
|
||||
|
||||
ret = nouveau_bo_map(tx->rect[1].bo, flags);
|
||||
ret = nouveau_bo_map(tx->rect[1].bo, flags, nvc0->screen->base.client);
|
||||
if (ret)
|
||||
return NULL;
|
||||
return tx->rect[1].bo->map;
|
||||
|
|
@ -360,9 +323,6 @@ void
|
|||
nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
|
||||
|
||||
nouveau_bo_unmap(tx->rect[1].bo);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -371,33 +331,34 @@ nvc0_cb_push(struct nouveau_context *nv,
|
|||
unsigned base, unsigned size,
|
||||
unsigned offset, unsigned words, const uint32_t *data)
|
||||
{
|
||||
struct nouveau_channel *chan = nv->screen->channel;
|
||||
struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
|
||||
assert(!(offset & 3));
|
||||
size = align(size, 0x100);
|
||||
|
||||
MARK_RING (chan, 16, 2);
|
||||
BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
|
||||
OUT_RING (chan, size);
|
||||
OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR);
|
||||
OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR);
|
||||
nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
|
||||
PUSH_DATA (push, size);
|
||||
PUSH_DATAh(push, bo->offset + base);
|
||||
PUSH_DATA (push, bo->offset + base);
|
||||
|
||||
while (words) {
|
||||
unsigned nr = AVAIL_RING(chan);
|
||||
unsigned nr = PUSH_AVAIL(push);
|
||||
nr = MIN2(nr, words);
|
||||
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
|
||||
|
||||
BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1);
|
||||
OUT_RING (chan, offset);
|
||||
OUT_RINGp (chan, data, nr);
|
||||
BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
|
||||
PUSH_DATA (push, offset);
|
||||
PUSH_DATAp(push, data, nr);
|
||||
|
||||
words -= nr;
|
||||
data += nr;
|
||||
offset += nr * 4;
|
||||
|
||||
if (words) {
|
||||
MARK_RING(chan, 6, 1);
|
||||
nouveau_bo_validate(chan, bo, domain | NOUVEAU_BO_WR);
|
||||
}
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_inlines.h"
|
||||
|
|
@ -128,7 +130,7 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb,
|
|||
struct pipe_vertex_element *ve, unsigned attr)
|
||||
{
|
||||
const void *data;
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nv04_resource *res = nv04_resource(vb->buffer);
|
||||
float v[4];
|
||||
int i;
|
||||
|
|
@ -139,10 +141,11 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb,
|
|||
|
||||
util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1);
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), nc + 1);
|
||||
OUT_RING (chan, VTX_ATTR(attr, nc, FLOAT, 32));
|
||||
PUSH_SPACE(push, 6);
|
||||
BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), nc + 1);
|
||||
PUSH_DATA (push, VTX_ATTR(attr, nc, FLOAT, 32));
|
||||
for (i = 0; i < nc; ++i)
|
||||
OUT_RINGf(chan, v[i]);
|
||||
PUSH_DATAf(push, v[i]);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
|
|
@ -171,7 +174,7 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
|
|||
|
||||
nvc0->vbo_fifo = nvc0->vbo_user = 0;
|
||||
|
||||
nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
|
||||
|
||||
for (i = 0; i < nvc0->num_vtxbufs; ++i) {
|
||||
vb = &nvc0->vtxbuf[i];
|
||||
|
|
@ -189,33 +192,41 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
|
|||
nvc0->vbo_user |= 1 << i;
|
||||
assert(vb->stride > vb->buffer_offset);
|
||||
nvc0_vbuf_range(nvc0, i, &base, &size);
|
||||
nouveau_user_buffer_upload(buf, base, size);
|
||||
nouveau_user_buffer_upload(&nvc0->base, buf, base, size);
|
||||
} else {
|
||||
nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART);
|
||||
}
|
||||
nvc0->base.vbo_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
|
||||
BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_update_user_vbufs(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
uint32_t base, offset, size;
|
||||
int i;
|
||||
uint32_t written = 0;
|
||||
|
||||
/* TODO: use separate bufctx bin for user buffers
|
||||
*/
|
||||
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
|
||||
|
||||
PUSH_SPACE(push, nvc0->vertex->num_elements * 8);
|
||||
|
||||
for (i = 0; i < nvc0->vertex->num_elements; ++i) {
|
||||
struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe;
|
||||
const int b = ve->vertex_buffer_index;
|
||||
struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b];
|
||||
struct nv04_resource *buf = nv04_resource(vb->buffer);
|
||||
|
||||
if (!(nvc0->vbo_user & (1 << b)))
|
||||
if (!(nvc0->vbo_user & (1 << b))) {
|
||||
BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!vb->stride) {
|
||||
nvc0_emit_vtxattr(nvc0, vb, ve, i);
|
||||
|
|
@ -225,17 +236,18 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0)
|
|||
|
||||
if (!(written & (1 << b))) {
|
||||
written |= 1 << b;
|
||||
nouveau_user_buffer_upload(buf, base, size);
|
||||
nouveau_user_buffer_upload(&nvc0->base, buf, base, size);
|
||||
}
|
||||
offset = vb->buffer_offset + ve->src_offset;
|
||||
|
||||
MARK_RING (chan, 6, 4);
|
||||
BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
|
||||
OUT_RING (chan, i);
|
||||
OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
|
||||
OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
|
||||
BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5);
|
||||
PUSH_DATA (push, i);
|
||||
PUSH_DATAh(push, buf->address + base + size - 1);
|
||||
PUSH_DATA (push, buf->address + base + size - 1);
|
||||
PUSH_DATAh(push, buf->address + offset);
|
||||
PUSH_DATA (push, buf->address + offset);
|
||||
|
||||
BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
|
||||
}
|
||||
nvc0->base.vbo_dirty = TRUE;
|
||||
}
|
||||
|
|
@ -256,7 +268,7 @@ nvc0_release_user_vbufs(struct nvc0_context *nvc0)
|
|||
void
|
||||
nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_vertex_stateobj *vertex = nvc0->vertex;
|
||||
struct pipe_vertex_buffer *vb;
|
||||
struct nvc0_vertex_element *ve;
|
||||
|
|
@ -270,19 +282,21 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
|
|||
nvc0_prevalidate_vbufs(nvc0);
|
||||
}
|
||||
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
|
||||
PUSH_SPACE(push, vertex->num_elements + 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
|
||||
for (i = 0; i < vertex->num_elements; ++i) {
|
||||
ve = &vertex->element[i];
|
||||
vb = &nvc0->vtxbuf[ve->pipe.vertex_buffer_index];
|
||||
|
||||
if (likely(vb->stride) || nvc0->vbo_fifo) {
|
||||
OUT_RING(chan, ve->state);
|
||||
PUSH_DATA(push, ve->state);
|
||||
} else {
|
||||
OUT_RING(chan, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
|
||||
PUSH_DATA(push, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
|
||||
nvc0->vbo_fifo &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
PUSH_SPACE(push, vertex->num_elements * 16);
|
||||
for (i = 0; i < vertex->num_elements; ++i) {
|
||||
struct nv04_resource *res;
|
||||
unsigned size, offset;
|
||||
|
|
@ -292,13 +306,13 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
|
|||
|
||||
if (unlikely(ve->pipe.instance_divisor)) {
|
||||
if (!(nvc0->state.instance_elts & (1 << i))) {
|
||||
IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
|
||||
}
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
|
||||
OUT_RING (chan, ve->pipe.instance_divisor);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
|
||||
PUSH_DATA (push, ve->pipe.instance_divisor);
|
||||
} else
|
||||
if (unlikely(nvc0->state.instance_elts & (1 << i))) {
|
||||
IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
|
||||
}
|
||||
|
||||
res = nv04_resource(vb->buffer);
|
||||
|
|
@ -306,37 +320,58 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
|
|||
if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) {
|
||||
if (!nvc0->vbo_fifo)
|
||||
nvc0_emit_vtxattr(nvc0, vb, &ve->pipe, i);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
size = vb->buffer->width0;
|
||||
offset = ve->pipe.src_offset + vb->buffer_offset;
|
||||
|
||||
MARK_RING (chan, 8, 4);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
OUT_RING (chan, (1 << 12) | vb->stride);
|
||||
BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
|
||||
OUT_RING (chan, i);
|
||||
OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
|
||||
OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
PUSH_DATA (push, (1 << 12) | vb->stride);
|
||||
BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5);
|
||||
PUSH_DATA (push, i);
|
||||
PUSH_DATAh(push, res->address + size - 1);
|
||||
PUSH_DATA (push, res->address + size - 1);
|
||||
PUSH_DATAh(push, res->address + offset);
|
||||
PUSH_DATA (push, res->address + offset);
|
||||
}
|
||||
for (; i < nvc0->state.num_vtxelts; ++i) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(i)), 1);
|
||||
OUT_RING (chan, NVC0_3D_VERTEX_ATTRIB_INACTIVE);
|
||||
PUSH_SPACE(push, 5);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(i)), 1);
|
||||
PUSH_DATA (push, NVC0_3D_VERTEX_ATTRIB_INACTIVE);
|
||||
if (unlikely(nvc0->state.instance_elts & (1 << i)))
|
||||
IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
OUT_RING (chan, 0);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
}
|
||||
|
||||
nvc0->state.num_vtxelts = vertex->num_elements;
|
||||
nvc0->state.instance_elts = vertex->instance_elts;
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_idxbuf_validate(struct nvc0_context *nvc0)
|
||||
{
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nv04_resource *buf = nv04_resource(nvc0->idxbuf.buffer);
|
||||
|
||||
assert(buf);
|
||||
if (!nouveau_resource_mapped_by_gpu(&buf->base))
|
||||
return;
|
||||
|
||||
PUSH_SPACE(push, 6);
|
||||
BEGIN_NVC0(push, NVC0_3D(INDEX_ARRAY_START_HIGH), 5);
|
||||
PUSH_DATAh(push, buf->address + nvc0->idxbuf.offset);
|
||||
PUSH_DATA (push, buf->address + nvc0->idxbuf.offset);
|
||||
PUSH_DATAh(push, buf->address + buf->base.width0 - 1);
|
||||
PUSH_DATA (push, buf->address + buf->base.width0 - 1);
|
||||
PUSH_DATA (push, nvc0->idxbuf.index_size >> 1);
|
||||
|
||||
BCTX_REFN(nvc0->bufctx_3d, IDX, buf, RD);
|
||||
}
|
||||
|
||||
#define NVC0_PRIM_GL_CASE(n) \
|
||||
case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
|
||||
|
||||
|
|
@ -367,13 +402,11 @@ nvc0_prim_gl(unsigned prim)
|
|||
}
|
||||
|
||||
static void
|
||||
nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan)
|
||||
nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
|
||||
{
|
||||
struct nvc0_screen *screen = chan->user_private;
|
||||
struct nvc0_screen *screen = push->user_priv;
|
||||
|
||||
nouveau_fence_update(&screen->base, TRUE);
|
||||
|
||||
nvc0_bufctx_emit_relocs(screen->cur_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -381,47 +414,51 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
|
|||
unsigned mode, unsigned start, unsigned count,
|
||||
unsigned instance_count)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
unsigned prim;
|
||||
|
||||
if (nvc0->state.index_bias) {
|
||||
IMMED_RING(chan, RING_3D(VB_ELEMENT_BASE), 0);
|
||||
PUSH_SPACE(push, 1);
|
||||
IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0);
|
||||
nvc0->state.index_bias = 0;
|
||||
}
|
||||
|
||||
prim = nvc0_prim_gl(mode);
|
||||
|
||||
while (instance_count--) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, prim);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2);
|
||||
OUT_RING (chan, start);
|
||||
OUT_RING (chan, count);
|
||||
IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
|
||||
PUSH_SPACE(push, 6);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, prim);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2);
|
||||
PUSH_DATA (push, start);
|
||||
PUSH_DATA (push, count);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
|
||||
|
||||
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
|
||||
nvc0_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
||||
if (count & 3) {
|
||||
unsigned i;
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3);
|
||||
PUSH_SPACE(push, 4);
|
||||
BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), count & 3);
|
||||
for (i = 0; i < (count & 3); ++i)
|
||||
OUT_RING(chan, *map++);
|
||||
PUSH_DATA(push, *map++);
|
||||
count &= ~3;
|
||||
}
|
||||
while (count) {
|
||||
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr);
|
||||
PUSH_SPACE(push, nr + 1);
|
||||
BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U8), nr);
|
||||
for (i = 0; i < nr; ++i) {
|
||||
OUT_RING(chan,
|
||||
PUSH_DATA(push,
|
||||
(map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
|
||||
map += 4;
|
||||
}
|
||||
|
|
@ -430,22 +467,24 @@ nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
|
|||
}
|
||||
|
||||
static void
|
||||
nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
|
||||
nvc0_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
||||
if (count & 1) {
|
||||
count &= ~1;
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (chan, *map++);
|
||||
PUSH_SPACE(push, 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (push, *map++);
|
||||
}
|
||||
while (count) {
|
||||
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
|
||||
PUSH_SPACE(push, nr + 1);
|
||||
BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U16), nr);
|
||||
for (i = 0; i < nr; ++i) {
|
||||
OUT_RING(chan, (map[1] << 16) | map[0]);
|
||||
PUSH_DATA(push, (map[1] << 16) | map[0]);
|
||||
map += 2;
|
||||
}
|
||||
count -= nr * 2;
|
||||
|
|
@ -453,7 +492,7 @@ nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
|
|||
}
|
||||
|
||||
static void
|
||||
nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
|
||||
nvc0_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
|
@ -461,8 +500,9 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
|
|||
while (count) {
|
||||
const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr);
|
||||
OUT_RINGp (chan, map, nr);
|
||||
PUSH_SPACE(push, nr + 1);
|
||||
BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), nr);
|
||||
PUSH_DATAp(push, map, nr);
|
||||
|
||||
map += nr;
|
||||
count -= nr;
|
||||
|
|
@ -470,22 +510,24 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
|
|||
}
|
||||
|
||||
static void
|
||||
nvc0_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
|
||||
nvc0_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
map += start;
|
||||
|
||||
if (count & 1) {
|
||||
count--;
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
|
||||
OUT_RING (chan, *map++);
|
||||
PUSH_SPACE(push, 1);
|
||||
BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1);
|
||||
PUSH_DATA (push, *map++);
|
||||
}
|
||||
while (count) {
|
||||
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
|
||||
|
||||
BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
|
||||
PUSH_SPACE(push, nr + 1);
|
||||
BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U16), nr);
|
||||
for (i = 0; i < nr; ++i) {
|
||||
OUT_RING(chan, (map[1] << 16) | map[0]);
|
||||
PUSH_DATA(push, (map[1] << 16) | map[0]);
|
||||
map += 2;
|
||||
}
|
||||
count -= nr * 2;
|
||||
|
|
@ -497,7 +539,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
|
|||
unsigned mode, unsigned start, unsigned count,
|
||||
unsigned instance_count, int32_t index_bias)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
void *data;
|
||||
unsigned prim;
|
||||
const unsigned index_size = nvc0->idxbuf.index_size;
|
||||
|
|
@ -505,34 +547,27 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
|
|||
prim = nvc0_prim_gl(mode);
|
||||
|
||||
if (index_bias != nvc0->state.index_bias) {
|
||||
BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
|
||||
OUT_RING (chan, index_bias);
|
||||
PUSH_SPACE(push, 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 1);
|
||||
PUSH_DATA (push, index_bias);
|
||||
nvc0->state.index_bias = index_bias;
|
||||
}
|
||||
|
||||
if (nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) {
|
||||
struct nv04_resource *res = nv04_resource(nvc0->idxbuf.buffer);
|
||||
unsigned offset = nvc0->idxbuf.offset;
|
||||
unsigned limit = nvc0->idxbuf.buffer->width0 - 1;
|
||||
|
||||
while (instance_count--) {
|
||||
MARK_RING (chan, 11, 4);
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_RING(chan, RING_3D(INDEX_ARRAY_START_HIGH), 7);
|
||||
OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
|
||||
OUT_RESRCh(chan, res, limit, NOUVEAU_BO_RD);
|
||||
OUT_RESRCl(chan, res, limit, NOUVEAU_BO_RD);
|
||||
OUT_RING (chan, index_size >> 1);
|
||||
OUT_RING (chan, start);
|
||||
OUT_RING (chan, count);
|
||||
IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
|
||||
|
||||
nvc0_resource_fence(res, NOUVEAU_BO_RD);
|
||||
|
||||
mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
PUSH_SPACE(push, 1);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), prim);
|
||||
do {
|
||||
PUSH_SPACE(push, 7);
|
||||
BEGIN_NVC0(push, NVC0_3D(INDEX_BATCH_FIRST), 2);
|
||||
PUSH_DATA (push, start);
|
||||
PUSH_DATA (push, count);
|
||||
if (--instance_count) {
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_END_GL), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
PUSH_DATA (push, prim | NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT);
|
||||
}
|
||||
} while (instance_count);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
|
||||
} else {
|
||||
data = nouveau_resource_map_offset(&nvc0->base,
|
||||
nv04_resource(nvc0->idxbuf.buffer),
|
||||
|
|
@ -541,26 +576,28 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
|
|||
return;
|
||||
|
||||
while (instance_count--) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, prim);
|
||||
PUSH_SPACE(push, 2);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, prim);
|
||||
switch (index_size) {
|
||||
case 1:
|
||||
nvc0_draw_elements_inline_u08(chan, data, start, count);
|
||||
nvc0_draw_elements_inline_u08(push, data, start, count);
|
||||
break;
|
||||
case 2:
|
||||
nvc0_draw_elements_inline_u16(chan, data, start, count);
|
||||
nvc0_draw_elements_inline_u16(push, data, start, count);
|
||||
break;
|
||||
case 4:
|
||||
if (shorten)
|
||||
nvc0_draw_elements_inline_u32_short(chan, data, start, count);
|
||||
nvc0_draw_elements_inline_u32_short(push, data, start, count);
|
||||
else
|
||||
nvc0_draw_elements_inline_u32(chan, data, start, count);
|
||||
nvc0_draw_elements_inline_u32(push, data, start, count);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
|
||||
PUSH_SPACE(push, 1);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
|
||||
|
||||
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
|
|
@ -571,7 +608,7 @@ static void
|
|||
nvc0_draw_stream_output(struct nvc0_context *nvc0,
|
||||
const struct pipe_draw_info *info)
|
||||
{
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
struct nvc0_so_target *so = nvc0_so_target(info->count_from_stream_output);
|
||||
struct nv04_resource *res = nv04_resource(so->pipe.buffer);
|
||||
unsigned mode = nvc0_prim_gl(info->mode);
|
||||
|
|
@ -579,21 +616,23 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0,
|
|||
|
||||
if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
|
||||
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
IMMED_RING(chan, RING_3D(SERIALIZE), 0);
|
||||
nvc0_query_fifo_wait(chan, so->pq);
|
||||
IMMED_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 0);
|
||||
PUSH_SPACE(push, 2);
|
||||
IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
|
||||
nvc0_query_fifo_wait(push, so->pq);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
|
||||
}
|
||||
|
||||
while (num_instances--) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
|
||||
OUT_RING (chan, mode);
|
||||
BEGIN_RING(chan, RING_3D(DRAW_TFB_BASE), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_RING(chan, RING_3D(DRAW_TFB_STRIDE), 1);
|
||||
OUT_RING (chan, so->stride);
|
||||
BEGIN_RING(chan, RING_3D(DRAW_TFB_BYTES), 1);
|
||||
nvc0_query_pushbuf_submit(chan, so->pq, 0x4);
|
||||
IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
|
||||
PUSH_SPACE(push, 8);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
|
||||
PUSH_DATA (push, mode);
|
||||
BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BASE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_STRIDE), 1);
|
||||
PUSH_DATA (push, so->stride);
|
||||
BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BYTES), 1);
|
||||
nvc0_query_pushbuf_submit(push, so->pq, 0x4);
|
||||
IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
|
||||
|
||||
mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
|
||||
}
|
||||
|
|
@ -603,7 +642,7 @@ void
|
|||
nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_channel *chan = nvc0->screen->base.channel;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
|
||||
/* For picking only a few vertices from a large user buffer, push is better,
|
||||
* if index count is larger and we expect repeated vertices, suggest upload.
|
||||
|
|
@ -624,24 +663,27 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
/* 8 as minimum to avoid immediate double validation of new buffers */
|
||||
nvc0_state_validate(nvc0, ~0, 8);
|
||||
|
||||
chan->flush_notify = nvc0_draw_vbo_flush_notify;
|
||||
push->kick_notify = nvc0_draw_vbo_kick_notify;
|
||||
|
||||
if (nvc0->vbo_fifo) {
|
||||
nvc0_push_vbo(nvc0, info);
|
||||
chan->flush_notify = nvc0_default_flush_notify;
|
||||
push->kick_notify = nvc0_default_kick_notify;
|
||||
return;
|
||||
}
|
||||
|
||||
/* space for base instance, flush, and prim restart */
|
||||
PUSH_SPACE(push, 8);
|
||||
|
||||
if (nvc0->state.instance_base != info->start_instance) {
|
||||
nvc0->state.instance_base = info->start_instance;
|
||||
/* NOTE: this does not affect the shader input, should it ? */
|
||||
BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1);
|
||||
OUT_RING (chan, info->start_instance);
|
||||
BEGIN_NVC0(push, NVC0_3D(VB_INSTANCE_BASE), 1);
|
||||
PUSH_DATA (push, info->start_instance);
|
||||
}
|
||||
|
||||
if (nvc0->base.vbo_dirty) {
|
||||
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
|
||||
OUT_RING (chan, 0);
|
||||
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
nvc0->base.vbo_dirty = FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -659,20 +701,20 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
|
||||
if (info->primitive_restart != nvc0->state.prim_restart) {
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2);
|
||||
OUT_RING (chan, 1);
|
||||
OUT_RING (chan, info->restart_index);
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 2);
|
||||
PUSH_DATA (push, 1);
|
||||
PUSH_DATA (push, info->restart_index);
|
||||
|
||||
if (info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
} else {
|
||||
IMMED_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 0);
|
||||
IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0);
|
||||
}
|
||||
nvc0->state.prim_restart = info->primitive_restart;
|
||||
} else
|
||||
if (info->primitive_restart) {
|
||||
BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1);
|
||||
OUT_RING (chan, info->restart_index);
|
||||
BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_INDEX), 1);
|
||||
PUSH_DATA (push, info->restart_index);
|
||||
|
||||
if (info->restart_index > 65535)
|
||||
shorten = FALSE;
|
||||
|
|
@ -682,7 +724,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
info->mode, info->start, info->count,
|
||||
info->instance_count, info->index_bias);
|
||||
}
|
||||
chan->flush_notify = nvc0_default_flush_notify;
|
||||
push->kick_notify = nvc0_default_kick_notify;
|
||||
|
||||
nvc0_release_user_vbufs(nvc0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,117 +4,132 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "nouveau/nouveau_bo.h"
|
||||
#include "nouveau/nouveau_channel.h"
|
||||
#include "nouveau/nouveau_grobj.h"
|
||||
#include "nouveau/nouveau_device.h"
|
||||
#include "nouveau/nouveau_resource.h"
|
||||
#include "nouveau/nouveau_pushbuf.h"
|
||||
#include "nouveau/nouveau_reloc.h"
|
||||
|
||||
#include "nvc0_resource.h" /* OUT_RESRC */
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau/nouveau_buffer.h"
|
||||
|
||||
#ifndef NV04_PFIFO_MAX_PACKET_LEN
|
||||
#define NV04_PFIFO_MAX_PACKET_LEN 2047
|
||||
#endif
|
||||
|
||||
#define NVC0_SUBCH_3D 1
|
||||
#define NVC0_SUBCH_2D 2
|
||||
#define NVC0_SUBCH_MF 3
|
||||
|
||||
#define NVC0_MF_(n) NVC0_M2MF_##n
|
||||
|
||||
#define RING_3D(n) ((NVC0_SUBCH_3D << 13) | (NVC0_3D_##n >> 2))
|
||||
#define RING_2D(n) ((NVC0_SUBCH_2D << 13) | (NVC0_2D_##n >> 2))
|
||||
#define RING_MF(n) ((NVC0_SUBCH_MF << 13) | (NVC0_MF_(n) >> 2))
|
||||
|
||||
#define RING_3D_(m) ((NVC0_SUBCH_3D << 13) | ((m) >> 2))
|
||||
#define RING_2D_(m) ((NVC0_SUBCH_2D << 13) | ((m) >> 2))
|
||||
#define RING_MF_(m) ((NVC0_SUBCH_MF << 13) | ((m) >> 2))
|
||||
|
||||
#define RING_GR(gr, m) (((gr)->subc << 13) | ((m) >> 2))
|
||||
|
||||
int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
|
||||
|
||||
static inline uint32_t
|
||||
nouveau_bo_tile_layout(const struct nouveau_bo *bo)
|
||||
static INLINE void
|
||||
nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin,
|
||||
unsigned flags, struct nouveau_bo *bo)
|
||||
{
|
||||
return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
|
||||
nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
nouveau_bo_validate(struct nouveau_channel *chan,
|
||||
struct nouveau_bo *bo, unsigned flags)
|
||||
nvc0_add_resident(struct nouveau_bufctx *bufctx, int bin,
|
||||
struct nv04_resource *res, unsigned flags)
|
||||
{
|
||||
nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
|
||||
struct nouveau_bufref *ref =
|
||||
nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain);
|
||||
ref->priv = res;
|
||||
ref->priv_data = flags;
|
||||
}
|
||||
|
||||
/* incremental methods */
|
||||
#define BCTX_REFN_bo(ctx, bin, fl, bo) \
|
||||
nv50_add_bufctx_resident_bo(ctx, NVC0_BIND_##bin, fl, bo);
|
||||
|
||||
#define BCTX_REFN(bctx, bin, res, acc) \
|
||||
nvc0_add_resident(bctx, NVC0_BIND_##bin, res, NOUVEAU_BO_##acc)
|
||||
|
||||
static INLINE void
|
||||
BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
|
||||
PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
|
||||
{
|
||||
WAIT_RING(chan, size + 1);
|
||||
OUT_RING (chan, (0x2 << 28) | (size << 16) | mthd);
|
||||
struct nouveau_pushbuf_refn ref = { bo, flags };
|
||||
nouveau_pushbuf_refn(push, &ref, 1);
|
||||
}
|
||||
|
||||
/* non-incremental */
|
||||
|
||||
#define SUBC_3D(m) 1, (m)
|
||||
#define NVC0_3D(n) SUBC_3D(NVC0_3D_##n)
|
||||
|
||||
#define SUBC_2D(m) 2, (m)
|
||||
#define NVC0_2D(n) SUBC_2D(NVC0_2D_##n)
|
||||
|
||||
#define SUBC_M2MF(m) 3, (m)
|
||||
#define NVC0_M2MF(n) SUBC_M2MF(NVC0_M2MF_##n)
|
||||
|
||||
#define SUBC_COMPUTE(m) 4, (m)
|
||||
#define NVC0_COMPUTE(n) SUBC_COMPUTE(NVC0_COMPUTE_##n)
|
||||
|
||||
static INLINE uint32_t
|
||||
NVC0_FIFO_PKHDR_SQ(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0x20000000 | (size << 16) | (subc << 13) | (mthd >> 2);
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
NVC0_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0x60000000 | (size << 16) | (subc << 13) | (mthd >> 2);
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint8_t data)
|
||||
{
|
||||
return 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2);
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
NVC0_FIFO_PKHDR_1I(int subc, int mthd, unsigned size)
|
||||
{
|
||||
return 0xa0000000 | (size << 16) | (subc << 13) | (mthd >> 2);
|
||||
}
|
||||
|
||||
|
||||
static INLINE uint8_t
|
||||
nouveau_bo_memtype(const struct nouveau_bo *bo)
|
||||
{
|
||||
return bo->config.nvc0.memtype;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
|
||||
PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data)
|
||||
{
|
||||
WAIT_RING(chan, size + 1);
|
||||
OUT_RING (chan, (0x6 << 28) | (size << 16) | mthd);
|
||||
}
|
||||
|
||||
/* increment-once */
|
||||
static INLINE void
|
||||
BEGIN_RING_1I(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
|
||||
{
|
||||
WAIT_RING(chan, size + 1);
|
||||
OUT_RING (chan, (0xa << 28) | (size << 16) | mthd);
|
||||
}
|
||||
|
||||
/* inline-data */
|
||||
static INLINE void
|
||||
IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data)
|
||||
{
|
||||
WAIT_RING(chan, 1);
|
||||
OUT_RING (chan, (0x8 << 28) | (data << 16) | mthd);
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
|
||||
unsigned delta, unsigned flags)
|
||||
{
|
||||
return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
|
||||
unsigned delta, unsigned flags)
|
||||
{
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
|
||||
*push->cur++ = (uint32_t)(data >> 32);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
|
||||
BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
struct nouveau_subchannel *subc = &gr->channel->subc[s];
|
||||
|
||||
assert(s < 8);
|
||||
if (subc->gr) {
|
||||
assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT);
|
||||
subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
|
||||
}
|
||||
subc->gr = gr;
|
||||
subc->gr->subc = s;
|
||||
subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
|
||||
|
||||
BEGIN_RING(chan, RING_GR(gr, 0x0000), 1);
|
||||
OUT_RING (chan, gr->grclass);
|
||||
}
|
||||
|
||||
#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, size + 1);
|
||||
#endif
|
||||
PUSH_DATA (push, NVC0_FIFO_PKHDR_SQ(subc, mthd, size));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BEGIN_NIC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, size + 1);
|
||||
#endif
|
||||
PUSH_DATA (push, NVC0_FIFO_PKHDR_NI(subc, mthd, size));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
BEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
|
||||
{
|
||||
#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, size + 1);
|
||||
#endif
|
||||
PUSH_DATA (push, NVC0_FIFO_PKHDR_1I(subc, mthd, size));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
IMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, uint8_t data)
|
||||
{
|
||||
#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
|
||||
PUSH_SPACE(push, 1);
|
||||
#endif
|
||||
PUSH_DATA (push, NVC0_FIFO_PKHDR_IL(subc, mthd, data));
|
||||
}
|
||||
|
||||
#endif /* __NVC0_WINSYS_H__ */
|
||||
|
|
|
|||
|
|
@ -6,10 +6,6 @@
|
|||
|
||||
#include "nouveau_drm_public.h"
|
||||
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nouveau_channel.h"
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau/nouveau_screen.h"
|
||||
|
||||
|
|
@ -20,7 +16,7 @@ nouveau_drm_screen_create(int fd)
|
|||
struct pipe_screen *(*init)(struct nouveau_device *);
|
||||
int ret;
|
||||
|
||||
ret = nouveau_device_open_existing(&dev, 0, fd, 0);
|
||||
ret = nouveau_device_wrap(fd, 0, &dev);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue