vc4_context.c revision 01e04c3f
1/* 2 * Copyright © 2014 Broadcom 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 (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include <xf86drm.h> 25#include <err.h> 26 27#include "pipe/p_defines.h" 28#include "util/ralloc.h" 29#include "util/u_inlines.h" 30#include "util/u_memory.h" 31#include "util/u_blitter.h" 32#include "util/u_upload_mgr.h" 33#include "indices/u_primconvert.h" 34#include "pipe/p_screen.h" 35 36#include "vc4_screen.h" 37#include "vc4_context.h" 38#include "vc4_resource.h" 39 40void 41vc4_flush(struct pipe_context *pctx) 42{ 43 struct vc4_context *vc4 = vc4_context(pctx); 44 45 hash_table_foreach(vc4->jobs, entry) { 46 struct vc4_job *job = entry->data; 47 vc4_job_submit(vc4, job); 48 } 49} 50 51static void 52vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, 53 unsigned flags) 54{ 55 struct vc4_context *vc4 = vc4_context(pctx); 56 57 vc4_flush(pctx); 58 59 if (fence) { 60 struct pipe_screen *screen = pctx->screen; 61 int fd = -1; 62 63 if (flags & PIPE_FLUSH_FENCE_FD) { 64 /* The vc4_fence takes ownership of the returned fd. */ 65 drmSyncobjExportSyncFile(vc4->fd, vc4->job_syncobj, 66 &fd); 67 } 68 69 struct vc4_fence *f = vc4_fence_create(vc4->screen, 70 vc4->last_emit_seqno, 71 fd); 72 screen->fence_reference(screen, fence, NULL); 73 *fence = (struct pipe_fence_handle *)f; 74 } 75} 76 77/* We can't flush the texture cache within rendering a tile, so we have to 78 * flush all rendering to the kernel so that the next job reading from the 79 * tile gets a flushed cache. 80 */ 81static void 82vc4_texture_barrier(struct pipe_context *pctx, unsigned flags) 83{ 84 vc4_flush(pctx); 85} 86 87static void 88vc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc) 89{ 90 struct vc4_context *vc4 = vc4_context(pctx); 91 struct vc4_resource *rsc = vc4_resource(prsc); 92 93 rsc->initialized_buffers = 0; 94 95 struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs, 96 prsc); 97 if (!entry) 98 return; 99 100 struct vc4_job *job = entry->data; 101 if (job->key.zsbuf && job->key.zsbuf->texture == prsc) 102 job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL); 103} 104 105static void 106vc4_context_destroy(struct pipe_context *pctx) 107{ 108 struct vc4_context *vc4 = vc4_context(pctx); 109 110 vc4_flush(pctx); 111 112 if (vc4->blitter) 113 util_blitter_destroy(vc4->blitter); 114 115 if (vc4->primconvert) 116 util_primconvert_destroy(vc4->primconvert); 117 118 if (vc4->uploader) 119 u_upload_destroy(vc4->uploader); 120 121 slab_destroy_child(&vc4->transfer_pool); 122 123 pipe_surface_reference(&vc4->framebuffer.cbufs[0], NULL); 124 pipe_surface_reference(&vc4->framebuffer.zsbuf, NULL); 125 126 if (vc4->yuv_linear_blit_vs) 127 pctx->delete_vs_state(pctx, vc4->yuv_linear_blit_vs); 128 if (vc4->yuv_linear_blit_fs_8bit) 129 pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_8bit); 130 if (vc4->yuv_linear_blit_fs_16bit) 131 pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_16bit); 132 133 vc4_program_fini(pctx); 134 135 if (vc4->screen->has_syncobj) { 136 drmSyncobjDestroy(vc4->fd, vc4->job_syncobj); 137 drmSyncobjDestroy(vc4->fd, vc4->in_syncobj); 138 } 139 if (vc4->in_fence_fd >= 0) 140 close(vc4->in_fence_fd); 141 142 ralloc_free(vc4); 143} 144 145struct pipe_context * 146vc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) 147{ 148 struct vc4_screen *screen = vc4_screen(pscreen); 149 struct vc4_context *vc4; 150 int err; 151 152 /* Prevent dumping of the shaders built during context setup. */ 153 uint32_t saved_shaderdb_flag = vc4_debug & VC4_DEBUG_SHADERDB; 154 vc4_debug &= ~VC4_DEBUG_SHADERDB; 155 156 vc4 = rzalloc(NULL, struct vc4_context); 157 if (!vc4) 158 return NULL; 159 struct pipe_context *pctx = &vc4->base; 160 161 vc4->screen = screen; 162 163 pctx->screen = pscreen; 164 pctx->priv = priv; 165 pctx->destroy = vc4_context_destroy; 166 pctx->flush = vc4_pipe_flush; 167 pctx->invalidate_resource = vc4_invalidate_resource; 168 pctx->texture_barrier = vc4_texture_barrier; 169 170 vc4_draw_init(pctx); 171 vc4_state_init(pctx); 172 vc4_program_init(pctx); 173 vc4_query_init(pctx); 174 vc4_resource_context_init(pctx); 175 176 vc4->fd = screen->fd; 177 178 err = vc4_job_init(vc4); 179 if (err) 180 goto fail; 181 182 err = vc4_fence_context_init(vc4); 183 if (err) 184 goto fail; 185 186 slab_create_child(&vc4->transfer_pool, &screen->transfer_pool); 187 188 vc4->uploader = u_upload_create_default(&vc4->base); 189 vc4->base.stream_uploader = vc4->uploader; 190 vc4->base.const_uploader = vc4->uploader; 191 192 vc4->blitter = util_blitter_create(pctx); 193 if (!vc4->blitter) 194 goto fail; 195 196 vc4->primconvert = util_primconvert_create(pctx, 197 (1 << PIPE_PRIM_QUADS) - 1); 198 if (!vc4->primconvert) 199 goto fail; 200 201 vc4_debug |= saved_shaderdb_flag; 202 203 vc4->sample_mask = (1 << VC4_MAX_SAMPLES) - 1; 204 205 return &vc4->base; 206 207fail: 208 pctx->destroy(pctx); 209 return NULL; 210} 211