/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
* All Rights Reserved.
* Copyright 2009 VMware, Inc. All Rights Reserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Keith Whitwell <keithw@vmware.com>
* Brian Paul
* Michel Dänzer
*/
cso_delete_vertex_shader(st->cso_context, st->clear.vs);
st->clear.vs = NULL;
}
+ if (st->clear.vs_layered) {
+ cso_delete_vertex_shader(st->cso_context, st->clear.vs_layered);
+ st->clear.vs_layered = NULL;
+ }
+ if (st->clear.gs_layered) {
+ cso_delete_geometry_shader(st->cso_context, st->clear.gs_layered);
+ st->clear.gs_layered = NULL;
+ }
}
/**
* Helper function to set the fragment shaders.
*/
-static INLINE void
+static inline void
set_fragment_shader(struct st_context *st)
{
if (!st->clear.fs)
/**
* Helper function to set the vertex shader.
*/
-static INLINE void
+static inline void
set_vertex_shader(struct st_context *st)
{
/* vertex shader - still required to provide the linkage between
const uint semantic_indexes[] = { 0, 0 };
st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
semantic_names,
- semantic_indexes);
+ semantic_indexes,
+ FALSE);
}
cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
+ cso_set_geometry_shader_handle(st->cso_context, NULL);
}
{
struct pipe_context *pipe = st->pipe;
- if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) ||
- !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) {
- assert(!"Got layered clear, but the VS layer output is unsupported");
+ if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID)) {
+ assert(!"Got layered clear, but VS instancing is unsupported");
set_vertex_shader(st);
return;
}
if (!st->clear.vs_layered) {
- st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
+ bool vs_layer =
+ pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT);
+ if (vs_layer) {
+ st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
+ } else {
+ st->clear.vs_layered = util_make_layered_clear_helper_vertex_shader(pipe);
+ st->clear.gs_layered = util_make_layered_clear_geometry_shader(pipe);
+ }
}
cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered);
+ cso_set_geometry_shader_handle(st->cso_context, st->clear.gs_layered);
}
return;
}
+ /* Convert Z from [0,1] to [-1,1] range */
+ z = z * 2.0f - 1.0f;
+
/* positions */
vertices[0][0][0] = x0;
vertices[0][0][1] = y0;
util_framebuffer_get_num_layers(&st->state.framebuffer);
/*
- printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
+ printf("%s %s%s%s %f,%f %f,%f\n", __func__,
color ? "color, " : "",
depth ? "depth, " : "",
stencil ? "stencil" : "",
cso_save_depth_stencil_alpha(st->cso_context);
cso_save_rasterizer(st->cso_context);
cso_save_sample_mask(st->cso_context);
+ cso_save_min_samples(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_tessctrl_shader(st->cso_context);
+ cso_save_tesseval_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);
}
cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
- cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
cso_set_sample_mask(st->cso_context, ~0);
+ cso_set_min_samples(st->cso_context, 1);
cso_set_rasterizer(st->cso_context, &st->clear.raster);
/* viewport state: viewport matching window dims */
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.scale[2] = 0.5f;
vp.translate[0] = 0.5f * fb_width;
vp.translate[1] = 0.5f * fb_height;
- vp.translate[2] = 0.0f;
- vp.translate[3] = 0.0f;
+ vp.translate[2] = 0.5f;
cso_set_viewport(st->cso_context, &vp);
}
set_fragment_shader(st);
- cso_set_geometry_shader_handle(st->cso_context, NULL);
+ cso_set_tessctrl_shader_handle(st->cso_context, NULL);
+ cso_set_tesseval_shader_handle(st->cso_context, NULL);
if (num_layers > 1)
set_vertex_shader_layered(st);
cso_restore_depth_stencil_alpha(st->cso_context);
cso_restore_rasterizer(st->cso_context);
cso_restore_sample_mask(st->cso_context);
+ cso_restore_min_samples(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_tessctrl_shader(st->cso_context);
+ cso_restore_tesseval_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);
/**
* Return if the scissor must be enabled during the clear.
*/
-static INLINE GLboolean
+static inline GLboolean
is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
{
- return ctx->Scissor.Enabled &&
- (ctx->Scissor.X > 0 ||
- ctx->Scissor.Y > 0 ||
- (unsigned) ctx->Scissor.Width < rb->Width ||
- (unsigned) ctx->Scissor.Height < rb->Height);
+ return (ctx->Scissor.EnableFlags & 1) &&
+ (ctx->Scissor.ScissorArray[0].X > 0 ||
+ ctx->Scissor.ScissorArray[0].Y > 0 ||
+ (unsigned) ctx->Scissor.ScissorArray[0].Width < rb->Width ||
+ (unsigned) ctx->Scissor.ScissorArray[0].Height < rb->Height);
}
/**
* Return if all of the color channels are masked.
*/
-static INLINE GLboolean
+static inline GLboolean
is_color_disabled(struct gl_context *ctx, int i)
{
return !ctx->Color.ColorMask[i][0] &&
/**
* Return if any of the color channels are masked.
*/
-static INLINE GLboolean
+static inline GLboolean
is_color_masked(struct gl_context *ctx, int i)
{
return !ctx->Color.ColorMask[i][0] ||
}
+/**
+ * Return if all of the stencil bits are masked.
+ */
+static inline GLboolean
+is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+ const GLuint stencilMax = 0xff;
+
+ assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
+ return (ctx->Stencil.WriteMask[0] & stencilMax) == 0;
+}
+
+
/**
* Return if any of the stencil bits are masked.
*/
-static INLINE GLboolean
+static inline GLboolean
is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb)
{
const GLuint stencilMax = 0xff;
if (mask & BUFFER_BITS_COLOR) {
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
+ GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
- if (mask & (1 << b)) {
+ if (b >= 0 && mask & (1 << b)) {
struct gl_renderbuffer *rb
= ctx->DrawBuffer->Attachment[b].Renderbuffer;
struct st_renderbuffer *strb = st_renderbuffer(rb);
if (mask & BUFFER_BIT_DEPTH) {
struct st_renderbuffer *strb = st_renderbuffer(depthRb);
- if (strb->surface) {
+ if (strb->surface && ctx->Depth.Mask) {
if (is_scissor_enabled(ctx, depthRb))
quad_buffers |= PIPE_CLEAR_DEPTH;
else
if (mask & BUFFER_BIT_STENCIL) {
struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
- if (strb->surface) {
+ if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
if (is_scissor_enabled(ctx, stencilRb) ||
is_stencil_masked(ctx, stencilRb))
quad_buffers |= PIPE_CLEAR_STENCIL;
}
}
- /*
- * If we're going to use clear_with_quad() for any reason, use it for
- * everything possible.
+ /* Always clear depth and stencil together.
+ * This can only happen when the stencil writemask is not a full mask.
+ */
+ if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL &&
+ clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL;
+ clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
+ }
+
+ /* Only use quad-based clearing for the renderbuffers which cannot
+ * use pipe->clear. We want to always use pipe->clear for the other
+ * renderbuffers, because it's likely to be faster.
*/
if (quad_buffers) {
- quad_buffers |= clear_buffers;
clear_with_quad(ctx, quad_buffers);
- } else if (clear_buffers) {
+ }
+ if (clear_buffers) {
/* We can't translate the clear color to the colorbuffer format,
* because different colorbuffers may have different formats.
*/