#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"
return;
enum pipe_shader_ir preferred_ir =
- screen->get_shader_param(screen, MESA_SHADER_VERTEX,
+ screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_PREFERRED_IR);
if (preferred_ir == PIPE_SHADER_IR_NIR) {
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 =
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 */
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;
/* XXX if DrawPixels image is larger than max texture size, break
* it up into chunks.
*/
- maxSize = 1 << (pipe->screen->get_param(pipe->screen,
- PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ maxSize = pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_TEXTURE_2D_SIZE);
assert(width <= maxSize);
assert(height <= maxSize);
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);
}
return fpv;
}
+/**
+ * Get fragment program variant for a glDrawPixels command
+ * for COLOR_INDEX data
+ */
+static struct st_fp_variant *
+get_color_index_fp_variant(struct st_context *st)
+{
+ struct gl_context *ctx = st->ctx;
+ struct st_fp_variant_key key;
+ struct st_fp_variant *fpv;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st->has_shareable_shaders ? NULL : st;
+ key.drawpixels = 1;
+ /* Since GL is always in RGBA mode MapColorFlag does not
+ * affect GL_COLOR_INDEX format.
+ * Scale and bias also never affect GL_COLOR_INDEX format.
+ */
+ key.scaleAndBias = 0;
+ key.pixelMaps = 0;
+ key.clamp_color = st->clamp_frag_color_in_shader &&
+ ctx->Color._ClampFragmentColor;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
+
+ return fpv;
+}
+
/**
* Clamp glDrawPixels width and height to the maximum texture size.
clamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height,
struct gl_pixelstore_attrib *unpack)
{
- const int maxSize =
- 1 << (pipe->screen->get_param(pipe->screen,
- PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ const int maxSize = pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_TEXTURE_2D_SIZE);
if (*width > maxSize) {
if (unpack->RowLength == 0)
}
+/**
+ * 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()
*/
write_stencil);
}
else {
- fpv = get_color_fp_variant(st);
+ fpv = (format != GL_COLOR_INDEX) ? get_color_fp_variant(st) :
+ get_color_index_fp_variant(st);
driver_fp = fpv->driver_shader;
- if (ctx->Pixel.MapColorFlag) {
+ if (ctx->Pixel.MapColorFlag && format != GL_COLOR_INDEX) {
pipe_sampler_view_reference(&sv[1],
st->pixel_xfer.pixelmap_sampler_view);
num_sampler_view++;
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,
struct gl_pixelstore_attrib pack, unpack;
GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH;
- if (type == GL_COLOR &&
- ctx->Pixel.ZoomX == 1.0 &&
+ if (ctx->Pixel.ZoomX == 1.0 &&
ctx->Pixel.ZoomY == 1.0 &&
- ctx->_ImageTransferState == 0x0 &&
- !ctx->Color.BlendEnabled &&
- !ctx->Color.AlphaEnabled &&
- (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
- !ctx->Depth.Test &&
- !ctx->Fog.Enabled &&
- !ctx->Stencil.Enabled &&
- !ctx->FragmentProgram.Enabled &&
- !ctx->VertexProgram.Enabled &&
- !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
- !_mesa_ati_fragment_shader_enabled(ctx) &&
- ctx->DrawBuffer->_NumColorDrawBuffers == 1 &&
+ (type != GL_COLOR ||
+ (ctx->_ImageTransferState == 0x0 &&
+ !ctx->Color.BlendEnabled &&
+ !ctx->Color.AlphaEnabled &&
+ (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
+ !ctx->Depth.Test &&
+ !ctx->Fog.Enabled &&
+ !ctx->Stencil.Enabled &&
+ !ctx->FragmentProgram.Enabled &&
+ !ctx->VertexProgram.Enabled &&
+ !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
+ !_mesa_ati_fragment_shader_enabled(ctx) &&
+ ctx->DrawBuffer->_NumColorDrawBuffers == 1)) &&
!ctx->Query.CondRenderQuery &&
!ctx->Query.CurrentOcclusionObject) {
struct st_renderbuffer *rbRead, *rbDraw;
drawW = readW;
drawH = readH;
- rbRead = st_get_color_read_renderbuffer(ctx);
- rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
+ if (type == GL_COLOR) {
+ rbRead = st_get_color_read_renderbuffer(ctx);
+ rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
+ } else if (type == GL_DEPTH || type == GL_DEPTH_STENCIL) {
+ rbRead = st_renderbuffer(ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer);
+ rbDraw = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer);
+ } else if (type == GL_STENCIL) {
+ rbRead = st_renderbuffer(ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
+ rbDraw = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
+ } else {
+ return false;
+ }
/* Flip src/dst position depending on the orientation of buffers. */
if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
blit.dst.box.width = drawW;
blit.dst.box.height = drawH;
blit.dst.box.depth = 1;
- blit.mask = PIPE_MASK_RGBA;
blit.filter = PIPE_TEX_FILTER_NEAREST;
+ if (type == GL_COLOR)
+ blit.mask |= PIPE_MASK_RGBA;
+ if (type == GL_DEPTH)
+ blit.mask |= PIPE_MASK_Z;
+ if (type == GL_STENCIL)
+ blit.mask |= PIPE_MASK_S;
+ if (type == GL_DEPTH_STENCIL)
+ blit.mask |= PIPE_MASK_ZS;
+
if (ctx->DrawBuffer != ctx->WinSysDrawBuffer)
st_window_rectangles_to_blit(ctx, &blit);
st_validate_state(st, ST_PIPELINE_META);
+ if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
+ return;
+
if (type == GL_DEPTH_STENCIL) {
/* XXX make this more efficient */
st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
return;
}
- if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
- return;
-
/*
* The subsequent code implements glCopyPixels by copying the source
* pixels into a temporary texture that's then applied to a textured quad.
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 {
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);
}
}
/* 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,