Home | History | Annotate | Download | only in nouveau
      1 /*
      2  * Copyright (C) 2009-2010 Francisco Jerez.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  */
     26 
     27 #include "nouveau_driver.h"
     28 #include "nouveau_context.h"
     29 #include "nouveau_fbo.h"
     30 #include "nouveau_util.h"
     31 #include "nv04_3d.xml.h"
     32 #include "nv04_driver.h"
     33 
     34 static GLboolean
     35 texunit_needs_combiners(struct gl_texture_unit *u)
     36 {
     37 	struct gl_texture_object *t = u->_Current;
     38 	struct gl_texture_image *ti = t->Image[0][t->BaseLevel];
     39 
     40 	return ti->TexFormat == MESA_FORMAT_A8 ||
     41 		ti->TexFormat == MESA_FORMAT_L8 ||
     42 		u->EnvMode == GL_COMBINE ||
     43 		u->EnvMode == GL_COMBINE4_NV ||
     44 		u->EnvMode == GL_BLEND ||
     45 		u->EnvMode == GL_ADD;
     46 }
     47 
     48 struct nouveau_object *
     49 nv04_context_engine(struct gl_context *ctx)
     50 {
     51 	struct nv04_context *nctx = to_nv04_context(ctx);
     52 	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
     53 	struct nouveau_pushbuf *push = context_push(ctx);
     54 	struct nouveau_object *fahrenheit;
     55 
     56 	if ((ctx->Texture.Unit[0]._ReallyEnabled &&
     57 	     texunit_needs_combiners(&ctx->Texture.Unit[0])) ||
     58 	    ctx->Texture.Unit[1]._ReallyEnabled ||
     59 	    ctx->Stencil.Enabled ||
     60 	    !(ctx->Color.ColorMask[0][RCOMP] &&
     61 	      ctx->Color.ColorMask[0][GCOMP] &&
     62 	      ctx->Color.ColorMask[0][BCOMP] &&
     63 	      ctx->Color.ColorMask[0][ACOMP]))
     64 		fahrenheit = hw->eng3dm;
     65 	else
     66 		fahrenheit = hw->eng3d;
     67 
     68 	if (fahrenheit != nctx->eng3d) {
     69 		BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
     70 		PUSH_DATA (push, fahrenheit->handle);
     71 		nctx->eng3d = fahrenheit;
     72 	}
     73 
     74 	return fahrenheit;
     75 }
     76 
     77 static void
     78 nv04_hwctx_init(struct gl_context *ctx)
     79 {
     80 	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
     81 	struct nouveau_pushbuf *push = context_push(ctx);
     82 	struct nv04_fifo *fifo = hw->chan->data;
     83 
     84 	BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1);
     85 	PUSH_DATA (push, hw->surf3d->handle);
     86 	BEGIN_NV04(push, NV04_SF3D(DMA_NOTIFY), 3);
     87 	PUSH_DATA (push, hw->ntfy->handle);
     88 	PUSH_DATA (push, fifo->vram);
     89 	PUSH_DATA (push, fifo->vram);
     90 
     91 	BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
     92 	PUSH_DATA (push, hw->eng3d->handle);
     93 	BEGIN_NV04(push, NV04_TTRI(DMA_NOTIFY), 4);
     94 	PUSH_DATA (push, hw->ntfy->handle);
     95 	PUSH_DATA (push, fifo->vram);
     96 	PUSH_DATA (push, fifo->gart);
     97 	PUSH_DATA (push, hw->surf3d->handle);
     98 
     99 	BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
    100 	PUSH_DATA (push, hw->eng3dm->handle);
    101 	BEGIN_NV04(push, NV04_MTRI(DMA_NOTIFY), 4);
    102 	PUSH_DATA (push, hw->ntfy->handle);
    103 	PUSH_DATA (push, fifo->vram);
    104 	PUSH_DATA (push, fifo->gart);
    105 	PUSH_DATA (push, hw->surf3d->handle);
    106 
    107 	PUSH_KICK (push);
    108 }
    109 
    110 static void
    111 init_dummy_texture(struct gl_context *ctx)
    112 {
    113 	struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture;
    114 
    115 	nouveau_surface_alloc(ctx, s, SWIZZLED,
    116 			      NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM,
    117 			      MESA_FORMAT_ARGB8888, 1, 1);
    118 
    119 	nouveau_bo_map(s->bo, NOUVEAU_BO_WR, context_client(ctx));
    120 	*(uint32_t *)s->bo->map = 0xffffffff;
    121 }
    122 
    123 static void
    124 nv04_context_destroy(struct gl_context *ctx)
    125 {
    126 	struct nouveau_context *nctx = to_nouveau_context(ctx);
    127 
    128 	nv04_surface_takedown(ctx);
    129 	nv04_render_destroy(ctx);
    130 	nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture);
    131 
    132 	nouveau_object_del(&nctx->hw.eng3d);
    133 	nouveau_object_del(&nctx->hw.eng3dm);
    134 	nouveau_object_del(&nctx->hw.surf3d);
    135 
    136 	nouveau_context_deinit(ctx);
    137 	FREE(ctx);
    138 }
    139 
    140 static struct gl_context *
    141 nv04_context_create(struct nouveau_screen *screen, const struct gl_config *visual,
    142 		    struct gl_context *share_ctx)
    143 {
    144 	struct nv04_context *nctx;
    145 	struct nouveau_hw_state *hw;
    146 	struct gl_context *ctx;
    147 	int ret;
    148 
    149 	nctx = CALLOC_STRUCT(nv04_context);
    150 	if (!nctx)
    151 		return NULL;
    152 
    153 	ctx = &nctx->base.base;
    154 	hw = &nctx->base.hw;
    155 
    156 	if (!nouveau_context_init(ctx, screen, visual, share_ctx))
    157 		goto fail;
    158 
    159 	/* GL constants. */
    160 	ctx->Const.MaxTextureLevels = 11;
    161 	ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS;
    162 	ctx->Const.MaxTextureImageUnits = NV04_TEXTURE_UNITS;
    163 	ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS;
    164 	ctx->Const.MaxTextureMaxAnisotropy = 2;
    165 	ctx->Const.MaxTextureLodBias = 15;
    166 
    167 	/* 2D engine. */
    168 	ret = nv04_surface_init(ctx);
    169 	if (!ret)
    170 		goto fail;
    171 
    172 	/* 3D engine. */
    173 	ret = nouveau_object_new(context_chan(ctx), 0xbeef0001,
    174 				 NV04_TEXTURED_TRIANGLE_CLASS, NULL, 0,
    175 				 &hw->eng3d);
    176 	if (ret)
    177 		goto fail;
    178 
    179 	ret = nouveau_object_new(context_chan(ctx), 0xbeef0002,
    180 				 NV04_MULTITEX_TRIANGLE_CLASS, NULL, 0,
    181 				 &hw->eng3dm);
    182 	if (ret)
    183 		goto fail;
    184 
    185 	ret = nouveau_object_new(context_chan(ctx), 0xbeef0003,
    186 				 NV04_SURFACE_3D_CLASS, NULL, 0,
    187 				 &hw->surf3d);
    188 	if (ret)
    189 		goto fail;
    190 
    191 	init_dummy_texture(ctx);
    192 	nv04_hwctx_init(ctx);
    193 	nv04_render_init(ctx);
    194 
    195 	return ctx;
    196 
    197 fail:
    198 	nv04_context_destroy(ctx);
    199 	return NULL;
    200 }
    201 
    202 const struct nouveau_driver nv04_driver = {
    203 	.context_create = nv04_context_create,
    204 	.context_destroy = nv04_context_destroy,
    205 	.surface_copy = nv04_surface_copy,
    206 	.surface_fill = nv04_surface_fill,
    207 	.emit = (nouveau_state_func[]) {
    208 		nv04_defer_control,
    209 		nouveau_emit_nothing,
    210 		nv04_defer_blend,
    211 		nv04_defer_blend,
    212 		nouveau_emit_nothing,
    213 		nouveau_emit_nothing,
    214 		nouveau_emit_nothing,
    215 		nouveau_emit_nothing,
    216 		nouveau_emit_nothing,
    217 		nouveau_emit_nothing,
    218 		nv04_defer_control,
    219 		nouveau_emit_nothing,
    220 		nv04_defer_control,
    221 		nouveau_emit_nothing,
    222 		nv04_defer_control,
    223 		nv04_defer_control,
    224 		nouveau_emit_nothing,
    225 		nv04_emit_framebuffer,
    226 		nv04_defer_blend,
    227 		nouveau_emit_nothing,
    228 		nouveau_emit_nothing,
    229 		nouveau_emit_nothing,
    230 		nouveau_emit_nothing,
    231 		nouveau_emit_nothing,
    232 		nouveau_emit_nothing,
    233 		nouveau_emit_nothing,
    234 		nouveau_emit_nothing,
    235 		nouveau_emit_nothing,
    236 		nouveau_emit_nothing,
    237 		nouveau_emit_nothing,
    238 		nouveau_emit_nothing,
    239 		nouveau_emit_nothing,
    240 		nouveau_emit_nothing,
    241 		nouveau_emit_nothing,
    242 		nouveau_emit_nothing,
    243 		nouveau_emit_nothing,
    244 		nouveau_emit_nothing,
    245 		nouveau_emit_nothing,
    246 		nouveau_emit_nothing,
    247 		nouveau_emit_nothing,
    248 		nouveau_emit_nothing,
    249 		nouveau_emit_nothing,
    250 		nouveau_emit_nothing,
    251 		nouveau_emit_nothing,
    252 		nouveau_emit_nothing,
    253 		nouveau_emit_nothing,
    254 		nouveau_emit_nothing,
    255 		nouveau_emit_nothing,
    256 		nv04_emit_scissor,
    257 		nv04_defer_blend,
    258 		nv04_defer_control,
    259 		nv04_defer_control,
    260 		nv04_defer_control,
    261 		nv04_emit_tex_env,
    262 		nv04_emit_tex_env,
    263 		nouveau_emit_nothing,
    264 		nouveau_emit_nothing,
    265 		nouveau_emit_nothing,
    266 		nouveau_emit_nothing,
    267 		nouveau_emit_nothing,
    268 		nouveau_emit_nothing,
    269 		nouveau_emit_nothing,
    270 		nouveau_emit_nothing,
    271 		nouveau_emit_nothing,
    272 		nouveau_emit_nothing,
    273 		nv04_emit_tex_obj,
    274 		nv04_emit_tex_obj,
    275 		nouveau_emit_nothing,
    276 		nouveau_emit_nothing,
    277 		nouveau_emit_nothing,
    278 		nv04_emit_blend,
    279 		nv04_emit_control,
    280 	},
    281 	.num_emit = NUM_NV04_STATE,
    282 };
    283