blob: 8abac09ffd5ded884f8d7720f29e834e0011f506 [file] [log] [blame]
Christoph Bumiller4c224752010-11-12 15:17:40 +01001/*
2 * Copyright 2010 Christoph Bumiller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#include "draw/draw_context.h"
24#include "pipe/p_defines.h"
Christoph Bumiller2d06ee82012-03-07 19:44:10 +010025#include "util/u_framebuffer.h"
Christoph Bumiller4c224752010-11-12 15:17:40 +010026
27#include "nvc0_context.h"
28#include "nvc0_screen.h"
29#include "nvc0_resource.h"
30
Christoph Bumiller4c224752010-11-12 15:17:40 +010031static void
Marek Olšák7e023032011-03-08 00:57:48 +010032nvc0_flush(struct pipe_context *pipe,
Christoph Bumiller4c224752010-11-12 15:17:40 +010033 struct pipe_fence_handle **fence)
34{
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +020035 struct nvc0_context *nvc0 = nvc0_context(pipe);
36 struct nouveau_screen *screen = &nvc0->screen->base;
Christoph Bumiller4c224752010-11-12 15:17:40 +010037
Christoph Bumillera6ea37d2011-02-20 17:57:47 +010038 if (fence)
Christoph Bumiller43888172011-03-13 13:07:54 +010039 nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
Christoph Bumiller4c224752010-11-12 15:17:40 +010040
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +020041 PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
Christoph Bumiller4c224752010-11-12 15:17:40 +010042}
43
44static void
Christoph Bumiller83ff3802011-03-17 17:07:30 +010045nvc0_texture_barrier(struct pipe_context *pipe)
46{
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +020047 struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf;
Christoph Bumiller83ff3802011-03-17 17:07:30 +010048
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +020049 IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
50 IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0);
Christoph Bumiller83ff3802011-03-17 17:07:30 +010051}
52
53static void
Christoph Bumiller26a199e2011-03-13 13:06:42 +010054nvc0_context_unreference_resources(struct nvc0_context *nvc0)
55{
56 unsigned s, i;
57
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +020058 nouveau_bufctx_del(&nvc0->bufctx_3d);
59 nouveau_bufctx_del(&nvc0->bufctx);
Christoph Bumiller26a199e2011-03-13 13:06:42 +010060
Christoph Bumiller2d06ee82012-03-07 19:44:10 +010061 util_unreference_framebuffer_state(&nvc0->framebuffer);
62
Christoph Bumiller26a199e2011-03-13 13:06:42 +010063 for (i = 0; i < nvc0->num_vtxbufs; ++i)
64 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
65
66 pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
67
68 for (s = 0; s < 5; ++s) {
69 for (i = 0; i < nvc0->num_textures[s]; ++i)
70 pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
71
72 for (i = 0; i < 16; ++i)
73 pipe_resource_reference(&nvc0->constbuf[s][i], NULL);
74 }
75
76 for (i = 0; i < nvc0->num_tfbbufs; ++i)
Christoph Bumiller14bd9d72011-12-09 18:46:09 +010077 pipe_so_target_reference(&nvc0->tfbbuf[i], NULL);
Christoph Bumiller26a199e2011-03-13 13:06:42 +010078}
79
80static void
Christoph Bumiller4c224752010-11-12 15:17:40 +010081nvc0_destroy(struct pipe_context *pipe)
82{
83 struct nvc0_context *nvc0 = nvc0_context(pipe);
84
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +020085 if (nvc0->screen->cur_ctx == nvc0) {
86 nvc0->base.pushbuf->kick_notify = NULL;
87 nvc0->screen->cur_ctx = NULL;
88 nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
89 }
90 nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);
91
Christoph Bumiller26a199e2011-03-13 13:06:42 +010092 nvc0_context_unreference_resources(nvc0);
93
Christoph Bumiller4c224752010-11-12 15:17:40 +010094 draw_destroy(nvc0->draw);
95
Christoph Bumiller4c224752010-11-12 15:17:40 +010096 FREE(nvc0);
97}
98
Christoph Bumillera6ea37d2011-02-20 17:57:47 +010099void
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200100nvc0_default_kick_notify(struct nouveau_pushbuf *push)
Christoph Bumillera6ea37d2011-02-20 17:57:47 +0100101{
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200102 struct nvc0_screen *screen = push->user_priv;
Christoph Bumillera6ea37d2011-02-20 17:57:47 +0100103
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200104 if (screen) {
105 nouveau_fence_next(&screen->base);
106 nouveau_fence_update(&screen->base, TRUE);
107 if (screen->cur_ctx)
108 screen->cur_ctx->state.flushed = TRUE;
109 }
Christoph Bumillera6ea37d2011-02-20 17:57:47 +0100110}
111
Christoph Bumiller4c224752010-11-12 15:17:40 +0100112struct pipe_context *
113nvc0_create(struct pipe_screen *pscreen, void *priv)
114{
Christoph Bumiller4c224752010-11-12 15:17:40 +0100115 struct nvc0_screen *screen = nvc0_screen(pscreen);
116 struct nvc0_context *nvc0;
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000117 struct pipe_context *pipe;
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200118 int ret;
119 uint32_t flags;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100120
121 nvc0 = CALLOC_STRUCT(nvc0_context);
122 if (!nvc0)
123 return NULL;
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000124 pipe = &nvc0->base.pipe;
125
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200126 nvc0->base.pushbuf = screen->base.pushbuf;
127
128 ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT,
129 &nvc0->bufctx_3d);
130 if (!ret)
131 nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
132 if (ret)
133 goto out_err;
134
Christoph Bumiller4c224752010-11-12 15:17:40 +0100135 nvc0->screen = screen;
Christoph Bumillere44089b2012-04-14 23:56:56 +0200136 nvc0->base.screen = &screen->base;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100137
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000138 pipe->screen = pscreen;
139 pipe->priv = priv;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100140
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000141 pipe->destroy = nvc0_destroy;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100142
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000143 pipe->draw_vbo = nvc0_draw_vbo;
144 pipe->clear = nvc0_clear;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100145
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000146 pipe->flush = nvc0_flush;
Christoph Bumiller83ff3802011-03-17 17:07:30 +0100147 pipe->texture_barrier = nvc0_texture_barrier;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100148
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200149 if (!screen->cur_ctx) {
Ben Skeggs48e191f2011-03-01 14:37:06 +1000150 screen->cur_ctx = nvc0;
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200151 nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
152 }
153 screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100154
Christoph Bumillerb3d8e1f2011-01-09 21:50:06 +0100155 nvc0_init_query_functions(nvc0);
Christoph Bumiller4c224752010-11-12 15:17:40 +0100156 nvc0_init_surface_functions(nvc0);
157 nvc0_init_state_functions(nvc0);
Christoph Bumillere44089b2012-04-14 23:56:56 +0200158 nvc0_init_transfer_functions(nvc0);
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000159 nvc0_init_resource_functions(pipe);
Christoph Bumiller4c224752010-11-12 15:17:40 +0100160
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000161 nvc0->draw = draw_create(pipe);
Christoph Bumiller4c224752010-11-12 15:17:40 +0100162 assert(nvc0->draw);
163 draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0));
164
Christoph Bumillerea316c52011-07-21 10:39:41 +0200165 nouveau_context_init_vdec(&nvc0->base);
166
Christoph Bumiller3afabfb2011-09-13 23:10:35 +0200167 /* shader builtin library is per-screen, but we need a context for m2mf */
168 nvc0_program_library_upload(nvc0);
169
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200170 /* add permanently resident buffers to bufctxts */
171
172 flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
173
174 BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
Christoph Bumillere44089b2012-04-14 23:56:56 +0200175 BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo);
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200176 BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);
177
178 flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
179
180 BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
181 BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);
182
Christoph Bumiller2206a7f2012-03-01 21:28:29 +0100183 nvc0->base.scratch.bo_size = 2 << 20;
184
Ben Skeggs1ba8e952011-03-01 15:28:26 +1000185 return pipe;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100186
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200187out_err:
188 if (nvc0) {
189 if (nvc0->bufctx_3d)
190 nouveau_bufctx_del(&nvc0->bufctx_3d);
191 if (nvc0->bufctx)
192 nouveau_bufctx_del(&nvc0->bufctx);
193 FREE(nvc0);
Christoph Bumiller4c224752010-11-12 15:17:40 +0100194 }
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200195 return NULL;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100196}
197
198void
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200199nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
200 boolean on_flush)
Christoph Bumiller4c224752010-11-12 15:17:40 +0100201{
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200202 struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
203 struct nouveau_list *it;
Christoph Bumiller4c224752010-11-12 15:17:40 +0100204
Christoph Bumiller6d1cdec2012-04-06 15:41:55 +0200205 for (it = list->next; it != list; it = it->next) {
206 struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
207 struct nv04_resource *res = ref->priv;
208 if (res)
209 nvc0_resource_validate(res, (unsigned)ref->priv_data);
Christoph Bumiller4c224752010-11-12 15:17:40 +0100210 }
Christoph Bumiller4c224752010-11-12 15:17:40 +0100211}