summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c47
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.c17
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c11
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c42
-rw-r--r--src/gallium/drivers/nv50/nv50_stateobj.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c4
8 files changed, 81 insertions, 48 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 912367b8391..930cee7c1e7 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -30,25 +30,20 @@
#include "nouveau/nouveau_reloc.h"
static void
-nv50_flush(struct pipe_context *pipe, unsigned flags,
+nv50_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
-
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
- OUT_RING (chan, 0x20);
- }
+ struct nouveau_screen *screen = &nv50_context(pipe)->screen->base;
if (fence)
- nouveau_fence_ref(nv50->screen->base.fence.current,
- (struct nouveau_fence **)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);
- if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME))
- FIRE_RING(chan);
+ FIRE_RING(screen->channel);
}
void
@@ -64,10 +59,34 @@ nv50_default_flush_notify(struct nouveau_channel *chan)
}
static void
+nv50_context_unreference_resources(struct nv50_context *nv50)
+{
+ unsigned s, i;
+
+ for (i = 0; i < NV50_BUFCTX_COUNT; ++i)
+ nv50_bufctx_reset(nv50, i);
+
+ for (i = 0; i < nv50->num_vtxbufs; ++i)
+ pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
+
+ pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
+
+ for (s = 0; s < 3; ++s) {
+ for (i = 0; i < nv50->num_textures[s]; ++i)
+ pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
+
+ for (i = 0; i < 16; ++i)
+ pipe_resource_reference(&nv50->constbuf[s][i], NULL);
+ }
+}
+
+static void
nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ nv50_context_unreference_resources(nv50);
+
draw_destroy(nv50->draw);
if (nv50->screen->cur_ctx == nv50) {
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index ae6b26af1eb..9eeca05ada3 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -106,7 +106,6 @@ const struct u_resource_vtbl nv50_miptree_vtbl =
{
nv50_miptree_get_handle, /* get_handle */
nv50_miptree_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
nv50_miptree_transfer_new, /* get_transfer */
nv50_miptree_transfer_del, /* transfer_destroy */
nv50_miptree_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c
index 2a2fb0e32bc..1ae4d70a845 100644
--- a/src/gallium/drivers/nv50/nv50_resource.c
+++ b/src/gallium/drivers/nv50/nv50_resource.c
@@ -3,22 +3,6 @@
#include "nv50_resource.h"
#include "nouveau/nouveau_screen.h"
-static unsigned
-nv50_resource_is_referenced(struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned face, int layer)
-{
- struct nv04_resource *res = nv04_resource(resource);
- unsigned flags = 0;
- unsigned bo_flags = nouveau_bo_pending(res->bo);
-
- if (bo_flags & NOUVEAU_BO_RD)
- flags = PIPE_REFERENCED_FOR_READ;
- if (bo_flags & NOUVEAU_BO_WR)
- flags |= PIPE_REFERENCED_FOR_WRITE;
-
- return flags;
-}
static struct pipe_resource *
nv50_resource_create(struct pipe_screen *screen,
@@ -52,7 +36,6 @@ nv50_init_resource_functions(struct pipe_context *pcontext)
pcontext->transfer_unmap = u_transfer_unmap_vtbl;
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
- pcontext->is_resource_referenced = nv50_resource_is_referenced;
pcontext->create_surface = nv50_miptree_surface_new;
pcontext->surface_destroy = nv50_miptree_surface_del;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index ae0365eb5c5..7690c80eef0 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -40,7 +40,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bindings, unsigned geom_flags)
+ unsigned bindings)
{
if (sample_count > 1)
return FALSE;
@@ -127,7 +127,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_SHADER_STENCIL_EXPORT:
return 0;
case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
default:
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 980bc369293..db257159698 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -796,10 +796,13 @@ nv50_set_index_buffer(struct pipe_context *pipe,
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (ib)
+ if (ib) {
+ pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+
memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
- else
- nv50->idxbuf.buffer = NULL;
+ } else {
+ pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
+ }
}
static void
@@ -866,5 +869,7 @@ nv50_init_state_functions(struct nv50_context *nv50)
pipe->set_vertex_buffers = nv50_set_vertex_buffers;
pipe->set_index_buffer = nv50_set_index_buffer;
+
+ pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index bf46296e7ef..f3d45eb95e0 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -43,8 +43,9 @@ nv50_validate_fb(struct nv50_context *nv50)
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_RDWR);
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
}
if (fb->zsbuf) {
@@ -74,7 +75,7 @@ nv50_validate_fb(struct nv50_context *nv50)
mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
} else {
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
OUT_RING (chan, 0);
@@ -253,6 +254,35 @@ nv50_validate_rasterizer(struct nv50_context *nv50)
OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
}
+static void
+nv50_switch_pipe_context(struct nv50_context *ctx_to)
+{
+ struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
+
+ if (ctx_from)
+ ctx_to->state = ctx_from->state;
+
+ ctx_to->dirty = ~0;
+
+ if (!ctx_to->vertex)
+ ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
+
+ if (!ctx_to->vertprog)
+ ctx_to->dirty &= ~NV50_NEW_VERTPROG;
+ if (!ctx_to->fragprog)
+ ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
+
+ if (!ctx_to->blend)
+ ctx_to->dirty &= ~NV50_NEW_BLEND;
+ if (!ctx_to->rast)
+ ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
+ if (!ctx_to->zsa)
+ ctx_to->dirty &= ~NV50_NEW_ZSA;
+
+ ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx =
+ ctx_to;
+}
+
static struct state_validate {
void (*func)(struct nv50_context *);
uint32_t states;
@@ -292,11 +322,9 @@ boolean
nv50_state_validate(struct nv50_context *nv50)
{
unsigned i;
-#if 0
- if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */
- nv50->dirty = 0xffffffff;
-#endif
- nv50->screen->cur_ctx = nv50;
+
+ if (nv50->screen->cur_ctx != nv50)
+ nv50_switch_pipe_context(nv50);
if (nv50->dirty) {
for (i = 0; i < validate_list_len; ++i) {
diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h
index cf5b92ef1a8..515e3e78d42 100644
--- a/src/gallium/drivers/nv50/nv50_stateobj.h
+++ b/src/gallium/drivers/nv50/nv50_stateobj.h
@@ -49,7 +49,7 @@ struct nv50_vertex_stateobj {
boolean need_conversion;
unsigned vertex_size;
unsigned packet_vertex_limit;
- struct nv50_vertex_element element[1];
+ struct nv50_vertex_element element[0];
};
#endif
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 4f0a5018459..abdb9ce2f93 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -51,10 +51,8 @@ nv50_vertex_state_create(struct pipe_context *pipe,
struct translate_key transkey;
unsigned i;
- assert(num_elements);
-
so = MALLOC(sizeof(*so) +
- (num_elements - 1) * sizeof(struct nv50_vertex_element));
+ num_elements * sizeof(struct nv50_vertex_element));
if (!so)
return NULL;
so->num_elements = num_elements;