1af69d88dSmrg/* 2af69d88dSmrg * Copyright © 2014 Broadcom 3af69d88dSmrg * 4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 6af69d88dSmrg * to deal in the Software without restriction, including without limitation 7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 10af69d88dSmrg * 11af69d88dSmrg * The above copyright notice and this permission notice (including the next 12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the 13af69d88dSmrg * Software. 14af69d88dSmrg * 15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21af69d88dSmrg * IN THE SOFTWARE. 22af69d88dSmrg */ 23af69d88dSmrg 24af69d88dSmrg#include <xf86drm.h> 25af69d88dSmrg#include <err.h> 26af69d88dSmrg 27af69d88dSmrg#include "pipe/p_defines.h" 2801e04c3fSmrg#include "util/ralloc.h" 29af69d88dSmrg#include "util/u_inlines.h" 30af69d88dSmrg#include "util/u_memory.h" 31af69d88dSmrg#include "util/u_blitter.h" 3201e04c3fSmrg#include "util/u_upload_mgr.h" 33af69d88dSmrg#include "pipe/p_screen.h" 34af69d88dSmrg 35af69d88dSmrg#include "vc4_screen.h" 36af69d88dSmrg#include "vc4_context.h" 37af69d88dSmrg#include "vc4_resource.h" 38af69d88dSmrg 3901e04c3fSmrgvoid 4001e04c3fSmrgvc4_flush(struct pipe_context *pctx) 41af69d88dSmrg{ 4201e04c3fSmrg struct vc4_context *vc4 = vc4_context(pctx); 43af69d88dSmrg 4401e04c3fSmrg hash_table_foreach(vc4->jobs, entry) { 4501e04c3fSmrg struct vc4_job *job = entry->data; 4601e04c3fSmrg vc4_job_submit(vc4, job); 47af69d88dSmrg } 48af69d88dSmrg} 49af69d88dSmrg 5001e04c3fSmrgstatic void 5101e04c3fSmrgvc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, 5201e04c3fSmrg unsigned flags) 53af69d88dSmrg{ 54af69d88dSmrg struct vc4_context *vc4 = vc4_context(pctx); 55af69d88dSmrg 5601e04c3fSmrg vc4_flush(pctx); 57af69d88dSmrg 5801e04c3fSmrg if (fence) { 5901e04c3fSmrg struct pipe_screen *screen = pctx->screen; 6001e04c3fSmrg int fd = -1; 6101e04c3fSmrg 6201e04c3fSmrg if (flags & PIPE_FLUSH_FENCE_FD) { 6301e04c3fSmrg /* The vc4_fence takes ownership of the returned fd. */ 6401e04c3fSmrg drmSyncobjExportSyncFile(vc4->fd, vc4->job_syncobj, 6501e04c3fSmrg &fd); 6601e04c3fSmrg } 67af69d88dSmrg 6801e04c3fSmrg struct vc4_fence *f = vc4_fence_create(vc4->screen, 6901e04c3fSmrg vc4->last_emit_seqno, 7001e04c3fSmrg fd); 7101e04c3fSmrg screen->fence_reference(screen, fence, NULL); 7201e04c3fSmrg *fence = (struct pipe_fence_handle *)f; 7301e04c3fSmrg } 74af69d88dSmrg} 75af69d88dSmrg 7601e04c3fSmrg/* We can't flush the texture cache within rendering a tile, so we have to 7701e04c3fSmrg * flush all rendering to the kernel so that the next job reading from the 7801e04c3fSmrg * tile gets a flushed cache. 7901e04c3fSmrg */ 80af69d88dSmrgstatic void 8101e04c3fSmrgvc4_texture_barrier(struct pipe_context *pctx, unsigned flags) 82af69d88dSmrg{ 83af69d88dSmrg vc4_flush(pctx); 84af69d88dSmrg} 85af69d88dSmrg 869f464c52Smayastatic void 879f464c52Smayavc4_set_debug_callback(struct pipe_context *pctx, 889f464c52Smaya const struct pipe_debug_callback *cb) 899f464c52Smaya{ 909f464c52Smaya struct vc4_context *vc4 = vc4_context(pctx); 919f464c52Smaya 929f464c52Smaya if (cb) 939f464c52Smaya vc4->debug = *cb; 949f464c52Smaya else 959f464c52Smaya memset(&vc4->debug, 0, sizeof(vc4->debug)); 969f464c52Smaya} 979f464c52Smaya 9801e04c3fSmrgstatic void 9901e04c3fSmrgvc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc) 100af69d88dSmrg{ 101af69d88dSmrg struct vc4_context *vc4 = vc4_context(pctx); 10201e04c3fSmrg struct vc4_resource *rsc = vc4_resource(prsc); 103af69d88dSmrg 10401e04c3fSmrg rsc->initialized_buffers = 0; 105af69d88dSmrg 10601e04c3fSmrg struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs, 10701e04c3fSmrg prsc); 10801e04c3fSmrg if (!entry) 10901e04c3fSmrg return; 110af69d88dSmrg 11101e04c3fSmrg struct vc4_job *job = entry->data; 11201e04c3fSmrg if (job->key.zsbuf && job->key.zsbuf->texture == prsc) 11301e04c3fSmrg job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL); 114af69d88dSmrg} 115af69d88dSmrg 116af69d88dSmrgstatic void 117af69d88dSmrgvc4_context_destroy(struct pipe_context *pctx) 118af69d88dSmrg{ 119af69d88dSmrg struct vc4_context *vc4 = vc4_context(pctx); 120af69d88dSmrg 12101e04c3fSmrg vc4_flush(pctx); 12201e04c3fSmrg 123af69d88dSmrg if (vc4->blitter) 124af69d88dSmrg util_blitter_destroy(vc4->blitter); 125af69d88dSmrg 12601e04c3fSmrg if (vc4->uploader) 12701e04c3fSmrg u_upload_destroy(vc4->uploader); 12801e04c3fSmrg 12901e04c3fSmrg slab_destroy_child(&vc4->transfer_pool); 13001e04c3fSmrg 13101e04c3fSmrg pipe_surface_reference(&vc4->framebuffer.cbufs[0], NULL); 13201e04c3fSmrg pipe_surface_reference(&vc4->framebuffer.zsbuf, NULL); 133af69d88dSmrg 13401e04c3fSmrg if (vc4->yuv_linear_blit_vs) 13501e04c3fSmrg pctx->delete_vs_state(pctx, vc4->yuv_linear_blit_vs); 13601e04c3fSmrg if (vc4->yuv_linear_blit_fs_8bit) 13701e04c3fSmrg pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_8bit); 13801e04c3fSmrg if (vc4->yuv_linear_blit_fs_16bit) 13901e04c3fSmrg pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_16bit); 14001e04c3fSmrg 14101e04c3fSmrg vc4_program_fini(pctx); 14201e04c3fSmrg 14301e04c3fSmrg if (vc4->screen->has_syncobj) { 14401e04c3fSmrg drmSyncobjDestroy(vc4->fd, vc4->job_syncobj); 14501e04c3fSmrg drmSyncobjDestroy(vc4->fd, vc4->in_syncobj); 14601e04c3fSmrg } 14701e04c3fSmrg if (vc4->in_fence_fd >= 0) 14801e04c3fSmrg close(vc4->in_fence_fd); 14901e04c3fSmrg 15001e04c3fSmrg ralloc_free(vc4); 151af69d88dSmrg} 152af69d88dSmrg 153af69d88dSmrgstruct pipe_context * 15401e04c3fSmrgvc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) 155af69d88dSmrg{ 156af69d88dSmrg struct vc4_screen *screen = vc4_screen(pscreen); 157af69d88dSmrg struct vc4_context *vc4; 15801e04c3fSmrg int err; 159af69d88dSmrg 160af69d88dSmrg /* Prevent dumping of the shaders built during context setup. */ 161af69d88dSmrg uint32_t saved_shaderdb_flag = vc4_debug & VC4_DEBUG_SHADERDB; 162af69d88dSmrg vc4_debug &= ~VC4_DEBUG_SHADERDB; 163af69d88dSmrg 16401e04c3fSmrg vc4 = rzalloc(NULL, struct vc4_context); 16501e04c3fSmrg if (!vc4) 166af69d88dSmrg return NULL; 167af69d88dSmrg struct pipe_context *pctx = &vc4->base; 168af69d88dSmrg 169af69d88dSmrg vc4->screen = screen; 170af69d88dSmrg 171af69d88dSmrg pctx->screen = pscreen; 172af69d88dSmrg pctx->priv = priv; 173af69d88dSmrg pctx->destroy = vc4_context_destroy; 174af69d88dSmrg pctx->flush = vc4_pipe_flush; 1759f464c52Smaya pctx->set_debug_callback = vc4_set_debug_callback; 17601e04c3fSmrg pctx->invalidate_resource = vc4_invalidate_resource; 17701e04c3fSmrg pctx->texture_barrier = vc4_texture_barrier; 178af69d88dSmrg 179af69d88dSmrg vc4_draw_init(pctx); 180af69d88dSmrg vc4_state_init(pctx); 181af69d88dSmrg vc4_program_init(pctx); 18201e04c3fSmrg vc4_query_init(pctx); 183af69d88dSmrg vc4_resource_context_init(pctx); 184af69d88dSmrg 185af69d88dSmrg vc4->fd = screen->fd; 186af69d88dSmrg 18701e04c3fSmrg err = vc4_job_init(vc4); 18801e04c3fSmrg if (err) 18901e04c3fSmrg goto fail; 19001e04c3fSmrg 19101e04c3fSmrg err = vc4_fence_context_init(vc4); 19201e04c3fSmrg if (err) 19301e04c3fSmrg goto fail; 19401e04c3fSmrg 19501e04c3fSmrg slab_create_child(&vc4->transfer_pool, &screen->transfer_pool); 19601e04c3fSmrg 19701e04c3fSmrg vc4->uploader = u_upload_create_default(&vc4->base); 19801e04c3fSmrg vc4->base.stream_uploader = vc4->uploader; 19901e04c3fSmrg vc4->base.const_uploader = vc4->uploader; 20001e04c3fSmrg 20101e04c3fSmrg vc4->blitter = util_blitter_create(pctx); 202af69d88dSmrg if (!vc4->blitter) 203af69d88dSmrg goto fail; 204af69d88dSmrg 205af69d88dSmrg vc4_debug |= saved_shaderdb_flag; 206af69d88dSmrg 20701e04c3fSmrg vc4->sample_mask = (1 << VC4_MAX_SAMPLES) - 1; 20801e04c3fSmrg 209af69d88dSmrg return &vc4->base; 210af69d88dSmrg 211af69d88dSmrgfail: 212af69d88dSmrg pctx->destroy(pctx); 213af69d88dSmrg return NULL; 214af69d88dSmrg} 215