1848b8605Smrg/* 2848b8605Smrg * Copyright © 2014 Broadcom 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 9848b8605Smrg * Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice (including the next 12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 13848b8605Smrg * Software. 14848b8605Smrg * 15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21848b8605Smrg * IN THE SOFTWARE. 22848b8605Smrg */ 23848b8605Smrg 24848b8605Smrg#include <xf86drm.h> 25848b8605Smrg#include <err.h> 26848b8605Smrg 27848b8605Smrg#include "pipe/p_defines.h" 28b8e80941Smrg#include "util/ralloc.h" 29848b8605Smrg#include "util/u_inlines.h" 30848b8605Smrg#include "util/u_memory.h" 31848b8605Smrg#include "util/u_blitter.h" 32b8e80941Smrg#include "util/u_upload_mgr.h" 33848b8605Smrg#include "indices/u_primconvert.h" 34848b8605Smrg#include "pipe/p_screen.h" 35848b8605Smrg 36848b8605Smrg#include "vc4_screen.h" 37848b8605Smrg#include "vc4_context.h" 38848b8605Smrg#include "vc4_resource.h" 39848b8605Smrg 40b8e80941Smrgvoid 41b8e80941Smrgvc4_flush(struct pipe_context *pctx) 42848b8605Smrg{ 43b8e80941Smrg struct vc4_context *vc4 = vc4_context(pctx); 44848b8605Smrg 45b8e80941Smrg hash_table_foreach(vc4->jobs, entry) { 46b8e80941Smrg struct vc4_job *job = entry->data; 47b8e80941Smrg vc4_job_submit(vc4, job); 48848b8605Smrg } 49848b8605Smrg} 50848b8605Smrg 51b8e80941Smrgstatic void 52b8e80941Smrgvc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, 53b8e80941Smrg unsigned flags) 54848b8605Smrg{ 55848b8605Smrg struct vc4_context *vc4 = vc4_context(pctx); 56848b8605Smrg 57b8e80941Smrg vc4_flush(pctx); 58848b8605Smrg 59b8e80941Smrg if (fence) { 60b8e80941Smrg struct pipe_screen *screen = pctx->screen; 61b8e80941Smrg int fd = -1; 62848b8605Smrg 63b8e80941Smrg if (flags & PIPE_FLUSH_FENCE_FD) { 64b8e80941Smrg /* The vc4_fence takes ownership of the returned fd. */ 65b8e80941Smrg drmSyncobjExportSyncFile(vc4->fd, vc4->job_syncobj, 66b8e80941Smrg &fd); 67b8e80941Smrg } 68b8e80941Smrg 69b8e80941Smrg struct vc4_fence *f = vc4_fence_create(vc4->screen, 70b8e80941Smrg vc4->last_emit_seqno, 71b8e80941Smrg fd); 72b8e80941Smrg screen->fence_reference(screen, fence, NULL); 73b8e80941Smrg *fence = (struct pipe_fence_handle *)f; 74b8e80941Smrg } 75848b8605Smrg} 76848b8605Smrg 77b8e80941Smrg/* We can't flush the texture cache within rendering a tile, so we have to 78b8e80941Smrg * flush all rendering to the kernel so that the next job reading from the 79b8e80941Smrg * tile gets a flushed cache. 80b8e80941Smrg */ 81848b8605Smrgstatic void 82b8e80941Smrgvc4_texture_barrier(struct pipe_context *pctx, unsigned flags) 83848b8605Smrg{ 84848b8605Smrg vc4_flush(pctx); 85848b8605Smrg} 86848b8605Smrg 87b8e80941Smrgstatic void 88b8e80941Smrgvc4_set_debug_callback(struct pipe_context *pctx, 89b8e80941Smrg const struct pipe_debug_callback *cb) 90848b8605Smrg{ 91848b8605Smrg struct vc4_context *vc4 = vc4_context(pctx); 92848b8605Smrg 93b8e80941Smrg if (cb) 94b8e80941Smrg vc4->debug = *cb; 95b8e80941Smrg else 96b8e80941Smrg memset(&vc4->debug, 0, sizeof(vc4->debug)); 97b8e80941Smrg} 98848b8605Smrg 99b8e80941Smrgstatic void 100b8e80941Smrgvc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc) 101b8e80941Smrg{ 102b8e80941Smrg struct vc4_context *vc4 = vc4_context(pctx); 103b8e80941Smrg struct vc4_resource *rsc = vc4_resource(prsc); 104848b8605Smrg 105b8e80941Smrg rsc->initialized_buffers = 0; 106848b8605Smrg 107b8e80941Smrg struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs, 108b8e80941Smrg prsc); 109b8e80941Smrg if (!entry) 110b8e80941Smrg return; 111b8e80941Smrg 112b8e80941Smrg struct vc4_job *job = entry->data; 113b8e80941Smrg if (job->key.zsbuf && job->key.zsbuf->texture == prsc) 114b8e80941Smrg job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL); 115848b8605Smrg} 116848b8605Smrg 117848b8605Smrgstatic void 118848b8605Smrgvc4_context_destroy(struct pipe_context *pctx) 119848b8605Smrg{ 120848b8605Smrg struct vc4_context *vc4 = vc4_context(pctx); 121848b8605Smrg 122b8e80941Smrg vc4_flush(pctx); 123b8e80941Smrg 124848b8605Smrg if (vc4->blitter) 125848b8605Smrg util_blitter_destroy(vc4->blitter); 126848b8605Smrg 127848b8605Smrg if (vc4->primconvert) 128848b8605Smrg util_primconvert_destroy(vc4->primconvert); 129848b8605Smrg 130b8e80941Smrg if (vc4->uploader) 131b8e80941Smrg u_upload_destroy(vc4->uploader); 132b8e80941Smrg 133b8e80941Smrg slab_destroy_child(&vc4->transfer_pool); 134848b8605Smrg 135b8e80941Smrg pipe_surface_reference(&vc4->framebuffer.cbufs[0], NULL); 136b8e80941Smrg pipe_surface_reference(&vc4->framebuffer.zsbuf, NULL); 137b8e80941Smrg 138b8e80941Smrg if (vc4->yuv_linear_blit_vs) 139b8e80941Smrg pctx->delete_vs_state(pctx, vc4->yuv_linear_blit_vs); 140b8e80941Smrg if (vc4->yuv_linear_blit_fs_8bit) 141b8e80941Smrg pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_8bit); 142b8e80941Smrg if (vc4->yuv_linear_blit_fs_16bit) 143b8e80941Smrg pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_16bit); 144b8e80941Smrg 145b8e80941Smrg vc4_program_fini(pctx); 146b8e80941Smrg 147b8e80941Smrg if (vc4->screen->has_syncobj) { 148b8e80941Smrg drmSyncobjDestroy(vc4->fd, vc4->job_syncobj); 149b8e80941Smrg drmSyncobjDestroy(vc4->fd, vc4->in_syncobj); 150b8e80941Smrg } 151b8e80941Smrg if (vc4->in_fence_fd >= 0) 152b8e80941Smrg close(vc4->in_fence_fd); 153b8e80941Smrg 154b8e80941Smrg ralloc_free(vc4); 155848b8605Smrg} 156848b8605Smrg 157848b8605Smrgstruct pipe_context * 158b8e80941Smrgvc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) 159848b8605Smrg{ 160848b8605Smrg struct vc4_screen *screen = vc4_screen(pscreen); 161848b8605Smrg struct vc4_context *vc4; 162b8e80941Smrg int err; 163848b8605Smrg 164848b8605Smrg /* Prevent dumping of the shaders built during context setup. */ 165848b8605Smrg uint32_t saved_shaderdb_flag = vc4_debug & VC4_DEBUG_SHADERDB; 166848b8605Smrg vc4_debug &= ~VC4_DEBUG_SHADERDB; 167848b8605Smrg 168b8e80941Smrg vc4 = rzalloc(NULL, struct vc4_context); 169b8e80941Smrg if (!vc4) 170848b8605Smrg return NULL; 171848b8605Smrg struct pipe_context *pctx = &vc4->base; 172848b8605Smrg 173848b8605Smrg vc4->screen = screen; 174848b8605Smrg 175848b8605Smrg pctx->screen = pscreen; 176848b8605Smrg pctx->priv = priv; 177848b8605Smrg pctx->destroy = vc4_context_destroy; 178848b8605Smrg pctx->flush = vc4_pipe_flush; 179b8e80941Smrg pctx->set_debug_callback = vc4_set_debug_callback; 180b8e80941Smrg pctx->invalidate_resource = vc4_invalidate_resource; 181b8e80941Smrg pctx->texture_barrier = vc4_texture_barrier; 182848b8605Smrg 183848b8605Smrg vc4_draw_init(pctx); 184848b8605Smrg vc4_state_init(pctx); 185848b8605Smrg vc4_program_init(pctx); 186b8e80941Smrg vc4_query_init(pctx); 187848b8605Smrg vc4_resource_context_init(pctx); 188848b8605Smrg 189848b8605Smrg vc4->fd = screen->fd; 190848b8605Smrg 191b8e80941Smrg err = vc4_job_init(vc4); 192b8e80941Smrg if (err) 193b8e80941Smrg goto fail; 194b8e80941Smrg 195b8e80941Smrg err = vc4_fence_context_init(vc4); 196b8e80941Smrg if (err) 197b8e80941Smrg goto fail; 198b8e80941Smrg 199b8e80941Smrg slab_create_child(&vc4->transfer_pool, &screen->transfer_pool); 200b8e80941Smrg 201b8e80941Smrg vc4->uploader = u_upload_create_default(&vc4->base); 202b8e80941Smrg vc4->base.stream_uploader = vc4->uploader; 203b8e80941Smrg vc4->base.const_uploader = vc4->uploader; 204b8e80941Smrg 205b8e80941Smrg vc4->blitter = util_blitter_create(pctx); 206848b8605Smrg if (!vc4->blitter) 207848b8605Smrg goto fail; 208848b8605Smrg 209848b8605Smrg vc4->primconvert = util_primconvert_create(pctx, 210848b8605Smrg (1 << PIPE_PRIM_QUADS) - 1); 211848b8605Smrg if (!vc4->primconvert) 212848b8605Smrg goto fail; 213848b8605Smrg 214848b8605Smrg vc4_debug |= saved_shaderdb_flag; 215848b8605Smrg 216b8e80941Smrg vc4->sample_mask = (1 << VC4_MAX_SAMPLES) - 1; 217b8e80941Smrg 218848b8605Smrg return &vc4->base; 219848b8605Smrg 220848b8605Smrgfail: 221848b8605Smrg pctx->destroy(pctx); 222848b8605Smrg return NULL; 223848b8605Smrg} 224