/* Second state atom for user clip planes: */ static void update_clip( struct st_context *st ) { struct pipe_clip_state clip; const struct gl_context *ctx = st->ctx; bool use_eye = FALSE; STATIC_ASSERT(sizeof(clip.ucp) <= sizeof(ctx->Transform._ClipUserPlane)); /* if we have a vertex shader that writes clip vertex we need to pass the pre-projection transformed coordinates into the driver. */ if (st->vp) { if (ctx->Shader.CurrentVertexProgram) use_eye = TRUE; } memcpy(clip.ucp, use_eye ? ctx->Transform.EyeUserPlane : ctx->Transform._ClipUserPlane, sizeof(clip.ucp)); st->state.clip = clip; cso_set_clip(st->cso_context, &clip); }
/* Second state atom for user clip planes: */ static void update_clip( struct st_context *st ) { struct pipe_clip_state clip; GLuint i; memset(&clip, 0, sizeof(clip)); for (i = 0; i < PIPE_MAX_CLIP_PLANES; i++) { if (st->ctx->Transform.ClipPlanesEnabled & (1 << i)) { memcpy(clip.ucp[clip.nr], st->ctx->Transform._ClipUserPlane[i], sizeof(clip.ucp[0])); clip.nr++; } } clip.depth_clamp = st->ctx->Transform.DepthClamp != GL_FALSE; if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) { st->state.clip = clip; cso_set_clip(st->cso_context, &clip); } }
/** * Do glClear by drawing a quadrilateral. * The vertices of the quad will be computed from the * ctx->DrawBuffer->_X/Ymin/max fields. */ static void clear_with_quad(struct gl_context *ctx, GLboolean color, GLboolean depth, GLboolean stencil) { struct st_context *st = st_context(ctx); const struct gl_framebuffer *fb = ctx->DrawBuffer; const GLfloat fb_width = (GLfloat) fb->Width; const GLfloat fb_height = (GLfloat) fb->Height; const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f; const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f; const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; float clearColor[4]; /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, color ? "color, " : "", depth ? "depth, " : "", stencil ? "stencil" : "", x0, y0, x1, y1); */ cso_save_blend(st->cso_context); cso_save_stencil_ref(st->cso_context); cso_save_depth_stencil_alpha(st->cso_context); cso_save_rasterizer(st->cso_context); cso_save_viewport(st->cso_context); cso_save_clip(st->cso_context); cso_save_fragment_shader(st->cso_context); cso_save_vertex_shader(st->cso_context); cso_save_vertex_elements(st->cso_context); cso_save_vertex_buffers(st->cso_context); /* blend state: RGBA masking */ { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (color) { if (ctx->Color.ColorMask[0][0]) blend.rt[0].colormask |= PIPE_MASK_R; if (ctx->Color.ColorMask[0][1]) blend.rt[0].colormask |= PIPE_MASK_G; if (ctx->Color.ColorMask[0][2]) blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->Color.ColorMask[0][3]) blend.rt[0].colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend.dither = 1; } cso_set_blend(st->cso_context, &blend); } /* depth_stencil state: always pass/set to ref value */ { struct pipe_depth_stencil_alpha_state depth_stencil; memset(&depth_stencil, 0, sizeof(depth_stencil)); if (depth) { depth_stencil.depth.enabled = 1; depth_stencil.depth.writemask = 1; depth_stencil.depth.func = PIPE_FUNC_ALWAYS; } if (stencil) { struct pipe_stencil_ref stencil_ref; memset(&stencil_ref, 0, sizeof(stencil_ref)); depth_stencil.stencil[0].enabled = 1; depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS; depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].valuemask = 0xff; depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; stencil_ref.ref_value[0] = ctx->Stencil.Clear; cso_set_stencil_ref(st->cso_context, &stencil_ref); } cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil); } cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw); cso_set_rasterizer(st->cso_context, &st->clear.raster); /* viewport state: viewport matching window dims */ { const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); struct pipe_viewport_state vp; vp.scale[0] = 0.5f * fb_width; vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f); vp.scale[2] = 1.0f; vp.scale[3] = 1.0f; vp.translate[0] = 0.5f * fb_width; vp.translate[1] = 0.5f * fb_height; vp.translate[2] = 0.0f; vp.translate[3] = 0.0f; cso_set_viewport(st->cso_context, &vp); } cso_set_clip(st->cso_context, &st->clear.clip); set_fragment_shader(st); set_vertex_shader(st); if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { st_translate_color(ctx->Color.ClearColorUnclamped, ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, clearColor); } /* draw quad matching scissor rect */ draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor); /* Restore pipe state */ cso_restore_blend(st->cso_context); cso_restore_stencil_ref(st->cso_context); cso_restore_depth_stencil_alpha(st->cso_context); cso_restore_rasterizer(st->cso_context); cso_restore_viewport(st->cso_context); cso_restore_clip(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); cso_restore_vertex_elements(st->cso_context); cso_restore_vertex_buffers(st->cso_context); }