1e88f27b3Smrg/* 2e88f27b3Smrg * Copyright 2012 Red Hat Inc. 3e88f27b3Smrg * 4e88f27b3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5e88f27b3Smrg * copy of this software and associated documentation files (the "Software"), 6e88f27b3Smrg * to deal in the Software without restriction, including without limitation 7e88f27b3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8e88f27b3Smrg * and/or sell copies of the Software, and to permit persons to whom the 9e88f27b3Smrg * Software is furnished to do so, subject to the following conditions: 10e88f27b3Smrg * 11e88f27b3Smrg * The above copyright notice and this permission notice shall be included in 12e88f27b3Smrg * all copies or substantial portions of the Software. 13e88f27b3Smrg * 14e88f27b3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15e88f27b3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16e88f27b3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17e88f27b3Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18e88f27b3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19e88f27b3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20e88f27b3Smrg * OTHER DEALINGS IN THE SOFTWARE. 21e88f27b3Smrg * 22e88f27b3Smrg * Authors: Ben Skeggs 23e88f27b3Smrg */ 24e88f27b3Smrg 25e88f27b3Smrg#include <stdio.h> 26e88f27b3Smrg#include <stdlib.h> 27e88f27b3Smrg#include <stdint.h> 28e88f27b3Smrg#include <stdbool.h> 29e88f27b3Smrg#include <assert.h> 30e88f27b3Smrg#include <errno.h> 31e88f27b3Smrg 32e88f27b3Smrg#include "libdrm_lists.h" 33e88f27b3Smrg 34e88f27b3Smrg#include "nouveau.h" 35e88f27b3Smrg#include "private.h" 36e88f27b3Smrg 37e88f27b3Smrgstruct nouveau_bufref_priv { 38e88f27b3Smrg struct nouveau_bufref base; 39e88f27b3Smrg struct nouveau_bufref_priv *next; 40e88f27b3Smrg struct nouveau_bufctx *bufctx; 41e88f27b3Smrg}; 42e88f27b3Smrg 43e88f27b3Smrgstruct nouveau_bufbin_priv { 44e88f27b3Smrg struct nouveau_bufref_priv *list; 45e88f27b3Smrg int relocs; 46e88f27b3Smrg}; 47e88f27b3Smrg 48e88f27b3Smrgstruct nouveau_bufctx_priv { 49e88f27b3Smrg struct nouveau_bufctx base; 50e88f27b3Smrg struct nouveau_bufref_priv *free; 51e88f27b3Smrg int nr_bins; 52e88f27b3Smrg struct nouveau_bufbin_priv bins[]; 53e88f27b3Smrg}; 54e88f27b3Smrg 55e88f27b3Smrgstatic inline struct nouveau_bufctx_priv * 56e88f27b3Smrgnouveau_bufctx(struct nouveau_bufctx *bctx) 57e88f27b3Smrg{ 58e88f27b3Smrg return (struct nouveau_bufctx_priv *)bctx; 59e88f27b3Smrg} 60e88f27b3Smrg 617cdc0497Smrgdrm_public int 62e88f27b3Smrgnouveau_bufctx_new(struct nouveau_client *client, int bins, 63e88f27b3Smrg struct nouveau_bufctx **pbctx) 64e88f27b3Smrg{ 65e88f27b3Smrg struct nouveau_bufctx_priv *priv; 66e88f27b3Smrg 67e88f27b3Smrg priv = calloc(1, sizeof(*priv) + sizeof(priv->bins[0]) * bins); 68e88f27b3Smrg if (priv) { 69e88f27b3Smrg DRMINITLISTHEAD(&priv->base.head); 70e88f27b3Smrg DRMINITLISTHEAD(&priv->base.pending); 71e88f27b3Smrg DRMINITLISTHEAD(&priv->base.current); 72e88f27b3Smrg priv->base.client = client; 73e88f27b3Smrg priv->nr_bins = bins; 74e88f27b3Smrg *pbctx = &priv->base; 75e88f27b3Smrg return 0; 76e88f27b3Smrg } 77e88f27b3Smrg 78e88f27b3Smrg return -ENOMEM; 79e88f27b3Smrg} 80e88f27b3Smrg 817cdc0497Smrgdrm_public void 82e88f27b3Smrgnouveau_bufctx_del(struct nouveau_bufctx **pbctx) 83e88f27b3Smrg{ 84e88f27b3Smrg struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx); 85e88f27b3Smrg struct nouveau_bufref_priv *pref; 86e88f27b3Smrg if (pctx) { 87e88f27b3Smrg while (pctx->nr_bins--) 88e88f27b3Smrg nouveau_bufctx_reset(&pctx->base, pctx->nr_bins); 89e88f27b3Smrg while ((pref = pctx->free)) { 90e88f27b3Smrg pctx->free = pref->next; 91e88f27b3Smrg free(pref); 92e88f27b3Smrg } 93e88f27b3Smrg free(pctx); 94e88f27b3Smrg *pbctx = NULL; 95e88f27b3Smrg } 96e88f27b3Smrg} 97e88f27b3Smrg 987cdc0497Smrgdrm_public void 99e88f27b3Smrgnouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin) 100e88f27b3Smrg{ 101e88f27b3Smrg struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx); 102e88f27b3Smrg struct nouveau_bufbin_priv *pbin = &pctx->bins[bin]; 103e88f27b3Smrg struct nouveau_bufref_priv *pref; 104e88f27b3Smrg 105e88f27b3Smrg while ((pref = pbin->list)) { 106e88f27b3Smrg DRMLISTDELINIT(&pref->base.thead); 107e88f27b3Smrg pbin->list = pref->next; 108e88f27b3Smrg pref->next = pctx->free; 109e88f27b3Smrg pctx->free = pref; 110e88f27b3Smrg } 111e88f27b3Smrg 112e88f27b3Smrg bctx->relocs -= pbin->relocs; 113e88f27b3Smrg pbin->relocs = 0; 114e88f27b3Smrg} 115e88f27b3Smrg 1167cdc0497Smrgdrm_public struct nouveau_bufref * 117e88f27b3Smrgnouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin, 118e88f27b3Smrg struct nouveau_bo *bo, uint32_t flags) 119e88f27b3Smrg{ 120e88f27b3Smrg struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx); 121e88f27b3Smrg struct nouveau_bufbin_priv *pbin = &pctx->bins[bin]; 122e88f27b3Smrg struct nouveau_bufref_priv *pref = pctx->free; 123e88f27b3Smrg 124e88f27b3Smrg if (!pref) 125e88f27b3Smrg pref = malloc(sizeof(*pref)); 126e88f27b3Smrg else 127e88f27b3Smrg pctx->free = pref->next; 128e88f27b3Smrg 129e88f27b3Smrg if (pref) { 130e88f27b3Smrg pref->base.bo = bo; 131e88f27b3Smrg pref->base.flags = flags; 132e88f27b3Smrg pref->base.packet = 0; 133e88f27b3Smrg 134e88f27b3Smrg DRMLISTADDTAIL(&pref->base.thead, &bctx->pending); 135e88f27b3Smrg pref->bufctx = bctx; 136e88f27b3Smrg pref->next = pbin->list; 137e88f27b3Smrg pbin->list = pref; 138e88f27b3Smrg } 139e88f27b3Smrg 140e88f27b3Smrg return &pref->base; 141e88f27b3Smrg} 142e88f27b3Smrg 1437cdc0497Smrgdrm_public struct nouveau_bufref * 144e88f27b3Smrgnouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet, 145e88f27b3Smrg struct nouveau_bo *bo, uint64_t data, uint32_t flags, 146e88f27b3Smrg uint32_t vor, uint32_t tor) 147e88f27b3Smrg{ 148e88f27b3Smrg struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx); 149e88f27b3Smrg struct nouveau_bufbin_priv *pbin = &pctx->bins[bin]; 150e88f27b3Smrg struct nouveau_bufref *bref = nouveau_bufctx_refn(bctx, bin, bo, flags); 151e88f27b3Smrg if (bref) { 152e88f27b3Smrg bref->packet = packet; 153e88f27b3Smrg bref->data = data; 154e88f27b3Smrg bref->vor = vor; 155e88f27b3Smrg bref->tor = tor; 156e88f27b3Smrg pbin->relocs++; 157e88f27b3Smrg bctx->relocs++; 158e88f27b3Smrg } 159e88f27b3Smrg return bref; 160e88f27b3Smrg} 161