Beispiel #1
0
void
nouveau_channel_free(struct nouveau_channel **chan)
{
	struct nouveau_channel_priv *nvchan;
	struct nouveau_device_priv *nvdev;
	struct drm_nouveau_channel_free cf;
	unsigned i;

	if (!chan || !*chan)
		return;
	nvchan = nouveau_channel(*chan);
	(*chan)->flush_notify = NULL;
	*chan = NULL;
	nvdev = nouveau_device(nvchan->base.device);

	FIRE_RING(&nvchan->base);

	nouveau_pushbuf_fini(&nvchan->base);
	if (nvchan->notifier_bo) {
		nouveau_bo_unmap(nvchan->notifier_bo);
		nouveau_bo_ref(NULL, &nvchan->notifier_bo);
	}

	for (i = 0; i < nvchan->drm.nr_subchan; i++)
		free(nvchan->base.subc[i].gr);

	nouveau_grobj_free(&nvchan->base.vram);
	nouveau_grobj_free(&nvchan->base.gart);
	nouveau_grobj_free(&nvchan->base.nullobj);

	cf.channel = nvchan->drm.channel;
	drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf));
	free(nvchan);
}
void
nouveau_channel_free(struct nouveau_channel **chan)
{
	struct nouveau_channel_priv *nvchan;
	struct nouveau_device_priv *nvdev;
	struct drm_nouveau_channel_free cf;

	if (!chan || !*chan)
		return;
	nvchan = nouveau_channel(*chan);
	*chan = NULL;
	nvdev = nouveau_device(nvchan->base.device);

	FIRE_RING(&nvchan->base);

	nouveau_bo_unmap(nvchan->notifier_bo);
	nouveau_bo_ref(NULL, &nvchan->notifier_bo);

	nouveau_grobj_free(&nvchan->base.vram);
	nouveau_grobj_free(&nvchan->base.gart);
	nouveau_grobj_free(&nvchan->base.nullobj);

	cf.channel = nvchan->drm.channel;
	drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf));
	free(nvchan);
}
Beispiel #3
0
/* Unlock the hardware using the global current context 
 */
void
UNLOCK_HARDWARE(struct nouveau_context *nv)
{
	struct nouveau_screen *nv_screen = nv->dri_screen->private;
	struct nouveau_device *dev = nv_screen->device;
	struct nouveau_device_priv *nvdev = nouveau_device(dev);

	assert(nv->locked);
	nv->locked = 0;

	DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);

	pipe_mutex_unlock(lockMutex);
} 
Beispiel #4
0
GLboolean
nouveau_context_create(const __GLcontextModes *glVis,
		       __DRIcontextPrivate *driContextPriv,
		       void *sharedContextPrivate)
{
	__DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
	struct nouveau_screen  *nv_screen = driScrnPriv->private;
	struct nouveau_context *nv;
	struct pipe_context *pipe;
	struct st_context *st_share = NULL;

	if (sharedContextPrivate)
		st_share = ((struct nouveau_context *)sharedContextPrivate)->st;

	nv = CALLOC_STRUCT(nouveau_context);
	if (!nv)
		return GL_FALSE;

	{
		struct nouveau_device_priv *nvdev =
			nouveau_device(nv_screen->device);

		nvdev->ctx  = driContextPriv->hHWContext;
		nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock;
	}

	pipe = drm_api_hooks.create_context(nv_screen->pscreen);
	if (!pipe) {
		FREE(nv);
		return GL_FALSE;
	}
	pipe->priv = nv;

	driContextPriv->driverPrivate = nv;
	nv->dri_screen = driScrnPriv;

	driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
			    nv->dri_screen->myNum, "nouveau");

	nv->st = st_create_context(pipe, glVis, st_share);
	return GL_TRUE;
}
Beispiel #5
0
/* Lock the hardware and validate our state.
 */
void
LOCK_HARDWARE(struct nouveau_context *nv)
{
	struct nouveau_screen *nv_screen = nv->dri_screen->private;
	struct nouveau_device *dev = nv_screen->device;
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	char __ret=0;

	assert(!nv->locked);
	pipe_mutex_lock(lockMutex);

	DRM_CAS(nvdev->lock, nvdev->ctx,
		(DRM_LOCK_HELD | nvdev->ctx), __ret);

	if (__ret) {
		drmGetLock(nvdev->fd, nvdev->ctx, 0);
		nouveau_contended_lock(nv);
	}
	nv->locked = 1;
}
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <stdlib.h>
#include <errno.h>

#include "nouveau_private.h"

int
nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle,
		    int class, struct nouveau_grobj **grobj)
{
	struct nouveau_device_priv *nvdev = nouveau_device(chan->device);
	struct nouveau_grobj_priv *nvgrobj;
	struct drm_nouveau_grobj_alloc g;
	int ret;

	if (!nvdev || !grobj || *grobj)
		return -EINVAL;

	nvgrobj = calloc(1, sizeof(*nvgrobj));
	if (!nvgrobj)
		return -ENOMEM;
	nvgrobj->base.channel = chan;
	nvgrobj->base.handle  = handle;
	nvgrobj->base.grclass = class;
	nvgrobj->base.bound   = NOUVEAU_GROBJ_UNBOUND;
	nvgrobj->base.subc    = -1;
Beispiel #7
0
int
nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
		      uint32_t tt_ctxdma, int pushbuf_size,
		      struct nouveau_channel **chan)
{
	struct nouveau_device_priv *nvdev = nouveau_device(dev);
	struct nouveau_channel_priv *nvchan;
	unsigned i;
	int ret;

	if (!nvdev || !chan || *chan)
	    return -EINVAL;

	nvchan = calloc(1, sizeof(struct nouveau_channel_priv));
	if (!nvchan)
		return -ENOMEM;
	nvchan->base.device = dev;

	nvchan->drm.fb_ctxdma_handle = fb_ctxdma;
	nvchan->drm.tt_ctxdma_handle = tt_ctxdma;
	ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
				  &nvchan->drm, sizeof(nvchan->drm));
	if (ret) {
		free(nvchan);
		return ret;
	}

	nvchan->base.id = nvchan->drm.channel;
	if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle,
			      &nvchan->base.vram) ||
	    nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle,
		    	      &nvchan->base.gart)) {
		nouveau_channel_free((void *)&nvchan);
		return -EINVAL;
	}

	/* Mark all DRM-assigned subchannels as in-use */
	for (i = 0; i < nvchan->drm.nr_subchan; i++) {
		struct nouveau_grobj_priv *gr = calloc(1, sizeof(*gr));

		gr->base.bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
		gr->base.subc = i;
		gr->base.handle = nvchan->drm.subchan[i].handle;
		gr->base.grclass = nvchan->drm.subchan[i].grclass;
		gr->base.channel = &nvchan->base;

		nvchan->base.subc[i].gr = &gr->base;
	}

	if (dev->chipset < 0xc0) {
		ret = nouveau_bo_wrap(dev, nvchan->drm.notifier_handle,
				      &nvchan->notifier_bo);
		if (!ret)
			ret = nouveau_bo_map(nvchan->notifier_bo,
					     NOUVEAU_BO_RDWR);
		if (ret) {
			nouveau_channel_free((void *)&nvchan);
			return ret;
		}

		ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030,
					  &nvchan->base.nullobj);
		if (ret) {
			nouveau_channel_free((void *)&nvchan);
			return ret;
		}
	}

	ret = nouveau_pushbuf_init(&nvchan->base, pushbuf_size);
	if (ret) {
		nouveau_channel_free((void *)&nvchan);
		return ret;
	}

	*chan = &nvchan->base;
	return 0;
}