Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv30/nv30_context.c
4574 views
/*1* Copyright 2012 Red Hat Inc.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*21* Authors: Ben Skeggs22*23*/2425#include "draw/draw_context.h"26#include "util/u_upload_mgr.h"2728#include "nv_object.xml.h"29#include "nv30/nv30-40_3d.xml.h"3031#include "nouveau_fence.h"32#include "nv30/nv30_context.h"33#include "nv30/nv30_transfer.h"34#include "nv30/nv30_state.h"3536static void37nv30_context_kick_notify(struct nouveau_pushbuf *push)38{39struct nouveau_screen *screen;40struct nv30_context *nv30;4142if (!push->user_priv)43return;44nv30 = container_of(push->user_priv, struct nv30_context, bufctx);45screen = &nv30->screen->base;4647nouveau_fence_next(screen);48nouveau_fence_update(screen, true);4950if (push->bufctx) {51struct nouveau_bufref *bref;52LIST_FOR_EACH_ENTRY(bref, &push->bufctx->current, thead) {53struct nv04_resource *res = bref->priv;54if (res && res->mm) {55nouveau_fence_ref(screen->fence.current, &res->fence);5657if (bref->flags & NOUVEAU_BO_RD)58res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;5960if (bref->flags & NOUVEAU_BO_WR) {61nouveau_fence_ref(screen->fence.current, &res->fence_wr);62res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |63NOUVEAU_BUFFER_STATUS_DIRTY;64}65}66}67}68}6970static void71nv30_context_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence,72unsigned flags)73{74struct nv30_context *nv30 = nv30_context(pipe);75struct nouveau_pushbuf *push = nv30->base.pushbuf;7677if (fence)78nouveau_fence_ref(nv30->screen->base.fence.current,79(struct nouveau_fence **)fence);8081PUSH_KICK(push);8283nouveau_context_update_frame_stats(&nv30->base);84}8586static int87nv30_invalidate_resource_storage(struct nouveau_context *nv,88struct pipe_resource *res,89int ref)90{91struct nv30_context *nv30 = nv30_context(&nv->pipe);92unsigned i;9394if (res->bind & PIPE_BIND_RENDER_TARGET) {95for (i = 0; i < nv30->framebuffer.nr_cbufs; ++i) {96if (nv30->framebuffer.cbufs[i] &&97nv30->framebuffer.cbufs[i]->texture == res) {98nv30->dirty |= NV30_NEW_FRAMEBUFFER;99nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FB);100if (!--ref)101return ref;102}103}104}105if (res->bind & PIPE_BIND_DEPTH_STENCIL) {106if (nv30->framebuffer.zsbuf &&107nv30->framebuffer.zsbuf->texture == res) {108nv30->dirty |= NV30_NEW_FRAMEBUFFER;109nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FB);110if (!--ref)111return ref;112}113}114115if (res->bind & PIPE_BIND_VERTEX_BUFFER) {116for (i = 0; i < nv30->num_vtxbufs; ++i) {117if (nv30->vtxbuf[i].buffer.resource == res) {118nv30->dirty |= NV30_NEW_ARRAYS;119nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);120if (!--ref)121return ref;122}123}124}125126if (res->bind & PIPE_BIND_SAMPLER_VIEW) {127for (i = 0; i < nv30->fragprog.num_textures; ++i) {128if (nv30->fragprog.textures[i] &&129nv30->fragprog.textures[i]->texture == res) {130nv30->dirty |= NV30_NEW_FRAGTEX;131nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FRAGTEX(i));132if (!--ref)133return ref;134}135}136for (i = 0; i < nv30->vertprog.num_textures; ++i) {137if (nv30->vertprog.textures[i] &&138nv30->vertprog.textures[i]->texture == res) {139nv30->dirty |= NV30_NEW_VERTTEX;140nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VERTTEX(i));141if (!--ref)142return ref;143}144}145}146147return ref;148}149150static void151nv30_context_destroy(struct pipe_context *pipe)152{153struct nv30_context *nv30 = nv30_context(pipe);154155if (nv30->blitter)156util_blitter_destroy(nv30->blitter);157158if (nv30->draw)159draw_destroy(nv30->draw);160161if (nv30->base.pipe.stream_uploader)162u_upload_destroy(nv30->base.pipe.stream_uploader);163164if (nv30->blit_vp)165nouveau_heap_free(&nv30->blit_vp);166167if (nv30->blit_fp)168pipe_resource_reference(&nv30->blit_fp, NULL);169170if (nv30->screen->base.pushbuf->user_priv == &nv30->bufctx)171nv30->screen->base.pushbuf->user_priv = NULL;172173nouveau_bufctx_del(&nv30->bufctx);174175if (nv30->screen->cur_ctx == nv30)176nv30->screen->cur_ctx = NULL;177178nouveau_context_destroy(&nv30->base);179}180181#define FAIL_CONTEXT_INIT(str, err) \182do { \183NOUVEAU_ERR(str, err); \184nv30_context_destroy(pipe); \185return NULL; \186} while(0)187188struct pipe_context *189nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)190{191struct nv30_screen *screen = nv30_screen(pscreen);192struct nv30_context *nv30 = CALLOC_STRUCT(nv30_context);193struct nouveau_pushbuf *push;194struct pipe_context *pipe;195int ret;196197if (!nv30)198return NULL;199200nv30->screen = screen;201nv30->base.screen = &screen->base;202nv30->base.copy_data = nv30_transfer_copy_data;203204pipe = &nv30->base.pipe;205pipe->screen = pscreen;206pipe->priv = priv;207pipe->destroy = nv30_context_destroy;208pipe->flush = nv30_context_flush;209210nv30->base.pipe.stream_uploader = u_upload_create_default(&nv30->base.pipe);211if (!nv30->base.pipe.stream_uploader) {212nv30_context_destroy(pipe);213return NULL;214}215nv30->base.pipe.const_uploader = nv30->base.pipe.stream_uploader;216217/*XXX: *cough* per-context client */218nv30->base.client = screen->base.client;219220/*XXX: *cough* per-context pushbufs */221push = screen->base.pushbuf;222nv30->base.pushbuf = push;223push->kick_notify = nv30_context_kick_notify;224225nv30->base.invalidate_resource_storage = nv30_invalidate_resource_storage;226227ret = nouveau_bufctx_new(nv30->base.client, 64, &nv30->bufctx);228if (ret) {229nv30_context_destroy(pipe);230return NULL;231}232233/*XXX: make configurable with performance vs quality, these defaults234* match the binary driver's defaults235*/236if (screen->eng3d->oclass < NV40_3D_CLASS)237nv30->config.filter = 0x00000004;238else239nv30->config.filter = 0x00002dc4;240241nv30->config.aniso = NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION_OFF;242243if (debug_get_bool_option("NV30_SWTNL", false))244nv30->draw_flags |= NV30_NEW_SWTNL;245246nouveau_context_init(&nv30->base);247nv30->sample_mask = 0xffff;248nv30_vbo_init(pipe);249nv30_query_init(pipe);250nv30_state_init(pipe);251nv30_resource_init(pipe);252nv30_clear_init(pipe);253nv30_fragprog_init(pipe);254nv30_vertprog_init(pipe);255nv30_texture_init(pipe);256nv30_fragtex_init(pipe);257nv40_verttex_init(pipe);258nv30_draw_init(pipe);259260nv30->blitter = util_blitter_create(pipe);261if (!nv30->blitter) {262nv30_context_destroy(pipe);263return NULL;264}265266nouveau_context_init_vdec(&nv30->base);267268return pipe;269}270271272