예제 #1
0
static void
nv17_zclear(struct gl_context *ctx, GLbitfield *buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_channel *chan = context_chan(ctx);
	struct nouveau_grobj *celsius = context_eng3d(ctx);
	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(
		ctx->DrawBuffer);
	struct nouveau_surface *s = &to_nouveau_renderbuffer(
		nfb->base.Attachment[BUFFER_DEPTH].Renderbuffer)->surface;

	/* Clear the hierarchical depth buffer */
	BEGIN_RING(chan, celsius, NV17_3D_HIERZ_FILL_VALUE, 1);
	OUT_RING(chan, pack_zs_f(s->format, ctx->Depth.Clear, 0));
	BEGIN_RING(chan, celsius, NV17_3D_HIERZ_BUFFER_CLEAR, 1);
	OUT_RING(chan, 1);

	/* Mark the depth buffer as cleared */
	if (use_fast_zclear(ctx, *buffers)) {
		if (nctx->hierz.clear_seq)
			*buffers &= ~BUFFER_BIT_DEPTH;

		nfb->hierz.clear_value =
			pack_zs_f(s->format, ctx->Depth.Clear, 0);
		nctx->hierz.clear_seq++;

		context_dirty(ctx, ZCLEAR);
	}
}
예제 #2
0
static void
nv04_hwctx_init(struct gl_context *ctx)
{
	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
	struct nouveau_pushbuf *push = context_push(ctx);
	struct nv04_fifo *fifo = hw->chan->data;

	BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1);
	PUSH_DATA (push, hw->surf3d->handle);
	BEGIN_NV04(push, NV04_SF3D(DMA_NOTIFY), 3);
	PUSH_DATA (push, hw->ntfy->handle);
	PUSH_DATA (push, fifo->vram);
	PUSH_DATA (push, fifo->vram);

	BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
	PUSH_DATA (push, hw->eng3d->handle);
	BEGIN_NV04(push, NV04_TTRI(DMA_NOTIFY), 4);
	PUSH_DATA (push, hw->ntfy->handle);
	PUSH_DATA (push, fifo->vram);
	PUSH_DATA (push, fifo->gart);
	PUSH_DATA (push, hw->surf3d->handle);

	BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
	PUSH_DATA (push, hw->eng3dm->handle);
	BEGIN_NV04(push, NV04_MTRI(DMA_NOTIFY), 4);
	PUSH_DATA (push, hw->ntfy->handle);
	PUSH_DATA (push, fifo->vram);
	PUSH_DATA (push, fifo->gart);
	PUSH_DATA (push, hw->surf3d->handle);

	PUSH_KICK (push);
}
예제 #3
0
void
nv20_emit_tex_gen(GLcontext *ctx, int emit)
{
	const int i = emit - NOUVEAU_STATE_TEX_GEN0;
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_channel *chan = context_chan(ctx);
	struct nouveau_grobj *kelvin = context_eng3d(ctx);
	struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
	int j;

	for (j = 0; j < 4; j++) {
		if (nctx->fallback == HWTNL && (unit->TexGenEnabled & 1 << j)) {
			struct gl_texgen *coord = get_texgen_coord(unit, j);
			float *k = get_texgen_coeff(coord);

			if (k) {
				BEGIN_RING(chan, kelvin, TX_GEN_COEFF(i, j), 4);
				OUT_RINGp(chan, k, 4);
			}

			BEGIN_RING(chan, kelvin, TX_GEN_MODE(i, j), 1);
			OUT_RING(chan, nvgl_texgen_mode(coord->Mode));

		} else {
			BEGIN_RING(chan, kelvin, TX_GEN_MODE(i, j), 1);
			OUT_RING(chan, 0);
		}
	}
}
static void
nv17_zclear(struct gl_context *ctx, GLbitfield *buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);
	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(
		ctx->DrawBuffer);
	struct nouveau_surface *s = &to_nouveau_renderbuffer(
		nfb->base.Attachment[BUFFER_DEPTH].Renderbuffer)->surface;

	/* Clear the hierarchical depth buffer */
	BEGIN_NV04(push, NV17_3D(HIERZ_FILL_VALUE), 1);
	PUSH_DATA (push, pack_zs_f(s->format, ctx->Depth.Clear, 0));
	BEGIN_NV04(push, NV17_3D(HIERZ_BUFFER_CLEAR), 1);
	PUSH_DATA (push, 1);

	/* Mark the depth buffer as cleared */
	if (use_fast_zclear(ctx, *buffers)) {
		if (nctx->hierz.clear_seq)
			*buffers &= ~BUFFER_BIT_DEPTH;

		nfb->hierz.clear_value =
			pack_zs_f(s->format, ctx->Depth.Clear, 0);
		nctx->hierz.clear_seq++;

		context_dirty(ctx, ZCLEAR);
	}
}
static void
nv10_clear(struct gl_context *ctx, GLbitfield buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);

	nouveau_validate_framebuffer(ctx);

	nouveau_pushbuf_bufctx(push, nctx->hw.bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return;
	}

	if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask) {
		if (context_chipset(ctx) >= 0x17)
			nv17_zclear(ctx, &buffers);
		else
			nv10_zclear(ctx, &buffers);

		/* Emit the zclear state if it's dirty */
		_mesa_update_state(ctx);
	}

	nouveau_pushbuf_bufctx(push, NULL);
	nouveau_clear(ctx, buffers);
}
예제 #6
0
struct nouveau_object *
nv04_context_engine(struct gl_context *ctx)
{
	struct nv04_context *nctx = to_nv04_context(ctx);
	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
	struct nouveau_pushbuf *push = context_push(ctx);
	struct nouveau_object *fahrenheit;

	if ((ctx->Texture.Unit[0]._ReallyEnabled &&
	     texunit_needs_combiners(&ctx->Texture.Unit[0])) ||
	    ctx->Texture.Unit[1]._ReallyEnabled ||
	    ctx->Stencil.Enabled ||
	    !(ctx->Color.ColorMask[0][RCOMP] &&
	      ctx->Color.ColorMask[0][GCOMP] &&
	      ctx->Color.ColorMask[0][BCOMP] &&
	      ctx->Color.ColorMask[0][ACOMP]))
		fahrenheit = hw->eng3dm;
	else
		fahrenheit = hw->eng3d;

	if (fahrenheit != nctx->eng3d) {
		BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
		PUSH_DATA (push, fahrenheit->handle);
		nctx->eng3d = fahrenheit;
	}

	return fahrenheit;
}
예제 #7
0
void
nv20_emit_tex_gen(struct gl_context *ctx, int emit)
{
	const int i = emit - NOUVEAU_STATE_TEX_GEN0;
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);
	struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
	int j;

	for (j = 0; j < 4; j++) {
		if (nctx->fallback == HWTNL && (unit->TexGenEnabled & 1 << j)) {
			struct gl_texgen *coord = get_texgen_coord(unit, j);
			float *k = get_texgen_coeff(coord);

			if (k) {
				BEGIN_NV04(push, NV20_3D(TEX_GEN_COEFF(i, j)), 4);
				PUSH_DATAp(push, k, 4);
			}

			BEGIN_NV04(push, NV20_3D(TEX_GEN_MODE(i, j)), 1);
			PUSH_DATA (push, nvgl_texgen_mode(coord->Mode));

		} else {
			BEGIN_NV04(push, NV20_3D(TEX_GEN_MODE(i, j)), 1);
			PUSH_DATA (push, 0);
		}
	}
}
static void
nv10_zclear(struct gl_context *ctx, GLbitfield *buffers)
{
	/*
	 * Pre-nv17 cards don't have native support for fast Z clears,
	 * but in some cases we can still "clear" the Z buffer without
	 * actually blitting to it if we're willing to sacrifice a few
	 * bits of depth precision.
	 *
	 * Each time a clear is requested we modify the viewport
	 * transform in such a way that the old contents of the depth
	 * buffer are clamped to the requested clear value when
	 * they're read by the GPU.
	 */
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;
	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb);
	struct nouveau_surface *s = &to_nouveau_renderbuffer(
		fb->Attachment[BUFFER_DEPTH].Renderbuffer)->surface;

	if (nv10_use_viewport_zclear(ctx)) {
		int x, y, w, h;
		float z = ctx->Depth.Clear;
		uint32_t value = pack_zs_f(s->format, z, 0);

		get_scissors(fb, &x, &y, &w, &h);
		*buffers &= ~BUFFER_BIT_DEPTH;

		if (use_fast_zclear(ctx, *buffers)) {
			if (nfb->hierz.clear_value != value) {
				/* Don't fast clear if we're changing
				 * the depth value. */
				nfb->hierz.clear_value = value;

			} else if (z == 0.0) {
				nctx->hierz.clear_seq++;
				context_dirty(ctx, ZCLEAR);

				if ((nctx->hierz.clear_seq & 7) != 0 &&
				    nctx->hierz.clear_seq != 1)
					/* We didn't wrap around -- no need to
					 * clear the depth buffer for real. */
					return;

			} else if (z == 1.0) {
				nctx->hierz.clear_seq--;
				context_dirty(ctx, ZCLEAR);

				if ((nctx->hierz.clear_seq & 7) != 7)
					/* No wrap around */
					return;
			}
		}

		value = pack_zs_f(s->format,
				  (z + (nctx->hierz.clear_seq & 7)) / 8, 0);
		context_drv(ctx)->surface_fill(ctx, s, ~0, value, x, y, w, h);
	}
}
예제 #9
0
파일: nouveau_vbo_t.c 프로젝트: Sheph/mesa
static GLboolean
vbo_maybe_split(struct gl_context *ctx, const struct gl_client_array **arrays,
	    const struct _mesa_prim *prims, GLuint nr_prims,
	    const struct _mesa_index_buffer *ib,
	    GLuint min_index, GLuint max_index)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_render_state *render = to_render_state(ctx);
	struct nouveau_bufctx *bufctx = nctx->hw.bufctx;
	unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * (bufctx->relocs +
						       render->attr_count),
		vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail),
		idx_avail = get_max_vertices(ctx, ib, pushbuf_avail);
	int stride;

	/* Try to keep client buffers smaller than the scratch BOs. */
	if (render->mode == VBO &&
	    (stride = get_max_client_stride(ctx, arrays)))
		    vert_avail = MIN2(vert_avail,
				      NOUVEAU_SCRATCH_SIZE / stride);

	if (max_index - min_index > vert_avail ||
	    (ib && ib->count > idx_avail)) {
		struct split_limits limits = {
			.max_verts = vert_avail,
			.max_indices = idx_avail,
			.max_vb_size = ~0,
		};

		vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index,
				max_index, TAG(vbo_render_prims), &limits);
		return GL_TRUE;
	}

	return GL_FALSE;
}

