void nv04_emit_tex_obj(struct gl_context *ctx, int emit) { struct nv04_context *nv04 = to_nv04_context(ctx); const int i = emit - NOUVEAU_STATE_TEX_OBJ0; struct nouveau_surface *s; uint32_t format = 0xa0, filter = 0x1010; if (ctx->Texture.Unit[i]._ReallyEnabled) { struct gl_texture_object *t = ctx->Texture.Unit[i]._Current; struct gl_texture_image *ti = t->Image[0][t->BaseLevel]; int lod_max = 1, lod_bias = 0; if (!nouveau_texture_validate(ctx, t)) return; s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; if (t->Sampler.MinFilter != GL_NEAREST && t->Sampler.MinFilter != GL_LINEAR) { lod_max = CLAMP(MIN2(t->Sampler.MaxLod, t->_MaxLambda), 0, 15) + 1; lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias + t->Sampler.LodBias, -16, 15) * 8; } format |= nvgl_wrap_mode(t->Sampler.WrapT) << 28 | nvgl_wrap_mode(t->Sampler.WrapS) << 24 | ti->HeightLog2 << 20 | ti->WidthLog2 << 16 | lod_max << 12 | get_tex_format(ti); filter |= log2i(t->Sampler.MaxAnisotropy) << 31 | nvgl_filter_mode(t->Sampler.MagFilter) << 28 | log2i(t->Sampler.MaxAnisotropy) << 27 | nvgl_filter_mode(t->Sampler.MinFilter) << 24 | (lod_bias & 0xff) << 16; } else { s = &to_nv04_context(ctx)->dummy_texture; format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT | NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT | 1 << 12 | NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST | NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; } nv04->texture[i] = s; nv04->format[i] = format; nv04->filter[i] = filter; }
void nv04_emit_blend(struct gl_context *ctx, int emit) { struct nv04_context *nv04 = to_nv04_context(ctx); nv04->blend &= NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK; nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_MASK_BIT_MSB | NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; /* Alpha blending. */ nv04->blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 | get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24; if (ctx->Color.BlendEnabled) nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE; /* Shade model. */ if (ctx->Light.ShadeModel == GL_SMOOTH) nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; else nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT; /* Secondary color */ if (_mesa_need_secondary_color(ctx)) nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE; /* Fog. */ if (ctx->Fog.Enabled) { nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; nv04->fog = pack_rgba_f(MESA_FORMAT_B8G8R8A8_UNORM, ctx->Fog.Color); } }
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; }
static void init_dummy_texture(struct gl_context *ctx) { struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture; nouveau_surface_alloc(ctx, s, SWIZZLED, NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM, MESA_FORMAT_ARGB8888, 1, 1); nouveau_bo_map(s->bo, NOUVEAU_BO_WR, context_client(ctx)); *(uint32_t *)s->bo->map = 0xffffffff; }
static void swtnl_update_viewport(struct gl_context *ctx) { float *viewport = to_nv04_context(ctx)->viewport; struct gl_framebuffer *fb = ctx->DrawBuffer; get_viewport_scale(ctx, viewport); get_viewport_translate(ctx, &viewport[MAT_TX]); /* It wants normalized Z coordinates. */ viewport[MAT_SZ] /= fb->_DepthMaxF; viewport[MAT_TZ] /= fb->_DepthMaxF; }
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); }
void nv04_emit_control(struct gl_context *ctx, int emit) { struct nv04_context *nv04 = to_nv04_context(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; int cull = ctx->Polygon.CullFaceMode; int front = ctx->Polygon.FrontFace; nv04->ctrl[0] = NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_FIXED | NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN_CORNER; nv04->ctrl[1] = 0; nv04->ctrl[2] = 0; /* Dithering. */ if (ctx->Color.DitherFlag) nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; /* Cull mode. */ if (!ctx->Polygon.CullFlag) nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE; else if (cull == GL_FRONT_AND_BACK) nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH; else nv04->ctrl[0] |= (cull == GL_FRONT) ^ (front == GL_CCW) ? NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW : NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW; /* Depth test. */ if (ctx->Depth.Test && fb->Visual.depthBits > 0) nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; if (ctx->Depth.Mask && fb->Visual.depthBits > 0) nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; nv04->ctrl[0] |= get_comparison_op(ctx->Depth.Func) << 16; /* Alpha test. */ if (ctx->Color.AlphaEnabled) nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; nv04->ctrl[0] |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | FLOAT_TO_UBYTE(ctx->Color.AlphaRef); /* Color mask. */ if (ctx->Color.ColorMask[0][RCOMP]) nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE; if (ctx->Color.ColorMask[0][GCOMP]) nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE; if (ctx->Color.ColorMask[0][BCOMP]) nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE; if (ctx->Color.ColorMask[0][ACOMP]) nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE; /* Stencil test. */ if (ctx->Stencil.WriteMask[0]) nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE; if (_mesa_stencil_is_enabled(ctx)) nv04->ctrl[1] |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE; nv04->ctrl[1] |= get_comparison_op(ctx->Stencil.Function[0]) << 4 | _mesa_get_stencil_ref(ctx, 0) << 8 | ctx->Stencil.ValueMask[0] << 16 | ctx->Stencil.WriteMask[0] << 24; nv04->ctrl[2] |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 | get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 | get_stencil_op(ctx->Stencil.FailFunc[0]); }
void nv04_emit_tex_obj(struct gl_context *ctx, int emit) { const int i = emit - NOUVEAU_STATE_TEX_OBJ0; struct nouveau_channel *chan = context_chan(ctx); struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; struct nouveau_surface *s; uint32_t format = 0xa0, filter = 0x1010; if (i && !nv04_mtex_engine(fahrenheit)) return; if (ctx->Texture.Unit[i]._ReallyEnabled) { struct gl_texture_object *t = ctx->Texture.Unit[i]._Current; struct gl_texture_image *ti = t->Image[0][t->BaseLevel]; int lod_max = 1, lod_bias = 0; if (!nouveau_texture_validate(ctx, t)) return; s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; if (t->MinFilter != GL_NEAREST && t->MinFilter != GL_LINEAR) { lod_max = CLAMP(MIN2(t->MaxLod, t->_MaxLambda), 0, 15) + 1; lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias + t->LodBias, -16, 15) * 8; } format |= nvgl_wrap_mode(t->WrapT) << 28 | nvgl_wrap_mode(t->WrapS) << 24 | ti->HeightLog2 << 20 | ti->WidthLog2 << 16 | lod_max << 12 | get_tex_format(ti); filter |= log2i(t->MaxAnisotropy) << 31 | nvgl_filter_mode(t->MagFilter) << 28 | log2i(t->MaxAnisotropy) << 27 | nvgl_filter_mode(t->MinFilter) << 24 | (lod_bias & 0xff) << 16; } else { s = &to_nv04_context(ctx)->dummy_texture; format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT | NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT | 1 << 12 | NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST | NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; } if (nv04_mtex_engine(fahrenheit)) { nouveau_bo_markl(bctx, fahrenheit, NV04_MULTITEX_TRIANGLE_OFFSET(i), s->bo, s->offset, bo_flags); nouveau_bo_mark(bctx, fahrenheit, NV04_MULTITEX_TRIANGLE_FORMAT(i), s->bo, format, 0, NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A, NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B, bo_flags | NOUVEAU_BO_OR); BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FILTER(i), 1); OUT_RING(chan, filter); } else { nouveau_bo_markl(bctx, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, s->bo, s->offset, bo_flags); nouveau_bo_mark(bctx, fahrenheit, NV04_TEXTURED_TRIANGLE_FORMAT, s->bo, format, 0, NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A, NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B, bo_flags | NOUVEAU_BO_OR); BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1); OUT_RING(chan, 0); BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1); OUT_RING(chan, filter); } }