#include "main/texformat.h"
#include "main/teximage.h"
#include "main/texstore.h"
+#include "main/glformats.h"
#include "program/program.h"
#include "program/prog_print.h"
#include "program/prog_instruction.h"
#include "cso_cache/cso_context.h"
-#if FEATURE_drawpix
-
/**
* Check if the given program is:
* 0: MOVE result.color, fragment.color;
return GL_STENCIL_INDEX;
default:
- if (_mesa_is_integer_format(format)) {
+ if (_mesa_is_enum_format_integer(format)) {
switch (type) {
case GL_BYTE:
return GL_RGBA8I;
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
+ return GL_R3_G3_B2;
+
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
return GL_RGBA4;
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return GL_RGB565;
+
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
return GL_RGB5_A1;
/* we'll do pixel transfer in a fragment shader */
ctx->_ImageTransferState = 0x0;
- transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
- PIPE_TRANSFER_WRITE, 0, 0,
- width, height);
-
/* map texture transfer */
- dest = pipe_transfer_map(pipe, transfer);
+ dest = pipe_transfer_map(pipe, pt, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ width, height, &transfer);
/* Put image into texture transfer.
/* unmap */
pipe_transfer_unmap(pipe, transfer);
- pipe->transfer_destroy(pipe, transfer);
assert(success);
}
u_upload_unmap(st->uploader);
- util_draw_vertex_buffer(pipe, st->cso_context, buf, offset,
+ util_draw_vertex_buffer(pipe, st->cso_context, buf,
+ cso_get_aux_vertex_buffer_slot(st->cso_context),
+ offset,
PIPE_PRIM_QUADS,
4, /* verts */
3); /* attribs/vert */
cso_save_rasterizer(cso);
cso_save_viewport(cso);
- cso_save_samplers(cso);
- cso_save_fragment_sampler_views(cso);
+ cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
+ cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
cso_save_fragment_shader(cso);
cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
- cso_save_vertex_buffers(cso);
+ cso_save_aux_vertex_buffer_slot(cso);
if (write_stencil) {
cso_save_depth_stencil_alpha(cso);
cso_save_blend(cso);
struct pipe_rasterizer_state rasterizer;
memset(&rasterizer, 0, sizeof(rasterizer));
rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader &&
- ctx->Color._ClampFragmentColor;
+ ctx->Color._ClampFragmentColor &&
+ !ctx->DrawBuffer->_IntegerColor;
rasterizer.gl_rasterization_rules = 1;
rasterizer.depth_clip = !ctx->Transform.DepthClamp;
rasterizer.scissor = ctx->Scissor.Enabled;
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.normalized_coords = normalized;
- cso_single_sampler(cso, 0, &sampler);
+ cso_single_sampler(cso, PIPE_SHADER_FRAGMENT, 0, &sampler);
if (num_sampler_view > 1) {
- cso_single_sampler(cso, 1, &sampler);
+ cso_single_sampler(cso, PIPE_SHADER_FRAGMENT, 1, &sampler);
}
- cso_single_sampler_done(cso);
+ cso_single_sampler_done(cso, PIPE_SHADER_FRAGMENT);
}
/* viewport state: viewport matching window dims */
cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* texture state: */
- cso_set_fragment_sampler_views(cso, num_sampler_view, sv);
+ cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
/* Compute Gallium window coords (y=0=top) with pixel zoom.
* Recall that these coords are transformed by the current
/* restore state */
cso_restore_rasterizer(cso);
cso_restore_viewport(cso);
- cso_restore_samplers(cso);
- cso_restore_fragment_sampler_views(cso);
+ cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
+ cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
cso_restore_fragment_shader(cso);
cso_restore_vertex_shader(cso);
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
- cso_restore_vertex_buffers(cso);
+ cso_restore_aux_vertex_buffer_slot(cso);
cso_restore_stream_outputs(cso);
if (write_stencil) {
cso_restore_depth_stencil_alpha(cso);
usage = PIPE_TRANSFER_WRITE;
}
- pt = pipe_get_transfer(pipe, strb->texture,
- strb->rtt_level, strb->rtt_face + strb->rtt_slice,
- usage, x, y,
- width, height);
-
- stmap = pipe_transfer_map(pipe, pt);
+ stmap = pipe_transfer_map(pipe, strb->texture,
+ strb->rtt_level, strb->rtt_face + strb->rtt_slice,
+ usage, x, y,
+ width, height, &pt);
pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
assert(pixels);
- sValues = (GLubyte *) malloc(width * sizeof(GLubyte));
- zValues = (GLuint *) malloc(width * sizeof(GLuint));
+ sValues = malloc(width * sizeof(GLubyte));
+ zValues = malloc(width * sizeof(GLuint));
if (sValues && zValues) {
GLint row;
/* unmap the stencil buffer */
pipe_transfer_unmap(pipe, pt);
- pipe->transfer_destroy(pipe, pt);
}
ctx->Pixel.AlphaScale != 1.0);
key.pixelMaps = ctx->Pixel.MapColorFlag;
key.clamp_color = st->clamp_frag_color_in_shader &&
- st->ctx->Color._ClampFragmentColor;
+ st->ctx->Color._ClampFragmentColor &&
+ !st->ctx->DrawBuffer->_IntegerColor;
fpv = st_get_fp_variant(st, st->fp, &key);
}
+/**
+ * Clamp glDrawPixels width and height to the maximum texture size.
+ */
+static void
+clamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *unpack)
+{
+ const unsigned maxSize =
+ 1 << (pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+
+ if (*width > maxSize) {
+ if (unpack->RowLength == 0)
+ unpack->RowLength = *width;
+ *width = maxSize;
+ }
+ if (*height > maxSize) {
+ *height = maxSize;
+ }
+}
+
+
/**
* Called via ctx->Driver.DrawPixels()
*/
struct pipe_sampler_view *sv[2];
int num_sampler_view = 1;
struct st_fp_variant *fpv;
+ struct gl_pixelstore_attrib clippedUnpack;
+
+ /* Mesa state should be up to date by now */
+ assert(ctx->NewState == 0x0);
+
+ st_validate_state(st);
+
+ /* Limit the size of the glDrawPixels to the max texture size.
+ * Strictly speaking, that's not correct but since we don't handle
+ * larger images yet, this is better than crashing.
+ */
+ clippedUnpack = *unpack;
+ unpack = &clippedUnpack;
+ clamp_size(st->pipe, &width, &height, &clippedUnpack);
if (format == GL_DEPTH_STENCIL)
write_stencil = write_depth = GL_TRUE;
return;
}
- /* Mesa state should be up to date by now */
- assert(ctx->NewState == 0x0);
-
- st_validate_state(st);
-
/*
* Get vertex/fragment shaders
*/
* The stencil is written using the shader stencil export
* functionality. */
if (write_stencil) {
- enum pipe_format stencil_format = PIPE_FORMAT_NONE;
-
- switch (pt->format) {
- case PIPE_FORMAT_Z24_UNORM_S8_UINT:
- case PIPE_FORMAT_X24S8_UINT:
- stencil_format = PIPE_FORMAT_X24S8_UINT;
- break;
- case PIPE_FORMAT_S8_UINT_Z24_UNORM:
- case PIPE_FORMAT_S8X24_UINT:
- stencil_format = PIPE_FORMAT_S8X24_UINT;
- break;
- case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
- case PIPE_FORMAT_X32_S8X24_UINT:
- stencil_format = PIPE_FORMAT_X32_S8X24_UINT;
- break;
- case PIPE_FORMAT_S8_UINT:
- stencil_format = PIPE_FORMAT_S8_UINT;
- break;
- default:
- assert(0);
- }
+ enum pipe_format stencil_format =
+ util_format_stencil_only(pt->format);
sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
stencil_format);
dsty = rbDraw->Base.Height - dsty - height;
}
- ptDraw = pipe_get_transfer(pipe,
- rbDraw->texture,
- rbDraw->rtt_level,
- rbDraw->rtt_face + rbDraw->rtt_slice,
- usage, dstx, dsty,
- width, height);
-
- assert(util_format_get_blockwidth(ptDraw->resource->format) == 1);
- assert(util_format_get_blockheight(ptDraw->resource->format) == 1);
+ assert(util_format_get_blockwidth(rbDraw->texture->format) == 1);
+ assert(util_format_get_blockheight(rbDraw->texture->format) == 1);
/* map the stencil buffer */
- drawMap = pipe_transfer_map(pipe, ptDraw);
+ drawMap = pipe_transfer_map(pipe,
+ rbDraw->texture,
+ rbDraw->rtt_level,
+ rbDraw->rtt_face + rbDraw->rtt_slice,
+ usage, dstx, dsty,
+ width, height, &ptDraw);
/* draw */
/* XXX PixelZoom not handled yet */
/* unmap the stencil buffer */
pipe_transfer_unmap(pipe, ptDraw);
- pipe->transfer_destroy(pipe, ptDraw);
}
}
else {
/* CPU-based fallback/conversion */
- struct pipe_transfer *ptRead =
- pipe_get_transfer(st->pipe, rbRead->texture,
+ struct pipe_transfer *ptRead;
+ void *mapRead =
+ pipe_transfer_map(st->pipe, rbRead->texture,
rbRead->rtt_level,
rbRead->rtt_face + rbRead->rtt_slice,
PIPE_TRANSFER_READ,
- readX, readY, readW, readH);
+ readX, readY, readW, readH, &ptRead);
struct pipe_transfer *ptTex;
+ void *mapTex;
enum pipe_transfer_usage transfer_usage;
if (ST_DEBUG & DEBUG_FALLBACK)
else
transfer_usage = PIPE_TRANSFER_WRITE;
- ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage,
- 0, 0, width, height);
+ mapTex = pipe_transfer_map(st->pipe, pt, 0, 0, transfer_usage,
+ 0, 0, width, height, &ptTex);
/* copy image from ptRead surface to ptTex surface */
if (type == GL_COLOR) {
/* alternate path using get/put_tile() */
- GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+ GLfloat *buf = malloc(width * height * 4 * sizeof(GLfloat));
enum pipe_format readFormat, drawFormat;
readFormat = util_format_linear(rbRead->texture->format);
drawFormat = util_format_linear(pt->format);
- pipe_get_tile_rgba_format(pipe, ptRead, 0, 0, readW, readH,
+ pipe_get_tile_rgba_format(ptRead, mapRead, 0, 0, readW, readH,
readFormat, buf);
- pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
+ pipe_put_tile_rgba_format(ptTex, mapTex, pack.SkipPixels,
+ pack.SkipRows,
readW, readH, drawFormat, buf);
free(buf);
}
else {
/* GL_DEPTH */
- GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
- pipe_get_tile_z(pipe, ptRead, 0, 0, readW, readH, buf);
- pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
+ GLuint *buf = malloc(width * height * sizeof(GLuint));
+ pipe_get_tile_z(ptRead, mapRead, 0, 0, readW, readH, buf);
+ pipe_put_tile_z(ptTex, mapTex, pack.SkipPixels, pack.SkipRows,
readW, readH, buf);
free(buf);
}
- pipe->transfer_destroy(pipe, ptRead);
- pipe->transfer_destroy(pipe, ptTex);
+ pipe->transfer_unmap(pipe, ptRead);
+ pipe->transfer_unmap(pipe, ptTex);
}
/* OK, the texture 'pt' contains the src image/pixels. Now draw a
if (st->drawpix.vert_shaders[1])
cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]);
}
-
-#endif /* FEATURE_drawpix */