/**************************************************************************
- *
+ *
* Copyright 2007 VMware, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* 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.
* 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.
- *
+ *
**************************************************************************/
/*
*/
#include "main/errors.h"
-#include "main/imports.h"
+
#include "main/image.h"
#include "main/bufferobj.h"
#include "main/blit.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "tgsi/tgsi_ureg.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_simple_shaders.h"
static nir_ssa_def *
sample_via_nir(nir_builder *b, nir_variable *texcoord,
- const char *name, int sampler)
+ const char *name, int sampler, enum glsl_base_type base_type,
+ nir_alu_type alu_type)
{
const struct glsl_type *sampler2D =
- glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);
+ glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, base_type);
nir_variable *var =
nir_variable_create(b->shader, nir_var_uniform, sampler2D, name);
tex->op = nir_texop_tex;
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
tex->coord_components = 2;
- tex->dest_type = nir_type_float;
+ tex->dest_type = alu_type;
tex->src[0].src_type = nir_tex_src_texture_deref;
tex->src[0].src = nir_src_for_ssa(&deref->dest.ssa);
tex->src[1].src_type = nir_tex_src_sampler_deref;
nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(),
"gl_FragDepth");
out->data.location = FRAG_RESULT_DEPTH;
- nir_ssa_def *depth = sample_via_nir(&b, texcoord, "depth", 0);
+ nir_ssa_def *depth = sample_via_nir(&b, texcoord, "depth", 0,
+ GLSL_TYPE_FLOAT, nir_type_float);
nir_store_var(&b, out, depth, 0x1);
/* Also copy color */
nir_variable_create(b.shader, nir_var_shader_out, glsl_uint_type(),
"gl_FragStencilRefARB");
out->data.location = FRAG_RESULT_STENCIL;
- nir_ssa_def *stencil = sample_via_nir(&b, texcoord, "stencil", 1);
+ nir_ssa_def *stencil = sample_via_nir(&b, texcoord, "stencil", 1,
+ GLSL_TYPE_UINT, nir_type_uint);
nir_store_var(&b, out, stencil, 0x1);
}
MESA_SHADER_VERTEX, 3,
inputs, outputs, NULL, 0);
} else {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_COLOR,
- st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD :
- TGSI_SEMANTIC_GENERIC };
+ const enum tgsi_semantic semantic_names[] = {
+ TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_COLOR,
+ st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD :
+ TGSI_SEMANTIC_GENERIC
+ };
const uint semantic_indexes[] = { 0, 0, 0 };
st->passthrough_vs =
unpack->SkipPixels != 0 ||
unpack->SkipRows != 0 ||
unpack->SwapBytes ||
- _mesa_is_bufferobj(unpack->BufferObj)) {
+ unpack->BufferObj) {
/* we don't allow non-default pixel unpacking values */
return NULL;
}
pipeFormat = st_choose_format(st, intFormat, format, type,
st->internal_target, 0, 0,
- PIPE_BIND_SAMPLER_VIEW, FALSE);
+ PIPE_BIND_SAMPLER_VIEW,
+ false, false);
assert(pipeFormat != PIPE_FORMAT_NONE);
}
unpack);
}
else {
- bool MAYBE_UNUSED success;
+ ASSERTED bool success;
success = _mesa_texstore(ctx, 2, /* dims */
baseInternalFormat, /* baseInternalFormat */
mformat, /* mesa_format */
ctx->_ImageTransferState = imageTransferStateSave;
}
- _mesa_unmap_pbo_source(ctx, unpack);
-
#if USE_DRAWPIXELS_CACHE
cache_drawpixels_image(st, width, height, format, type, unpack, pixels, pt);
#endif
+ _mesa_unmap_pbo_source(ctx, unpack);
+
return pt;
}
const unsigned fb_width = _mesa_geometric_width(ctx->DrawBuffer);
const unsigned fb_height = _mesa_geometric_height(ctx->DrawBuffer);
GLfloat x0, y0, x1, y1;
- GLsizei MAYBE_UNUSED maxSize;
+ ASSERTED GLsizei maxSize;
boolean normalized = sv[0]->texture->target == PIPE_TEXTURE_2D;
unsigned cso_state_mask;
ctx->Color._ClampFragmentColor;
rasterizer.half_pixel_center = 1;
rasterizer.bottom_edge_rule = 1;
- rasterizer.depth_clip_near = !ctx->Transform.DepthClampNear;
- rasterizer.depth_clip_far = !ctx->Transform.DepthClampFar;
+ rasterizer.depth_clip_near = st->clamp_frag_depth_in_shader ||
+ !ctx->Transform.DepthClampNear;
+ rasterizer.depth_clip_far = st->clamp_frag_depth_in_shader ||
+ !ctx->Transform.DepthClampFar;
rasterizer.scissor = ctx->Scissor.EnableFlags;
cso_set_rasterizer(cso, &rasterizer);
}
/* viewport state: viewport matching window dims */
cso_set_viewport_dims(cso, fb_width, fb_height, TRUE);
- cso_set_vertex_elements(cso, 3, st->util_velems);
+ st->util_velems.count = 3;
+ cso_set_vertex_elements(cso, &st->util_velems);
cso_set_stream_outputs(cso, 0, NULL, NULL);
/* Compute Gallium window coords (y=0=top) with pixel zoom.
y = ctx->DrawBuffer->Height - y - height;
}
- if (format == GL_STENCIL_INDEX &&
+ if (format == GL_STENCIL_INDEX &&
_mesa_is_format_packed_depth_stencil(strb->Base.Format)) {
/* writing stencil to a combined depth+stencil buffer */
usage = PIPE_TRANSFER_READ_WRITE;
}
+/**
+ * Compute the effective raster z position. This performs depth-clamping
+ * if needed.
+ */
+static float
+get_effective_raster_z(struct gl_context *ctx)
+{
+ float z = ctx->Current.RasterPos[2];
+ if (st_context(ctx)->clamp_frag_depth_in_shader) {
+ GLfloat depth_near;
+ GLfloat depth_far;
+ if (ctx->ViewportArray[0].Near < ctx->ViewportArray[0].Far) {
+ depth_near = ctx->ViewportArray[0].Near;
+ depth_far = ctx->ViewportArray[0].Far;
+ } else {
+ depth_near = ctx->ViewportArray[0].Far;
+ depth_far = ctx->ViewportArray[0].Near;
+ }
+
+ if (ctx->Transform.DepthClampNear)
+ z = MAX2(z, depth_near);
+ if (ctx->Transform.DepthClampFar)
+ z = MIN2(z, depth_far);
+ }
+ return z;
+}
+
+
/**
* Called via ctx->Driver.DrawPixels()
*/
fpv = (format != GL_COLOR_INDEX) ? get_color_fp_variant(st) :
get_color_index_fp_variant(st);
- driver_fp = fpv->driver_shader;
+ driver_fp = fpv->base.driver_shader;
if (ctx->Pixel.MapColorFlag && format != GL_COLOR_INDEX) {
pipe_sampler_view_reference(&sv[1],
num_sampler_view++;
}
- draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
+ draw_textured_quad(ctx, x, y, get_effective_raster_z(ctx),
width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
sv,
GLboolean invertTex = GL_FALSE;
GLint readX, readY, readW, readH;
struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
+ GLboolean write_stencil = GL_FALSE;
+ GLboolean write_depth = GL_FALSE;
_mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
return;
- if (type == GL_DEPTH_STENCIL) {
- /* XXX make this more efficient */
+ /* fallback if the driver can't do stencil exports */
+ if (type == GL_DEPTH_STENCIL &&
+ !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
return;
}
- if (type == GL_STENCIL) {
- /* can't use texturing to do stencil */
+ /* fallback if the driver can't do stencil exports */
+ if (type == GL_STENCIL &&
+ !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
return;
}
rbRead = st_get_color_read_renderbuffer(ctx);
- driver_fp = fpv->driver_shader;
+ driver_fp = fpv->base.driver_shader;
if (ctx->Pixel.MapColorFlag) {
pipe_sampler_view_reference(&sv[1],
* into the constant buffer, we need to update them
*/
st_upload_constants(st, &st->fp->Base);
- }
- else {
- assert(type == GL_DEPTH);
+ } else if (type == GL_DEPTH) {
rbRead = st_renderbuffer(ctx->ReadBuffer->
Attachment[BUFFER_DEPTH].Renderbuffer);
-
driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
+ } else if (type == GL_STENCIL) {
+ rbRead = st_renderbuffer(ctx->ReadBuffer->
+ Attachment[BUFFER_STENCIL].Renderbuffer);
+ driver_fp = get_drawpix_z_stencil_program(st, GL_FALSE, GL_TRUE);
+ } else {
+ assert(type == GL_DEPTH_STENCIL);
+ rbRead = st_renderbuffer(ctx->ReadBuffer->
+ Attachment[BUFFER_DEPTH].Renderbuffer);
+ driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_TRUE);
}
+
/* Choose the format for the temporary texture. */
srcFormat = rbRead->texture->format;
srcBind = PIPE_BIND_SAMPLER_VIEW |
if (type == GL_DEPTH) {
srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE,
GL_NONE, st->internal_target, 0, 0,
- srcBind, FALSE);
+ srcBind, false, false);
+ }
+ else if (type == GL_STENCIL) {
+ /* can't use texturing, fallback to copy */
+ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
+ return;
}
else {
assert(type == GL_COLOR);
if (util_format_is_float(srcFormat)) {
srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE,
GL_NONE, st->internal_target, 0, 0,
- srcBind, FALSE);
+ srcBind, false, false);
}
else if (util_format_is_pure_sint(srcFormat)) {
srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE,
GL_NONE, st->internal_target, 0, 0,
- srcBind, FALSE);
+ srcBind, false, false);
}
else if (util_format_is_pure_uint(srcFormat)) {
srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE,
GL_NONE, st->internal_target, 0, 0,
- srcBind, FALSE);
+ srcBind, false, false);
}
else if (util_format_is_snorm(srcFormat)) {
srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE,
GL_NONE, st->internal_target, 0, 0,
- srcBind, FALSE);
+ srcBind, false, false);
}
else {
srcFormat = st_choose_format(st, GL_RGBA, GL_NONE,
GL_NONE, st->internal_target, 0, 0,
- srcBind, FALSE);
+ srcBind, false, false);
}
}
return;
}
+ /* Create a second sampler view to read stencil */
+ if (type == GL_STENCIL || type == GL_DEPTH_STENCIL) {
+ write_stencil = GL_TRUE;
+ if (type == GL_DEPTH_STENCIL)
+ write_depth = GL_TRUE;
+ enum pipe_format stencil_format =
+ util_format_stencil_only(pt->format);
+ /* we should not be doing pixel map/transfer (see above) */
+ assert(num_sampler_view == 1);
+ sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
+ stencil_format);
+ if (!sv[1]) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
+ pipe_resource_reference(&pt, NULL);
+ pipe_sampler_view_reference(&sv[0], NULL);
+ return;
+ }
+ num_sampler_view++;
+ }
/* Copy the src region to the temporary texture. */
{
struct pipe_blit_info blit;
blit.dst.box.width = readW;
blit.dst.box.height = readH;
blit.dst.box.depth = 1;
- blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
+ if (type == GL_DEPTH)
+ blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
+ else if (type == GL_STENCIL)
+ blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_Z;
+ else
+ blit.mask = util_format_get_mask(pt->format);
blit.filter = PIPE_TEX_FILTER_NEAREST;
pipe->blit(pipe, &blit);
/* OK, the texture 'pt' contains the src image/pixels. Now draw a
* textured quad with that texture.
*/
- draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
+
+ draw_textured_quad(ctx, dstx, dsty, get_effective_raster_z(ctx),
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
sv,
num_sampler_view,
st->passthrough_vs,
driver_fp, fpv,
ctx->Current.Attrib[VERT_ATTRIB_COLOR0],
- invertTex, GL_FALSE, GL_FALSE);
+ invertTex, write_depth, write_stencil);
pipe_resource_reference(&pt, NULL);
pipe_sampler_view_reference(&sv[0], NULL);
for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) {
if (st->drawpix.zs_shaders[i])
- cso_delete_fragment_shader(st->cso_context,
- st->drawpix.zs_shaders[i]);
+ st->pipe->delete_fs_state(st->pipe, st->drawpix.zs_shaders[i]);
}
if (st->passthrough_vs)
- cso_delete_vertex_shader(st->cso_context, st->passthrough_vs);
+ st->pipe->delete_vs_state(st->pipe, st->passthrough_vs);
/* Free cache data */
for (i = 0; i < ARRAY_SIZE(st->drawpix_cache.entries); i++) {