#include "pipe/p_inlines.h"
#include "util/u_tile.h"
#include "util/u_draw_quad.h"
+#include "util/u_math.h"
#include "shader/prog_instruction.h"
#include "cso_cache/cso_context.h"
static struct st_fragment_program *
combined_drawpix_fragment_program(GLcontext *ctx)
{
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct st_fragment_program *stfp;
if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
enum pipe_format pipeFormat;
GLuint cpp;
GLenum baseFormat;
+ int ptw, pth;
baseFormat = _mesa_base_format(format);
assert(pipeFormat);
cpp = st_sizeof_format(pipeFormat);
- pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
if (!pixels)
return NULL;
- pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1,
+ /* Need to use POT texture? */
+ ptw = width;
+ pth = height;
+ if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+ int l2pt, maxSize;
+
+ l2pt = util_logbase2(width);
+ if (1<<l2pt != width) {
+ ptw = 1<<(l2pt+1);
+ }
+ l2pt = util_logbase2(height);
+ if (1<<l2pt != height) {
+ pth = 1<<(l2pt+1);
+ }
+
+ /* Check against maximum texture size */
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ assert(ptw <= maxSize);
+ assert(pth <= maxSize);
+ }
+
+ pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, ptw, pth, 1,
PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
return NULL;
}
ctx->_ImageTransferState = imageTransferStateSave;
}
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
return pt;
}
static void
draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
GLfloat x1, GLfloat y1, const GLfloat *color,
- GLboolean invertTex)
+ GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord)
{
- struct st_context *st = ctx->st;
- struct pipe_context *pipe = ctx->st->pipe;
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */
/* setup vertex data */
const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f;
const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f;
const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f;
- const GLfloat sLeft = 0.0f, sRight = 1.0f;
- const GLfloat tTop = invertTex, tBot = 1.0f - tTop;
+ const GLfloat sLeft = 0.0f, sRight = maxXcoord;
+ const GLfloat tTop = invertTex ? maxYcoord : 0.0f;
+ const GLfloat tBot = invertTex ? 0.0f : maxYcoord;
GLuint tex, i;
/* upper-left */
const GLfloat *color,
GLboolean invertTex)
{
- struct st_context *st = ctx->st;
- struct pipe_context *pipe = ctx->st->pipe;
- struct cso_context *cso = ctx->st->cso_context;
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct cso_context *cso = st->cso_context;
GLfloat x0, y0, x1, y1;
GLsizei maxSize;
y0 = (GLfloat) y;
y1 = y + height * ctx->Pixel.ZoomY;
- draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
+ draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
+ (GLfloat) width / pt->width[0],
+ (GLfloat) height / pt->height[0]);
/* restore state */
cso_restore_rasterizer(cso);
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels)
{
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *strb;
+ enum pipe_transfer_usage usage;
struct pipe_transfer *pt;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
GLint skipPixels;
y = ctx->DrawBuffer->Height - y - height;
}
+ if(format != GL_DEPTH_STENCIL &&
+ pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0)
+ usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ usage = PIPE_TRANSFER_WRITE;
+
pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, x, y,
+ usage, x, y,
width, height);
stmap = screen->transfer_map(screen, pt);
- pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
assert(pixels);
/* if width > MAX_WIDTH, have to process image in chunks */
case PIPE_FORMAT_S8_UNORM:
{
ubyte *dest = stmap + spanY * pt->stride + spanX;
+ assert(usage == PIPE_TRANSFER_WRITE);
memcpy(dest, sValues, spanWidth);
}
break;
if (format == GL_DEPTH_STENCIL) {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_WRITE);
for (k = 0; k < spanWidth; k++) {
dest[k] = zValues[k] | (sValues[k] << 24);
}
else {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (k = 0; k < spanWidth; k++) {
dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
}
if (format == GL_DEPTH_STENCIL) {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_WRITE);
for (k = 0; k < spanWidth; k++) {
- dest[k] = zValues[k] | (sValues[k] << 24);
+ dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
}
}
else {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (k = 0; k < spanWidth; k++) {
dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
}
skipPixels += spanWidth;
}
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
/* unmap the stencil buffer */
screen->transfer_unmap(screen, pt);
{
struct st_fragment_program *stfp;
struct st_vertex_program *stvp;
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct pipe_surface *ps;
- GLuint bufferFormat;
const GLfloat *color;
if (format == GL_STENCIL_INDEX ||
return;
}
- _mesa_set_vp_override( ctx, TRUE );
- _mesa_update_state( ctx );
+ /* Mesa state should be up to date by now */
+ assert(ctx->NewState == 0x0);
st_validate_state(st);
if (format == GL_DEPTH_COMPONENT) {
ps = st->state.framebuffer.zsbuf;
- stfp = make_fragment_shader_z(ctx->st);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
+ stfp = make_fragment_shader_z(st);
+ stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
color = ctx->Current.RasterColor;
}
else {
ps = st->state.framebuffer.cbufs[0];
stfp = combined_drawpix_fragment_program(ctx);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
+ stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
color = NULL;
}
- bufferFormat = ps->format;
-
/* draw with textured quad */
{
struct pipe_texture *pt
- = make_texture(ctx->st, width, height, format, type, unpack, pixels);
+ = make_texture(st, width, height, format, type, unpack, pixels);
if (pt) {
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
pipe_texture_reference(&pt, NULL);
}
}
-
- _mesa_set_vp_override( ctx, FALSE );
}
{
struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
struct pipe_screen *screen = ctx->st->pipe->screen;
+ enum pipe_transfer_usage usage;
struct pipe_transfer *ptDraw;
ubyte *drawMap;
ubyte *buffer;
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
&ctx->DefaultPacking, buffer);
+ if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
+ usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ usage = PIPE_TRANSFER_WRITE;
+
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+ dsty = rbDraw->Base.Height - dsty - height;
+ }
+
ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx),
rbDraw->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, dstx, dsty,
+ usage, dstx, dsty,
width, height);
assert(ptDraw->block.width == 1);
assert(ptDraw->block.height == 1);
-
+
/* map the stencil buffer */
drawMap = screen->transfer_map(screen, ptDraw);
{
uint *dst4 = (uint *) dst;
int j;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (j = 0; j < width; j++) {
*dst4 = (*dst4 & 0xffffff) | (src[j] << 24);
dst4++;
{
uint *dst4 = (uint *) dst;
int j;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (j = 0; j < width; j++) {
*dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff);
dst4++;
}
break;
case PIPE_FORMAT_S8_UNORM:
+ assert(usage == PIPE_TRANSFER_WRITE);
memcpy(dst, src, width);
break;
default:
GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type)
{
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *rbRead;
struct pipe_texture *pt;
GLfloat *color;
enum pipe_format srcFormat, texFormat;
+ int ptw, pth;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
st_validate_state(st);
+ if (srcx < 0) {
+ width -= -srcx;
+ dstx += -srcx;
+ srcx = 0;
+ }
+
+ if (srcy < 0) {
+ height -= -srcy;
+ dsty += -srcy;
+ srcy = 0;
+ }
+
+ if (dstx < 0) {
+ width -= -dstx;
+ srcx += -dstx;
+ dstx = 0;
+ }
+
+ if (dsty < 0) {
+ height -= -dsty;
+ srcy += -dsty;
+ dsty = 0;
+ }
+
+ if (width < 0 || height < 0)
+ return;
+
+
if (type == GL_STENCIL) {
/* can't use texturing to do stencil */
copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
stfp = combined_drawpix_fragment_program(ctx);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
+ stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
}
else {
assert(type == GL_DEPTH);
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- stfp = make_fragment_shader_z(ctx->st);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
+ stfp = make_fragment_shader_z(st);
+ stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
}
srcFormat = rbRead->texture->format;
}
}
- pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
- width, height, 1,
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+ srcy = ctx->DrawBuffer->Height - srcy - height;
+
+ if (srcy < 0) {
+ height -= -srcy;
+ srcy = 0;
+ }
+
+ if (height < 0)
+ return;
+ }
+
+ /* Need to use POT texture? */
+ ptw = width;
+ pth = height;
+ if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+ int l2pt, maxSize;
+
+ l2pt = util_logbase2(width);
+ if (1<<l2pt != width) {
+ ptw = 1<<(l2pt+1);
+ }
+ l2pt = util_logbase2(height);
+ if (1<<l2pt != height) {
+ pth = 1<<(l2pt+1);
+ }
+
+ /* Check against maximum texture size */
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ assert(ptw <= maxSize);
+ assert(pth <= maxSize);
+ }
+
+ pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
+ ptw, pth, 1,
PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt)
return;
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
- srcy = ctx->DrawBuffer->Height - srcy - height;
- }
if (srcFormat == texFormat) {
/* copy source framebuffer surface into mipmap/texture */
st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0,
PIPE_TRANSFER_READ, srcx, srcy, width,
height);
+ struct pipe_transfer *ptTex;
+ enum pipe_transfer_usage transfer_usage;
+
+ if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
+ transfer_usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ transfer_usage = PIPE_TRANSFER_WRITE;
- struct pipe_transfer *ptTex =
- st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, PIPE_TRANSFER_WRITE,
- 0, 0, width, height);
+ ptTex = st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, transfer_usage,
+ 0, 0, width, height);
if (type == GL_COLOR) {
/* alternate path using get/put_tile() */