/** * Save all the CSO state items specified by the state_mask bitmask * of CSO_BIT_x flags. */ void cso_save_state(struct cso_context *cso, unsigned state_mask) { assert(cso->saved_state == 0); cso->saved_state = state_mask; if (state_mask & CSO_BIT_AUX_VERTEX_BUFFER_SLOT) cso_save_aux_vertex_buffer_slot(cso); if (state_mask & CSO_BIT_BLEND) cso_save_blend(cso); if (state_mask & CSO_BIT_DEPTH_STENCIL_ALPHA) cso_save_depth_stencil_alpha(cso); if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS) cso_save_fragment_samplers(cso); if (state_mask & CSO_BIT_FRAGMENT_SAMPLER_VIEWS) cso_save_fragment_sampler_views(cso); if (state_mask & CSO_BIT_FRAGMENT_SHADER) cso_save_fragment_shader(cso); if (state_mask & CSO_BIT_FRAMEBUFFER) cso_save_framebuffer(cso); if (state_mask & CSO_BIT_GEOMETRY_SHADER) cso_save_geometry_shader(cso); if (state_mask & CSO_BIT_MIN_SAMPLES) cso_save_min_samples(cso); if (state_mask & CSO_BIT_RASTERIZER) cso_save_rasterizer(cso); if (state_mask & CSO_BIT_RENDER_CONDITION) cso_save_render_condition(cso); if (state_mask & CSO_BIT_SAMPLE_MASK) cso_save_sample_mask(cso); if (state_mask & CSO_BIT_STENCIL_REF) cso_save_stencil_ref(cso); if (state_mask & CSO_BIT_STREAM_OUTPUTS) cso_save_stream_outputs(cso); if (state_mask & CSO_BIT_TESSCTRL_SHADER) cso_save_tessctrl_shader(cso); if (state_mask & CSO_BIT_TESSEVAL_SHADER) cso_save_tesseval_shader(cso); if (state_mask & CSO_BIT_VERTEX_ELEMENTS) cso_save_vertex_elements(cso); if (state_mask & CSO_BIT_VERTEX_SHADER) cso_save_vertex_shader(cso); if (state_mask & CSO_BIT_VIEWPORT) cso_save_viewport(cso); if (state_mask & CSO_BIT_PAUSE_QUERIES) cso->pipe->set_active_query_state(cso->pipe, false); }
/** * 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, unsigned clear_buffers) { 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; unsigned num_layers = util_framebuffer_get_num_layers(&st->state.framebuffer); /* 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_sample_mask(st->cso_context); cso_save_viewport(st->cso_context); cso_save_fragment_shader(st->cso_context); cso_save_stream_outputs(st->cso_context); cso_save_vertex_shader(st->cso_context); cso_save_geometry_shader(st->cso_context); cso_save_vertex_elements(st->cso_context); cso_save_aux_vertex_buffer_slot(st->cso_context); /* blend state: RGBA masking */ { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); if (clear_buffers & PIPE_CLEAR_COLOR) { int num_buffers = ctx->Extensions.EXT_draw_buffers2 ? ctx->DrawBuffer->_NumColorDrawBuffers : 1; int i; blend.independent_blend_enable = num_buffers > 1; for (i = 0; i < num_buffers; i++) { if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i))) continue; if (ctx->Color.ColorMask[i][0]) blend.rt[i].colormask |= PIPE_MASK_R; if (ctx->Color.ColorMask[i][1]) blend.rt[i].colormask |= PIPE_MASK_G; if (ctx->Color.ColorMask[i][2]) blend.rt[i].colormask |= PIPE_MASK_B; if (ctx->Color.ColorMask[i][3]) blend.rt[i].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 (clear_buffers & PIPE_CLEAR_DEPTH) { depth_stencil.depth.enabled = 1; depth_stencil.depth.writemask = 1; depth_stencil.depth.func = PIPE_FUNC_ALWAYS; } if (clear_buffers & PIPE_CLEAR_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_stream_outputs(st->cso_context, 0, NULL, NULL); cso_set_sample_mask(st->cso_context, ~0); 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); } set_fragment_shader(st); cso_set_geometry_shader_handle(st->cso_context, NULL); if (num_layers > 1) set_vertex_shader_layered(st); else set_vertex_shader(st); /* We can't translate the clear color to the colorbuffer format, * because different colorbuffers may have different formats. */ /* draw quad matching scissor rect */ draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers, (union pipe_color_union*)&ctx->Color.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_sample_mask(st->cso_context); cso_restore_viewport(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); cso_restore_geometry_shader(st->cso_context); cso_restore_vertex_elements(st->cso_context); cso_restore_aux_vertex_buffer_slot(st->cso_context); cso_restore_stream_outputs(st->cso_context); }
/** * Main run function of the PP queue. Called on swapbuffers/flush. * * Runs all requested filters in order and handles shuffling the temp * buffers in between. */ void pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, struct pipe_resource *out, struct pipe_resource *indepth) { struct pipe_resource *refin = NULL, *refout = NULL; unsigned int i; struct cso_context *cso = ppq->p->cso; if (in->width0 != ppq->p->framebuffer.width || in->height0 != ppq->p->framebuffer.height) { pp_debug("Resizing the temp pp buffers\n"); pp_free_fbos(ppq); pp_init_fbos(ppq, in->width0, in->height0); } if (in == out && ppq->n_filters == 1) { /* Make a copy of in to tmp[0] in this case. */ unsigned int w = ppq->p->framebuffer.width; unsigned int h = ppq->p->framebuffer.height; util_blit_pixels(ppq->p->blitctx, in, 0, 0, 0, w, h, 0, ppq->tmps[0], 0, 0, w, h, 0, PIPE_TEX_MIPFILTER_NEAREST, TGSI_WRITEMASK_XYZW, 0); in = ppq->tmp[0]; } /* save state (restored below) */ cso_save_blend(cso); cso_save_depth_stencil_alpha(cso); cso_save_fragment_shader(cso); cso_save_framebuffer(cso); cso_save_geometry_shader(cso); cso_save_rasterizer(cso); cso_save_sample_mask(cso); cso_save_samplers(cso, PIPE_SHADER_FRAGMENT); cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT); cso_save_stencil_ref(cso); cso_save_stream_outputs(cso); cso_save_vertex_elements(cso); cso_save_vertex_shader(cso); cso_save_viewport(cso); cso_save_aux_vertex_buffer_slot(cso); cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX); cso_save_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT); cso_save_render_condition(cso); /* set default state */ cso_set_sample_mask(cso, ~0); cso_set_stream_outputs(cso, 0, NULL, 0); cso_set_geometry_shader_handle(cso, NULL); cso_set_render_condition(cso, NULL, 0); // Kept only for this frame. pipe_resource_reference(&ppq->depth, indepth); pipe_resource_reference(&refin, in); pipe_resource_reference(&refout, out); switch (ppq->n_filters) { case 1: /* No temp buf */ ppq->pp_queue[0] (ppq, in, out, 0); break; case 2: /* One temp buf */ ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0); ppq->pp_queue[1] (ppq, ppq->tmp[0], out, 1); break; default: /* Two temp bufs */ ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0); for (i = 1; i < (ppq->n_filters - 1); i++) { if (i % 2 == 0) ppq->pp_queue[i] (ppq, ppq->tmp[1], ppq->tmp[0], i); else ppq->pp_queue[i] (ppq, ppq->tmp[0], ppq->tmp[1], i); } if (i % 2 == 0) ppq->pp_queue[i] (ppq, ppq->tmp[1], out, i); else ppq->pp_queue[i] (ppq, ppq->tmp[0], out, i); break; } /* restore state we changed */ cso_restore_blend(cso); cso_restore_depth_stencil_alpha(cso); cso_restore_fragment_shader(cso); cso_restore_framebuffer(cso); cso_restore_geometry_shader(cso); cso_restore_rasterizer(cso); cso_restore_sample_mask(cso); cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT); cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT); cso_restore_stencil_ref(cso); cso_restore_stream_outputs(cso); cso_restore_vertex_elements(cso); cso_restore_vertex_shader(cso); cso_restore_viewport(cso); cso_restore_aux_vertex_buffer_slot(cso); cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX); cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT); cso_restore_render_condition(cso); pipe_resource_reference(&ppq->depth, NULL); pipe_resource_reference(&refin, NULL); pipe_resource_reference(&refout, NULL); }
/** * 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; union pipe_color_union clearColor; /* 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_fragment_shader(st->cso_context); cso_save_stream_outputs(st->cso_context); cso_save_vertex_shader(st->cso_context); cso_save_geometry_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_stream_outputs(st->cso_context, 0, NULL, 0); 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); } set_fragment_shader(st); set_vertex_shader(st); cso_set_geometry_shader_handle(st->cso_context, NULL); if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { st_translate_color(ctx->Color.ClearColor.f, ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, clearColor.f); } /* 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_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); cso_restore_geometry_shader(st->cso_context); cso_restore_vertex_elements(st->cso_context); cso_restore_vertex_buffers(st->cso_context); cso_restore_stream_outputs(st->cso_context); }