00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "main/glheader.h"
00035 #include "main/macros.h"
00036 #include "shader/prog_instruction.h"
00037 #include "st_context.h"
00038 #include "st_atom.h"
00039 #include "st_cb_accum.h"
00040 #include "st_cb_clear.h"
00041 #include "st_cb_fbo.h"
00042 #include "st_draw.h"
00043 #include "st_program.h"
00044 #include "st_public.h"
00045 #include "st_mesa_to_tgsi.h"
00046
00047 #include "pipe/p_context.h"
00048 #include "pipe/p_inlines.h"
00049 #include "pipe/p_state.h"
00050 #include "pipe/p_defines.h"
00051 #include "util/u_pack_color.h"
00052 #include "util/u_simple_shaders.h"
00053 #include "util/u_draw_quad.h"
00054
00055 #include "cso_cache/cso_context.h"
00056
00057
00058 void
00059 st_init_clear(struct st_context *st)
00060 {
00061 struct pipe_context *pipe = st->pipe;
00062
00063
00064 memset(&st->clear.raster, 0, sizeof(st->clear.raster));
00065 st->clear.raster.gl_rasterization_rules = 1;
00066 st->clear.raster.bypass_clipping = 1;
00067
00068
00069 st->clear.viewport.scale[0] = 1.0;
00070 st->clear.viewport.scale[1] = 1.0;
00071 st->clear.viewport.scale[2] = 1.0;
00072 st->clear.viewport.scale[3] = 1.0;
00073 st->clear.viewport.translate[0] = 0.0;
00074 st->clear.viewport.translate[1] = 0.0;
00075 st->clear.viewport.translate[2] = 0.0;
00076 st->clear.viewport.translate[3] = 0.0;
00077
00078
00079 st->clear.fs =
00080 util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader);
00081
00082
00083 {
00084 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
00085 TGSI_SEMANTIC_COLOR };
00086 const uint semantic_indexes[] = { 0, 0 };
00087 st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
00088 semantic_names,
00089 semantic_indexes,
00090 &st->clear.vert_shader);
00091 }
00092 }
00093
00094
00095 void
00096 st_destroy_clear(struct st_context *st)
00097 {
00098 struct pipe_context *pipe = st->pipe;
00099
00100 if (st->clear.vert_shader.tokens) {
00101 util_free_shader(&st->clear.vert_shader);
00102 st->clear.vert_shader.tokens = NULL;
00103 }
00104
00105 if (st->clear.frag_shader.tokens) {
00106 util_free_shader(&st->clear.frag_shader);
00107 st->clear.frag_shader.tokens = NULL;
00108 }
00109
00110 if (st->clear.fs) {
00111 cso_delete_fragment_shader(st->cso_context, st->clear.fs);
00112 st->clear.fs = NULL;
00113 }
00114 if (st->clear.vs) {
00115 cso_delete_vertex_shader(st->cso_context, st->clear.vs);
00116 st->clear.vs = NULL;
00117 }
00118 if (st->clear.vbuf) {
00119 pipe_buffer_reference(pipe->screen, &st->clear.vbuf, NULL);
00120 st->clear.vbuf = NULL;
00121 }
00122 }
00123
00124
00125 static GLboolean
00126 is_depth_stencil_format(enum pipe_format pipeFormat)
00127 {
00128 switch (pipeFormat) {
00129 case PIPE_FORMAT_S8Z24_UNORM:
00130 case PIPE_FORMAT_Z24S8_UNORM:
00131 return GL_TRUE;
00132 default:
00133 return GL_FALSE;
00134 }
00135 }
00136
00137
00138
00144 static void
00145 draw_quad(GLcontext *ctx,
00146 float x0, float y0, float x1, float y1, GLfloat z,
00147 const GLfloat color[4])
00148 {
00149 struct st_context *st = ctx->st;
00150 struct pipe_context *pipe = st->pipe;
00151 const GLuint max_slots = 1024 / sizeof(st->clear.vertices);
00152 GLuint i;
00153 void *buf;
00154
00155 if (st->clear.vbuf_slot >= max_slots) {
00156 pipe_buffer_reference(pipe->screen, &st->clear.vbuf, NULL);
00157 st->clear.vbuf_slot = 0;
00158 }
00159
00160 if (!st->clear.vbuf) {
00161 st->clear.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
00162 max_slots * sizeof(st->clear.vertices));
00163 }
00164
00165
00166 st->clear.vertices[0][0][0] = x0;
00167 st->clear.vertices[0][0][1] = y0;
00168
00169 st->clear.vertices[1][0][0] = x1;
00170 st->clear.vertices[1][0][1] = y0;
00171
00172 st->clear.vertices[2][0][0] = x1;
00173 st->clear.vertices[2][0][1] = y1;
00174
00175 st->clear.vertices[3][0][0] = x0;
00176 st->clear.vertices[3][0][1] = y1;
00177
00178
00179 for (i = 0; i < 4; i++) {
00180 st->clear.vertices[i][0][2] = z;
00181 st->clear.vertices[i][0][3] = 1.0;
00182 st->clear.vertices[i][1][0] = color[0];
00183 st->clear.vertices[i][1][1] = color[1];
00184 st->clear.vertices[i][1][2] = color[2];
00185 st->clear.vertices[i][1][3] = color[3];
00186 }
00187
00188
00189 buf = pipe_buffer_map(pipe->screen, st->clear.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
00190
00191 memcpy((char *)buf + st->clear.vbuf_slot * sizeof(st->clear.vertices),
00192 st->clear.vertices,
00193 sizeof(st->clear.vertices));
00194
00195 pipe_buffer_unmap(pipe->screen, st->clear.vbuf);
00196
00197
00198 util_draw_vertex_buffer(pipe,
00199 st->clear.vbuf,
00200 st->clear.vbuf_slot * sizeof(st->clear.vertices),
00201 PIPE_PRIM_TRIANGLE_FAN,
00202 4,
00203 2);
00204
00205
00206 st->clear.vbuf_slot++;
00207 }
00208
00209
00210
00216 static void
00217 clear_with_quad(GLcontext *ctx,
00218 GLboolean color, GLboolean depth, GLboolean stencil)
00219 {
00220 struct st_context *st = ctx->st;
00221 const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
00222 const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
00223 GLfloat y0, y1;
00224
00225 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
00226 y0 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax);
00227 y1 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin);
00228 }
00229 else {
00230 y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
00231 y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 cso_save_blend(st->cso_context);
00244 cso_save_depth_stencil_alpha(st->cso_context);
00245 cso_save_rasterizer(st->cso_context);
00246 cso_save_viewport(st->cso_context);
00247 cso_save_fragment_shader(st->cso_context);
00248 cso_save_vertex_shader(st->cso_context);
00249
00250
00251 {
00252 struct pipe_blend_state blend;
00253 memset(&blend, 0, sizeof(blend));
00254 blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
00255 blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
00256 blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
00257 blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
00258 if (color) {
00259 if (ctx->Color.ColorMask[0])
00260 blend.colormask |= PIPE_MASK_R;
00261 if (ctx->Color.ColorMask[1])
00262 blend.colormask |= PIPE_MASK_G;
00263 if (ctx->Color.ColorMask[2])
00264 blend.colormask |= PIPE_MASK_B;
00265 if (ctx->Color.ColorMask[3])
00266 blend.colormask |= PIPE_MASK_A;
00267 if (st->ctx->Color.DitherFlag)
00268 blend.dither = 1;
00269 }
00270 cso_set_blend(st->cso_context, &blend);
00271 }
00272
00273
00274 {
00275 struct pipe_depth_stencil_alpha_state depth_stencil;
00276 memset(&depth_stencil, 0, sizeof(depth_stencil));
00277 if (depth) {
00278 depth_stencil.depth.enabled = 1;
00279 depth_stencil.depth.writemask = 1;
00280 depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
00281 }
00282
00283 if (stencil) {
00284 depth_stencil.stencil[0].enabled = 1;
00285 depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
00286 depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
00287 depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
00288 depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
00289 depth_stencil.stencil[0].ref_value = ctx->Stencil.Clear;
00290 depth_stencil.stencil[0].value_mask = 0xff;
00291 depth_stencil.stencil[0].write_mask = ctx->Stencil.WriteMask[0] & 0xff;
00292 }
00293
00294 cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
00295 }
00296
00297 cso_set_rasterizer(st->cso_context, &st->clear.raster);
00298 cso_set_viewport(st->cso_context, &st->clear.viewport);
00299
00300 cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
00301 cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
00302
00303
00304 draw_quad(ctx, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor);
00305
00306
00307 cso_restore_blend(st->cso_context);
00308 cso_restore_depth_stencil_alpha(st->cso_context);
00309 cso_restore_rasterizer(st->cso_context);
00310 cso_restore_viewport(st->cso_context);
00311 cso_restore_fragment_shader(st->cso_context);
00312 cso_restore_vertex_shader(st->cso_context);
00313 }
00314
00315
00319 static INLINE GLboolean
00320 check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
00321 {
00322 const struct st_renderbuffer *strb = st_renderbuffer(rb);
00323
00324 if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
00325 return FALSE;
00326
00327 if (ctx->Scissor.Enabled)
00328 return TRUE;
00329
00330 if (!ctx->Color.ColorMask[0] ||
00331 !ctx->Color.ColorMask[1] ||
00332 !ctx->Color.ColorMask[2] ||
00333 !ctx->Color.ColorMask[3])
00334 return TRUE;
00335
00336 return FALSE;
00337 }
00338
00339
00340 static INLINE GLboolean
00341 check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
00342 {
00343 const struct st_renderbuffer *strb = st_renderbuffer(rb);
00344 const GLuint stencilMax = (1 << rb->StencilBits) - 1;
00345 GLboolean maskStencil
00346 = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
00347
00348 if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
00349 return FALSE;
00350
00351 if (ctx->Scissor.Enabled)
00352 return TRUE;
00353
00354 if (maskStencil)
00355 return TRUE;
00356
00357 return FALSE;
00358 }
00359
00360
00364 static INLINE GLboolean
00365 check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
00366 {
00367 const struct st_renderbuffer *strb = st_renderbuffer(rb);
00368 const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
00369
00370 if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
00371 return FALSE;
00372
00373 if (ctx->Scissor.Enabled)
00374 return TRUE;
00375
00376 if (isDS &&
00377 strb->surface->status == PIPE_SURFACE_STATUS_DEFINED &&
00378 ctx->DrawBuffer->Visual.stencilBits > 0)
00379 return TRUE;
00380
00381 return FALSE;
00382 }
00383
00384
00388 static INLINE GLboolean
00389 check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
00390 {
00391 const struct st_renderbuffer *strb = st_renderbuffer(rb);
00392 const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
00393 const GLuint stencilMax = (1 << rb->StencilBits) - 1;
00394 const GLboolean maskStencil
00395 = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
00396
00397 if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
00398 return FALSE;
00399
00400 if (maskStencil)
00401 return TRUE;
00402
00403 if (ctx->Scissor.Enabled)
00404 return TRUE;
00405
00406
00407
00408
00409
00410
00411 if (isDS &&
00412 strb->surface->status == PIPE_SURFACE_STATUS_DEFINED &&
00413 ctx->DrawBuffer->Visual.depthBits > 0)
00414 return TRUE;
00415
00416 return FALSE;
00417 }
00418
00419
00420
00421 static void
00422 clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
00423 {
00424 struct st_renderbuffer *strb = st_renderbuffer(rb);
00425
00426 if (!strb->surface)
00427 return;
00428
00429 if (check_clear_color_with_quad( ctx, rb )) {
00430
00431 clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE);
00432 }
00433 else {
00434
00435 uint clearValue;
00436
00437
00438
00439 util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue);
00440 ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
00441 }
00442 }
00443
00444
00445 static void
00446 clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
00447 {
00448 struct st_renderbuffer *strb = st_renderbuffer(rb);
00449
00450 if (!strb->surface)
00451 return;
00452
00453 if (check_clear_depth_with_quad(ctx, rb)) {
00454
00455 clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE);
00456 }
00457 else {
00458
00459 uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear);
00460 ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
00461 }
00462 }
00463
00464
00465 static void
00466 clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
00467 {
00468 struct st_renderbuffer *strb = st_renderbuffer(rb);
00469
00470 if (!strb->surface)
00471 return;
00472
00473 if (check_clear_stencil_with_quad(ctx, rb)) {
00474
00475 clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE);
00476 }
00477 else {
00478
00479 GLuint clearValue = ctx->Stencil.Clear;
00480
00481 switch (strb->surface->format) {
00482 case PIPE_FORMAT_S8Z24_UNORM:
00483 clearValue <<= 24;
00484 break;
00485 default:
00486 ;
00487 }
00488
00489 ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
00490 }
00491 }
00492
00493
00494 static void
00495 clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
00496 {
00497 struct st_renderbuffer *strb = st_renderbuffer(rb);
00498
00499 if (!strb->surface)
00500 return;
00501
00502 if (check_clear_depth_stencil_with_quad(ctx, rb)) {
00503
00504 clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE);
00505 }
00506 else {
00507
00508 GLuint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear);
00509
00510 switch (strb->surface->format) {
00511 case PIPE_FORMAT_S8Z24_UNORM:
00512 clearValue |= ctx->Stencil.Clear << 24;
00513 break;
00514 case PIPE_FORMAT_Z24S8_UNORM:
00515 clearValue |= ctx->Stencil.Clear;
00516 break;
00517 default:
00518 assert(0);
00519 }
00520
00521 ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
00522 }
00523 }
00524
00525
00526 void st_flush_clear( struct st_context *st )
00527 {
00528
00529
00530
00531 pipe_buffer_reference(st->pipe->screen, &st->clear.vbuf, NULL);
00532 st->clear.vbuf_slot = 0;
00533 }
00534
00535
00536
00542 static void st_clear(GLcontext *ctx, GLbitfield mask)
00543 {
00544 static const GLbitfield BUFFER_BITS_DS
00545 = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
00546 struct st_context *st = ctx->st;
00547 struct gl_renderbuffer *depthRb
00548 = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
00549 struct gl_renderbuffer *stencilRb
00550 = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
00551 GLbitfield cmask = mask & BUFFER_BITS_COLOR;
00552
00553
00554 st_validate_state( st );
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 if (cmask) {
00565 GLuint b;
00566 for (b = 0; cmask; b++) {
00567 if (cmask & (1 << b)) {
00568 struct gl_renderbuffer *rb
00569 = ctx->DrawBuffer->Attachment[b].Renderbuffer;
00570 assert(rb);
00571 clear_color_buffer(ctx, rb);
00572 cmask &= ~(1 << b);
00573 }
00574 assert(b < BUFFER_COUNT);
00575 }
00576 }
00577
00578 if (mask & BUFFER_BIT_ACCUM) {
00579 st_clear_accum_buffer(ctx,
00580 ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
00581 }
00582
00583 if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
00584
00585 clear_depth_stencil_buffer(ctx, depthRb);
00586 }
00587 else {
00588
00589 if (mask & BUFFER_BIT_DEPTH) {
00590 clear_depth_buffer(ctx, depthRb);
00591 }
00592 if (mask & BUFFER_BIT_STENCIL) {
00593 clear_stencil_buffer(ctx, stencilRb);
00594 }
00595 }
00596 }
00597
00598
00599 void st_init_clear_functions(struct dd_function_table *functions)
00600 {
00601 functions->Clear = st_clear;
00602 }