freedreno_context.c revision 848b8605
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_draw.h" 31#include "freedreno_program.h" 32#include "freedreno_resource.h" 33#include "freedreno_texture.h" 34#include "freedreno_state.h" 35#include "freedreno_gmem.h" 36#include "freedreno_query.h" 37#include "freedreno_query_hw.h" 38#include "freedreno_util.h" 39 40static struct fd_ringbuffer *next_rb(struct fd_context *ctx) 41{ 42 struct fd_ringbuffer *ring; 43 uint32_t ts; 44 45 /* grab next ringbuffer: */ 46 ring = ctx->rings[(ctx->rings_idx++) % ARRAY_SIZE(ctx->rings)]; 47 48 /* wait for new rb to be idle: */ 49 ts = fd_ringbuffer_timestamp(ring); 50 if (ts) { 51 DBG("wait: %u", ts); 52 fd_pipe_wait(ctx->screen->pipe, ts); 53 } 54 55 fd_ringbuffer_reset(ring); 56 57 return ring; 58} 59 60static void 61fd_context_next_rb(struct pipe_context *pctx) 62{ 63 struct fd_context *ctx = fd_context(pctx); 64 struct fd_ringbuffer *ring; 65 66 fd_ringmarker_del(ctx->draw_start); 67 fd_ringmarker_del(ctx->draw_end); 68 69 ring = next_rb(ctx); 70 71 ctx->draw_start = fd_ringmarker_new(ring); 72 ctx->draw_end = fd_ringmarker_new(ring); 73 74 fd_ringbuffer_set_parent(ring, NULL); 75 ctx->ring = ring; 76 77 fd_ringmarker_del(ctx->binning_start); 78 fd_ringmarker_del(ctx->binning_end); 79 80 ring = next_rb(ctx); 81 82 ctx->binning_start = fd_ringmarker_new(ring); 83 ctx->binning_end = fd_ringmarker_new(ring); 84 85 fd_ringbuffer_set_parent(ring, ctx->ring); 86 ctx->binning_ring = ring; 87} 88 89/* emit accumulated render cmds, needed for example if render target has 90 * changed, or for flush() 91 */ 92void 93fd_context_render(struct pipe_context *pctx) 94{ 95 struct fd_context *ctx = fd_context(pctx); 96 struct pipe_framebuffer_state *pfb = &ctx->framebuffer; 97 98 DBG("needs_flush: %d", ctx->needs_flush); 99 100 if (!ctx->needs_flush) 101 return; 102 103 fd_gmem_render_tiles(ctx); 104 105 DBG("%p/%p/%p", ctx->ring->start, ctx->ring->cur, ctx->ring->end); 106 107 /* if size in dwords is more than half the buffer size, then wait and 108 * wrap around: 109 */ 110 if ((ctx->ring->cur - ctx->ring->start) > ctx->ring->size/8) 111 fd_context_next_rb(pctx); 112 113 ctx->needs_flush = false; 114 ctx->cleared = ctx->partial_cleared = ctx->restore = ctx->resolve = 0; 115 ctx->gmem_reason = 0; 116 ctx->num_draws = 0; 117 118 if (pfb->cbufs[0]) 119 fd_resource(pfb->cbufs[0]->texture)->dirty = false; 120 if (pfb->zsbuf) 121 fd_resource(pfb->zsbuf->texture)->dirty = false; 122} 123 124static void 125fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, 126 unsigned flags) 127{ 128 DBG("fence=%p", fence); 129 130#if 0 131 if (fence) { 132 fd_fence_ref(ctx->screen->fence.current, 133 (struct fd_fence **)fence); 134 } 135#endif 136 137 fd_context_render(pctx); 138} 139 140void 141fd_context_destroy(struct pipe_context *pctx) 142{ 143 struct fd_context *ctx = fd_context(pctx); 144 unsigned i; 145 146 DBG(""); 147 148 fd_prog_fini(pctx); 149 fd_hw_query_fini(pctx); 150 151 util_dynarray_fini(&ctx->draw_patches); 152 153 if (ctx->blitter) 154 util_blitter_destroy(ctx->blitter); 155 156 if (ctx->primconvert) 157 util_primconvert_destroy(ctx->primconvert); 158 159 util_slab_destroy(&ctx->transfer_pool); 160 161 fd_ringmarker_del(ctx->draw_start); 162 fd_ringmarker_del(ctx->draw_end); 163 fd_ringmarker_del(ctx->binning_start); 164 fd_ringmarker_del(ctx->binning_end); 165 166 for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) 167 fd_ringbuffer_del(ctx->rings[i]); 168 169 for (i = 0; i < ARRAY_SIZE(ctx->pipe); i++) { 170 struct fd_vsc_pipe *pipe = &ctx->pipe[i]; 171 if (!pipe->bo) 172 break; 173 fd_bo_del(pipe->bo); 174 } 175 176 fd_device_del(ctx->dev); 177 178 FREE(ctx); 179} 180 181struct pipe_context * 182fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, 183 const uint8_t *primtypes, void *priv) 184{ 185 struct fd_screen *screen = fd_screen(pscreen); 186 struct pipe_context *pctx; 187 int i; 188 189 ctx->screen = screen; 190 191 ctx->primtypes = primtypes; 192 ctx->primtype_mask = 0; 193 for (i = 0; i < PIPE_PRIM_MAX; i++) 194 if (primtypes[i]) 195 ctx->primtype_mask |= (1 << i); 196 197 /* need some sane default in case state tracker doesn't 198 * set some state: 199 */ 200 ctx->sample_mask = 0xffff; 201 202 pctx = &ctx->base; 203 pctx->screen = pscreen; 204 pctx->priv = priv; 205 pctx->flush = fd_context_flush; 206 207 for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) { 208 ctx->rings[i] = fd_ringbuffer_new(screen->pipe, 0x100000); 209 if (!ctx->rings[i]) 210 goto fail; 211 } 212 213 fd_context_next_rb(pctx); 214 fd_reset_wfi(ctx); 215 216 util_dynarray_init(&ctx->draw_patches); 217 218 util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer), 219 16, UTIL_SLAB_SINGLETHREADED); 220 221 fd_draw_init(pctx); 222 fd_resource_context_init(pctx); 223 fd_query_context_init(pctx); 224 fd_texture_init(pctx); 225 fd_state_init(pctx); 226 fd_hw_query_init(pctx); 227 228 ctx->blitter = util_blitter_create(pctx); 229 if (!ctx->blitter) 230 goto fail; 231 232 ctx->primconvert = util_primconvert_create(pctx, ctx->primtype_mask); 233 if (!ctx->primconvert) 234 goto fail; 235 236 return pctx; 237 238fail: 239 pctx->destroy(pctx); 240 return NULL; 241} 242