gallium: fix type of flags in pipe_context::flush()
[mesa.git] / src / gallium / drivers / freedreno / freedreno_context.c
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3 /*
4 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 * Rob Clark <robclark@freedesktop.org>
27 */
28
29 #include "freedreno_context.h"
30 #include "freedreno_vbo.h"
31 #include "freedreno_blend.h"
32 #include "freedreno_rasterizer.h"
33 #include "freedreno_zsa.h"
34 #include "freedreno_state.h"
35 #include "freedreno_resource.h"
36 #include "freedreno_clear.h"
37 #include "freedreno_program.h"
38 #include "freedreno_texture.h"
39 #include "freedreno_gmem.h"
40 #include "freedreno_util.h"
41
42 /* there are two cases where we currently need to wait for render complete:
43 * 1) pctx->flush() .. since at the moment we have no way for DDX to sync
44 * the presentation blit with the 3d core
45 * 2) wrap-around for ringbuffer.. possibly we can do something more
46 * Intelligent here. Right now we need to ensure there is enough room
47 * at the end of the drawcmds in the cmdstream buffer for all the per-
48 * tile cmds. We do this the lamest way possible, by making the ringbuffer
49 * big, and flushing and resetting back to the beginning if we get too
50 * close to the end.
51 */
52 static void
53 fd_context_wait(struct pipe_context *pctx)
54 {
55 struct fd_context *ctx = fd_context(pctx);
56 uint32_t ts = fd_ringbuffer_timestamp(ctx->ring);
57
58 DBG("wait: %u", ts);
59
60 fd_pipe_wait(ctx->screen->pipe, ts);
61 fd_ringbuffer_reset(ctx->ring);
62 fd_ringmarker_mark(ctx->draw_start);
63 }
64
65 /* emit accumulated render cmds, needed for example if render target has
66 * changed, or for flush()
67 */
68 void
69 fd_context_render(struct pipe_context *pctx)
70 {
71 struct fd_context *ctx = fd_context(pctx);
72 struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
73
74 DBG("needs_flush: %d", ctx->needs_flush);
75
76 if (!ctx->needs_flush)
77 return;
78
79 fd_gmem_render_tiles(pctx);
80
81 DBG("%p/%p/%p", ctx->ring->start, ctx->ring->cur, ctx->ring->end);
82
83 /* if size in dwords is more than half the buffer size, then wait and
84 * wrap around:
85 */
86 if ((ctx->ring->cur - ctx->ring->start) > ctx->ring->size/8)
87 fd_context_wait(pctx);
88
89 ctx->needs_flush = false;
90 ctx->cleared = ctx->restore = ctx->resolve = 0;
91
92 fd_resource(pfb->cbufs[0]->texture)->dirty = false;
93 if (pfb->zsbuf)
94 fd_resource(pfb->zsbuf->texture)->dirty = false;
95 }
96
97 static void
98 fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
99 unsigned flags)
100 {
101 DBG("fence=%p", fence);
102
103 #if 0
104 if (fence) {
105 fd_fence_ref(ctx->screen->fence.current,
106 (struct fd_fence **)fence);
107 }
108 #endif
109
110 fd_context_render(pctx);
111 fd_context_wait(pctx);
112 }
113
114 static void
115 fd_context_destroy(struct pipe_context *pctx)
116 {
117 struct fd_context *ctx = fd_context(pctx);
118
119 DBG("");
120
121 if (ctx->blitter)
122 util_blitter_destroy(ctx->blitter);
123
124 fd_ringmarker_del(ctx->draw_start);
125 fd_ringmarker_del(ctx->draw_end);
126 fd_ringbuffer_del(ctx->ring);
127
128 fd_prog_fini(pctx);
129
130 FREE(ctx);
131 }
132
133 static struct pipe_resource *
134 create_solid_vertexbuf(struct pipe_context *pctx)
135 {
136 static const float init_shader_const[] = {
137 /* for clear/gmem2mem: */
138 -1.000000, +1.000000, +1.000000, +1.100000,
139 +1.000000, +1.000000, -1.000000, -1.100000,
140 +1.000000, +1.100000, -1.100000, +1.000000,
141 /* for mem2gmem: (vertices) */
142 -1.000000, +1.000000, +1.000000, +1.000000,
143 +1.000000, +1.000000, -1.000000, -1.000000,
144 +1.000000, +1.000000, -1.000000, +1.000000,
145 /* for mem2gmem: (tex coords) */
146 +0.000000, +0.000000, +1.000000, +0.000000,
147 +0.000000, +1.000000, +1.000000, +1.000000,
148 };
149 struct pipe_resource *prsc = pipe_buffer_create(pctx->screen,
150 PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, sizeof(init_shader_const));
151 pipe_buffer_write(pctx, prsc, 0,
152 sizeof(init_shader_const), init_shader_const);
153 return prsc;
154 }
155
156 struct pipe_context *
157 fd_context_create(struct pipe_screen *pscreen, void *priv)
158 {
159 struct fd_screen *screen = fd_screen(pscreen);
160 struct fd_context *ctx = CALLOC_STRUCT(fd_context);
161 struct pipe_context *pctx;
162
163 if (!ctx)
164 return NULL;
165
166 DBG("");
167
168 ctx->screen = screen;
169
170 ctx->ring = fd_ringbuffer_new(screen->pipe, 0x100000);
171 ctx->draw_start = fd_ringmarker_new(ctx->ring);
172 ctx->draw_end = fd_ringmarker_new(ctx->ring);
173
174 pctx = &ctx->base;
175 pctx->screen = pscreen;
176 pctx->priv = priv;
177 pctx->flush = fd_context_flush;
178 pctx->destroy = fd_context_destroy;
179
180 util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer),
181 16, UTIL_SLAB_SINGLETHREADED);
182
183 fd_vbo_init(pctx);
184 fd_blend_init(pctx);
185 fd_rasterizer_init(pctx);
186 fd_zsa_init(pctx);
187 fd_state_init(pctx);
188 fd_resource_context_init(pctx);
189 fd_clear_init(pctx);
190 fd_prog_init(pctx);
191 fd_texture_init(pctx);
192
193 ctx->blitter = util_blitter_create(pctx);
194 if (!ctx->blitter) {
195 fd_context_destroy(pctx);
196 return NULL;
197 }
198
199 /* construct vertex state used for solid ops (clear, and gmem<->mem) */
200 ctx->solid_vertexbuf = create_solid_vertexbuf(pctx);
201
202 fd_state_emit_setup(pctx);
203
204 return pctx;
205 }