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); } }
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); }
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); }
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; }
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); } }
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; }
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; }
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; }
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); }
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); }
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); }
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);
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); }
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 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); }
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); } }
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); } }
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); }
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)); }
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; }
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); } }
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; }