1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
4 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
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:
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
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
26 * Rob Clark <robclark@freedesktop.org>
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"
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
53 fd_context_wait(struct pipe_context
*pctx
)
55 struct fd_context
*ctx
= fd_context(pctx
);
56 uint32_t ts
= fd_ringbuffer_timestamp(ctx
->ring
);
60 fd_pipe_wait(ctx
->screen
->pipe
, ts
);
61 fd_ringbuffer_reset(ctx
->ring
);
62 fd_ringmarker_mark(ctx
->draw_start
);
65 /* emit accumulated render cmds, needed for example if render target has
66 * changed, or for flush()
69 fd_context_render(struct pipe_context
*pctx
)
71 struct fd_context
*ctx
= fd_context(pctx
);
72 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
74 DBG("needs_flush: %d", ctx
->needs_flush
);
76 if (!ctx
->needs_flush
)
79 fd_gmem_render_tiles(pctx
);
81 DBG("%p/%p/%p", ctx
->ring
->start
, ctx
->ring
->cur
, ctx
->ring
->end
);
83 /* if size in dwords is more than half the buffer size, then wait and
86 if ((ctx
->ring
->cur
- ctx
->ring
->start
) > ctx
->ring
->size
/8)
87 fd_context_wait(pctx
);
89 ctx
->needs_flush
= false;
90 ctx
->cleared
= ctx
->restore
= ctx
->resolve
= 0;
92 fd_resource(pfb
->cbufs
[0]->texture
)->dirty
= false;
94 fd_resource(pfb
->zsbuf
->texture
)->dirty
= false;
98 fd_context_flush(struct pipe_context
*pctx
, struct pipe_fence_handle
**fence
,
101 DBG("fence=%p", fence
);
105 fd_fence_ref(ctx
->screen
->fence
.current
,
106 (struct fd_fence
**)fence
);
110 fd_context_render(pctx
);
111 fd_context_wait(pctx
);
115 fd_context_destroy(struct pipe_context
*pctx
)
117 struct fd_context
*ctx
= fd_context(pctx
);
122 util_blitter_destroy(ctx
->blitter
);
124 fd_ringmarker_del(ctx
->draw_start
);
125 fd_ringmarker_del(ctx
->draw_end
);
126 fd_ringbuffer_del(ctx
->ring
);
133 static struct pipe_resource
*
134 create_solid_vertexbuf(struct pipe_context
*pctx
)
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,
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
);
156 struct pipe_context
*
157 fd_context_create(struct pipe_screen
*pscreen
, void *priv
)
159 struct fd_screen
*screen
= fd_screen(pscreen
);
160 struct fd_context
*ctx
= CALLOC_STRUCT(fd_context
);
161 struct pipe_context
*pctx
;
168 ctx
->screen
= screen
;
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
);
175 pctx
->screen
= pscreen
;
177 pctx
->flush
= fd_context_flush
;
178 pctx
->destroy
= fd_context_destroy
;
180 util_slab_create(&ctx
->transfer_pool
, sizeof(struct pipe_transfer
),
181 16, UTIL_SLAB_SINGLETHREADED
);
185 fd_rasterizer_init(pctx
);
188 fd_resource_context_init(pctx
);
191 fd_texture_init(pctx
);
193 ctx
->blitter
= util_blitter_create(pctx
);
195 fd_context_destroy(pctx
);
199 /* construct vertex state used for solid ops (clear, and gmem<->mem) */
200 ctx
->solid_vertexbuf
= create_solid_vertexbuf(pctx
);
202 fd_state_emit_setup(pctx
);