/* VBO rendering path. */

static GLboolean
check_update_array(struct nouveau_array *a, unsigned offset,
		   struct nouveau_bo *bo, int *pdelta)
{
	int delta = *pdelta;
	GLboolean dirty;

	if (a->bo == bo) {
		if (delta < 0)
			delta = ((int)offset - (int)a->offset) / a->stride;

		dirty = (delta < 0 ||
			 offset != (a->offset + delta * a->stride));
	} else {
		dirty = GL_TRUE;
	}

	*pdelta = (dirty ? 0 : delta);
	return dirty;
}
예제 #10
0
GLboolean
nouveau_context_create(gl_api api,
		       const struct gl_config *visual, __DRIcontext *dri_ctx,
		       unsigned major_version,
		       unsigned minor_version,
		       uint32_t flags,
		       bool notify_reset,
		       unsigned *error,
		       void *share_ctx)
{
	__DRIscreen *dri_screen = dri_ctx->driScreenPriv;
	struct nouveau_screen *screen = dri_screen->driverPrivate;
	struct nouveau_context *nctx;
	struct gl_context *ctx;

	if (flags & ~__DRI_CTX_FLAG_DEBUG) {
		*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
		return false;
	}

	if (notify_reset) {
		*error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
		return false;
	}

	ctx = screen->driver->context_create(screen, visual, share_ctx);
	if (!ctx) {
		*error = __DRI_CTX_ERROR_NO_MEMORY;
		return GL_FALSE;
	}

	driContextSetFlags(ctx, flags);

	nctx = to_nouveau_context(ctx);
	nctx->dri_context = dri_ctx;
	dri_ctx->driverPrivate = ctx;

	_mesa_compute_version(ctx);
	if (ctx->Version < major_version * 10 + minor_version) {
	   nouveau_context_destroy(dri_ctx);
	   *error = __DRI_CTX_ERROR_BAD_VERSION;
	   return GL_FALSE;
	}

	/* Exec table initialization requires the version to be computed */
	_mesa_initialize_dispatch_tables(ctx);
	_mesa_initialize_vbo_vtxfmt(ctx);

	if (nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_VRAM, 0, 4096,
			   NULL, &nctx->fence)) {
		nouveau_context_destroy(dri_ctx);
		*error = __DRI_CTX_ERROR_NO_MEMORY;
		return GL_FALSE;
	}

	*error = __DRI_CTX_ERROR_SUCCESS;
	return GL_TRUE;
}
static void
nv20_clear(struct gl_context *ctx, GLbitfield buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;
	uint32_t clear = 0;

	nouveau_validate_framebuffer(ctx);

	nouveau_pushbuf_bufctx(push, nctx->hw.bufctx);
	if (nouveau_pushbuf_validate(push)) {
		nouveau_pushbuf_bufctx(push, NULL);
		return;
	}

	if (buffers & BUFFER_BITS_COLOR) {
		struct nouveau_surface *s = &to_nouveau_renderbuffer(
			fb->_ColorDrawBuffers[0])->surface;

		if (ctx->Color.ColorMask[0][RCOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_R;
		if (ctx->Color.ColorMask[0][GCOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_G;
		if (ctx->Color.ColorMask[0][BCOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_B;
		if (ctx->Color.ColorMask[0][ACOMP])
			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_A;

		BEGIN_NV04(push, NV20_3D(CLEAR_VALUE), 1);
		PUSH_DATA (push, pack_rgba_clamp_f(s->format, ctx->Color.ClearColor.f));

		buffers &= ~BUFFER_BITS_COLOR;
	}

	if (buffers & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
		struct nouveau_surface *s = &to_nouveau_renderbuffer(
			fb->Attachment[BUFFER_DEPTH].Renderbuffer)->surface;

		if (buffers & BUFFER_BIT_DEPTH && ctx->Depth.Mask)
			clear |= NV20_3D_CLEAR_BUFFERS_DEPTH;
		if (buffers & BUFFER_BIT_STENCIL && ctx->Stencil.WriteMask[0])
			clear |= NV20_3D_CLEAR_BUFFERS_STENCIL;

		BEGIN_NV04(push, NV20_3D(CLEAR_DEPTH_VALUE), 1);
		PUSH_DATA (push, pack_zs_f(s->format, ctx->Depth.Clear,
					 ctx->Stencil.Clear));

		buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
	}

	BEGIN_NV04(push, NV20_3D(CLEAR_BUFFERS), 1);
	PUSH_DATA (push, clear);

	nouveau_pushbuf_bufctx(push, NULL);
	nouveau_clear(ctx, buffers);
}
float
nv10_transform_depth(struct gl_context *ctx, float z)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);

	if (nv10_use_viewport_zclear(ctx))
		return 2097152.0 * (z + (nctx->hierz.clear_seq & 7));
	else
		return ctx->DrawBuffer->_DepthMaxF * z;
}
예제 #13
0
int
nouveau_next_dirty_state(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	int i = BITSET_FFS(nctx->dirty) - 1;

	if (i < 0 || i >= context_drv(ctx)->num_emit)
		return -1;

	return i;
}
예제 #14
0
GLboolean
nv10_use_viewport_zclear(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;

	return context_chipset(ctx) < 0x17 &&
		!nctx->hierz.clear_blocked && fb->_DepthBuffer &&
		(_mesa_get_format_bits(fb->_DepthBuffer->Format,
				       GL_DEPTH_BITS) >= 24);
}
GLboolean
nv10_use_viewport_zclear(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;
	struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;

	return context_chipset(ctx) < 0x17 &&
		!nctx->hierz.clear_blocked && depthRb &&
		(_mesa_get_format_bits(depthRb->Format,
				       GL_DEPTH_BITS) >= 24);
}
예제 #16
0
void
nouveau_state_emit(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	const struct nouveau_driver *drv = context_drv(ctx);
	int i;

	while ((i = nouveau_next_dirty_state(ctx)) >= 0) {
		BITSET_CLEAR(nctx->dirty, i);
		drv->emit[i](ctx, i);
	}

	BITSET_ZERO(nctx->dirty);
}
static void
nv10_context_destroy(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);

	nv04_surface_takedown(ctx);
	nv10_swtnl_destroy(ctx);
	nv10_vbo_destroy(ctx);

	nouveau_object_del(&nctx->hw.eng3d);

	nouveau_context_deinit(ctx);
	free(ctx);
}
예제 #18
0
void
nv04_surface_takedown(struct gl_context *ctx)
{
    struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;

    nouveau_object_del(&hw->swzsurf);
    nouveau_object_del(&hw->sifm);
    nouveau_object_del(&hw->rect);
    nouveau_object_del(&hw->rop);
    nouveau_object_del(&hw->patt);
    nouveau_object_del(&hw->surf2d);
    nouveau_object_del(&hw->m2mf);
    nouveau_object_del(&hw->ntfy);
}
예제 #19
0
GLboolean
nv04_surface_init(struct gl_context *ctx)
{
    struct nouveau_pushbuf *push = context_push(ctx);
    struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
    struct nouveau_object *chan = hw->chan;
    unsigned handle = 0x88000000, class;
    int ret;

    /* Notifier object. */
    ret = nouveau_object_new(chan, handle++, NOUVEAU_NOTIFIER_CLASS,
    &(struct nv04_notify) {
        .length = 32,
    }, sizeof(struct nv04_notify), &hw->ntfy);
예제 #20
0
void
nv04_emit_framebuffer(GLcontext *ctx, int emit)
{
	struct nouveau_channel *chan = context_chan(ctx);
	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
	struct nouveau_grobj *surf3d = hw->surf3d;
	struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER);
	struct gl_framebuffer *fb = ctx->DrawBuffer;
	struct nouveau_surface *s;
	uint32_t rt_format = NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_PITCH;
	uint32_t rt_pitch = 0, zeta_pitch = 0;
	unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;

	if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT)
		return;

	/* Render target */
	if (fb->_NumColorDrawBuffers) {
		s = &to_nouveau_renderbuffer(
			fb->_ColorDrawBuffers[0])->surface;

		rt_format |= get_rt_format(s->format);
		zeta_pitch = rt_pitch = s->pitch;

		nouveau_bo_markl(bctx, surf3d,
				 NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR,
				 s->bo, 0, bo_flags);
	}

	/* depth/stencil */
	if (fb->_DepthBuffer) {
		s = &to_nouveau_renderbuffer(
			fb->_DepthBuffer->Wrapped)->surface;

		zeta_pitch = s->pitch;

		nouveau_bo_markl(bctx, surf3d,
				 NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA,
				 s->bo, 0, bo_flags);
	}

	BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
	OUT_RING(chan, rt_format);
	BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_PITCH, 1);
	OUT_RING(chan, zeta_pitch << 16 | rt_pitch);

	/* Recompute the scissor state. */
	context_dirty(ctx, SCISSOR);
}
예제 #21
0
static void
nv04_context_destroy(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);

	nv04_surface_takedown(ctx);
	nv04_render_destroy(ctx);
	nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture);

	nouveau_object_del(&nctx->hw.eng3d);
	nouveau_object_del(&nctx->hw.eng3dm);
	nouveau_object_del(&nctx->hw.surf3d);

	nouveau_context_deinit(ctx);
	FREE(ctx);
}
예제 #22
0
void
nouveau_state_init(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);

	ctx->Driver.AlphaFunc = nouveau_alpha_func;
	ctx->Driver.BlendColor = nouveau_blend_color;
	ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate;
	ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate;
	ctx->Driver.ClipPlane = nouveau_clip_plane;
	ctx->Driver.ColorMask = nouveau_color_mask;
	ctx->Driver.ColorMaterial = nouveau_color_material;
	ctx->Driver.CullFace = nouveau_cull_face;
	ctx->Driver.FrontFace = nouveau_front_face;
	ctx->Driver.DepthFunc = nouveau_depth_func;
	ctx->Driver.DepthMask = nouveau_depth_mask;
	ctx->Driver.DepthRange = nouveau_depth_range;
	ctx->Driver.ReadBuffer = nouveau_read_buffer;
	ctx->Driver.DrawBuffers = nouveau_draw_buffers;
	ctx->Driver.Enable = nouveau_enable;
	ctx->Driver.Fogfv = nouveau_fog;
	ctx->Driver.Lightfv = nouveau_light;
	ctx->Driver.LightModelfv = nouveau_light_model;
	ctx->Driver.LineStipple = nouveau_line_stipple;
	ctx->Driver.LineWidth = nouveau_line_width;
	ctx->Driver.LogicOpcode = nouveau_logic_opcode;
	ctx->Driver.PointParameterfv = nouveau_point_parameter;
	ctx->Driver.PointSize = nouveau_point_size;
	ctx->Driver.PolygonMode = nouveau_polygon_mode;
	ctx->Driver.PolygonOffset = nouveau_polygon_offset;
	ctx->Driver.PolygonStipple = nouveau_polygon_stipple;
	ctx->Driver.RenderMode = nouveau_render_mode;
	ctx->Driver.Scissor = nouveau_scissor;
	ctx->Driver.ShadeModel = nouveau_shade_model;
	ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate;
	ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate;
	ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate;
	ctx->Driver.TexGen = nouveau_tex_gen;
	ctx->Driver.TexEnv = nouveau_tex_env;
	ctx->Driver.TexParameter = nouveau_tex_parameter;
	ctx->Driver.Viewport = nouveau_viewport;

	ctx->Driver.UpdateState = nouveau_update_state;

	BITSET_ONES(nctx->dirty);
}
예제 #23
0
static void
nouveau_flush(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);

	PUSH_KICK(push);

	if (_mesa_is_winsys_fbo(ctx->DrawBuffer) &&
	    ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
		__DRIscreen *screen = nctx->screen->dri_screen;
		__DRIdri2LoaderExtension *dri2 = screen->dri2.loader;
		__DRIdrawable *drawable = nctx->dri_context->driDrawablePriv;

		dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
	}
}
예제 #24
0
static void
nouveau_flush(GLcontext *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_channel *chan = context_chan(ctx);

	FIRE_RING(chan);

	if (ctx->DrawBuffer->Name == 0 &&
	    ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
		__DRIscreen *screen = nctx->screen->dri_screen;
		__DRIdri2LoaderExtension *dri2 = screen->dri2.loader;
		__DRIdrawable *drawable = nctx->dri_context->driDrawablePriv;

		dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
	}
}
예제 #25
0
void
nv04_emit_scissor(GLcontext *ctx, int emit)
{
	struct nouveau_channel *chan = context_chan(ctx);
	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
	struct nouveau_grobj *surf3d = hw->surf3d;
	int x, y, w, h;

	get_scissors(ctx->DrawBuffer, &x, &y, &w, &h);

	BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2);
	OUT_RING(chan, w << 16 | x);
	OUT_RING(chan, h << 16 | y);

	/* Messing with surf3d invalidates some engine state. */
	context_dirty(ctx, CONTROL);
	context_dirty(ctx, BLEND);
}
예제 #26
0
static void
nouveau_finish(struct gl_context *ctx)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);
	struct nouveau_pushbuf_refn refn =
		{ nctx->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR };

	nouveau_flush(ctx);

	if (!nouveau_pushbuf_space(push, 16, 0, 0) &&
	    !nouveau_pushbuf_refn(push, &refn, 1)) {
		PUSH_DATA(push, 0);
		PUSH_KICK(push);
	}

	nouveau_bo_wait(nctx->fence, NOUVEAU_BO_RDWR, context_client(ctx));
}
예제 #27
0
static void
nv04_surface_copy_m2mf(struct gl_context *ctx,
                       struct nouveau_surface *dst,
                       struct nouveau_surface *src,
                       int dx, int dy, int sx, int sy,
                       int w, int h)
{
    struct nouveau_pushbuf_refn refs[] = {
        { src->bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART },
        { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART },
    };
    struct nouveau_pushbuf *push = context_push(ctx);
    struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
    struct nv04_fifo *fifo = hw->chan->data;
    unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp;
    unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp;

    while (h) {
        int count = (h > 2047) ? 2047 : h;

        if (nouveau_pushbuf_space(push, 16, 4, 0) ||
                nouveau_pushbuf_refn (push, refs, 2))
            return;

        BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2);
        PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
        PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
        BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
        PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
        PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
        PUSH_DATA (push, src->pitch);
        PUSH_DATA (push, dst->pitch);
        PUSH_DATA (push, w * src->cpp);
        PUSH_DATA (push, count);
        PUSH_DATA (push, 0x0101);
        PUSH_DATA (push, 0);

        src_offset += src->pitch * count;
        dst_offset += dst->pitch * count;
        h -= count;
    }
}
static GLboolean
use_fast_zclear(struct gl_context *ctx, GLbitfield buffers)
{
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct gl_framebuffer *fb = ctx->DrawBuffer;

	if (buffers & BUFFER_BIT_STENCIL) {
		/*
		 * The stencil test is bypassed when fast Z clears are
		 * enabled.
		 */
		nctx->hierz.clear_blocked = GL_TRUE;
		context_dirty(ctx, ZCLEAR);
		return GL_FALSE;
	}

	return !nctx->hierz.clear_blocked &&
		fb->_Xmax == fb->Width && fb->_Xmin == 0 &&
		fb->_Ymax == fb->Height && fb->_Ymin == 0;
}
예제 #29
0
void
nv20_emit_tex_mat(struct gl_context *ctx, int emit)
{
	const int i = emit - NOUVEAU_STATE_TEX_MAT0;
	struct nouveau_context *nctx = to_nouveau_context(ctx);
	struct nouveau_pushbuf *push = context_push(ctx);

	if (nctx->fallback == HWTNL &&
	    (ctx->Texture._TexMatEnabled & 1 << i)) {
		BEGIN_NV04(push, NV20_3D(TEX_MATRIX_ENABLE(i)), 1);
		PUSH_DATA (push, 1);

		BEGIN_NV04(push, NV20_3D(TEX_MATRIX(i,0)), 16);
		PUSH_DATAm(push, ctx->TextureMatrixStack[i].Top->m);

	} else {
		BEGIN_NV04(push, NV20_3D(TEX_MATRIX_ENABLE(i)), 1);
		PUSH_DATA (push, 0);
	}
}
예제 #30
0
GLboolean
nouveau_context_create(gl_api api,
		       const struct gl_config *visual, __DRIcontext *dri_ctx,
		       unsigned major_version,
		       unsigned minor_version,
		       uint32_t flags,
		       unsigned *error,
		       void *share_ctx)
{
	__DRIscreen *dri_screen = dri_ctx->driScreenPriv;
	struct nouveau_screen *screen = dri_screen->driverPrivate;
	struct nouveau_context *nctx;
	struct gl_context *ctx;

	/* API and flag filtering is handled in dri2CreateContextAttribs.
	 */
	(void) api;
	(void) flags;

	ctx = screen->driver->context_create(screen, visual, share_ctx);
	if (!ctx) {
		*error = __DRI_CTX_ERROR_NO_MEMORY;
		return GL_FALSE;
	}

	nctx = to_nouveau_context(ctx);
	nctx->dri_context = dri_ctx;
	dri_ctx->driverPrivate = ctx;

	_mesa_compute_version(ctx);
	if (ctx->VersionMajor < major_version
	    || (ctx->VersionMajor == major_version
		&& ctx->VersionMinor < minor_version)) {
	   nouveau_context_destroy(dri_ctx);
	   *error = __DRI_CTX_ERROR_BAD_VERSION;
	   return GL_FALSE;
	}

	*error = __DRI_CTX_ERROR_SUCCESS;
	return GL_TRUE;
}