17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 57117f1b4Smrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 87117f1b4Smrg * to deal in the Software without restriction, including without limitation 97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 117117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 127117f1b4Smrg * 137117f1b4Smrg * The above copyright notice and this permission notice shall be included 147117f1b4Smrg * in all copies or substantial portions of the Software. 157117f1b4Smrg * 167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg */ 247117f1b4Smrg 2501e04c3fSmrg#include "main/errors.h" 26c1f859d4Smrg#include "main/glheader.h" 27c1f859d4Smrg#include "main/macros.h" 287ec681f3Smrg 29af69d88dSmrg#include "main/format_pack.h" 307117f1b4Smrg 317117f1b4Smrg#include "s_context.h" 327117f1b4Smrg#include "s_span.h" 337117f1b4Smrg#include "s_stencil.h" 347117f1b4Smrg#include "s_zoom.h" 357117f1b4Smrg 367117f1b4Smrg 377117f1b4Smrg/** 387117f1b4Smrg * Compute the bounds of the region resulting from zooming a pixel span. 397117f1b4Smrg * The resulting region will be entirely inside the window/scissor bounds 407117f1b4Smrg * so no additional clipping is needed. 417117f1b4Smrg * \param imageX, imageY position of the mage being drawn (gl WindowPos) 427117f1b4Smrg * \param spanX, spanY position of span being drawing 437117f1b4Smrg * \param width number of pixels in span 447117f1b4Smrg * \param x0, x1 returned X bounds of zoomed region [x0, x1) 457117f1b4Smrg * \param y0, y1 returned Y bounds of zoomed region [y0, y1) 467117f1b4Smrg * \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped 477117f1b4Smrg */ 487117f1b4Smrgstatic GLboolean 493464ebd5Sriastradhcompute_zoomed_bounds(struct gl_context *ctx, GLint imageX, GLint imageY, 507117f1b4Smrg GLint spanX, GLint spanY, GLint width, 517117f1b4Smrg GLint *x0, GLint *x1, GLint *y0, GLint *y1) 527117f1b4Smrg{ 537117f1b4Smrg const struct gl_framebuffer *fb = ctx->DrawBuffer; 547117f1b4Smrg GLint c0, c1, r0, r1; 557117f1b4Smrg 5601e04c3fSmrg assert(spanX >= imageX); 5701e04c3fSmrg assert(spanY >= imageY); 587117f1b4Smrg 597117f1b4Smrg /* 607117f1b4Smrg * Compute destination columns: [c0, c1) 617117f1b4Smrg */ 627117f1b4Smrg c0 = imageX + (GLint) ((spanX - imageX) * ctx->Pixel.ZoomX); 637117f1b4Smrg c1 = imageX + (GLint) ((spanX + width - imageX) * ctx->Pixel.ZoomX); 647117f1b4Smrg if (c1 < c0) { 657117f1b4Smrg /* swap */ 667117f1b4Smrg GLint tmp = c1; 677117f1b4Smrg c1 = c0; 687117f1b4Smrg c0 = tmp; 697117f1b4Smrg } 707117f1b4Smrg c0 = CLAMP(c0, fb->_Xmin, fb->_Xmax); 717117f1b4Smrg c1 = CLAMP(c1, fb->_Xmin, fb->_Xmax); 727117f1b4Smrg if (c0 == c1) { 737117f1b4Smrg return GL_FALSE; /* no width */ 747117f1b4Smrg } 757117f1b4Smrg 767117f1b4Smrg /* 777117f1b4Smrg * Compute destination rows: [r0, r1) 787117f1b4Smrg */ 797117f1b4Smrg r0 = imageY + (GLint) ((spanY - imageY) * ctx->Pixel.ZoomY); 807117f1b4Smrg r1 = imageY + (GLint) ((spanY + 1 - imageY) * ctx->Pixel.ZoomY); 817117f1b4Smrg if (r1 < r0) { 827117f1b4Smrg /* swap */ 837117f1b4Smrg GLint tmp = r1; 847117f1b4Smrg r1 = r0; 857117f1b4Smrg r0 = tmp; 867117f1b4Smrg } 877117f1b4Smrg r0 = CLAMP(r0, fb->_Ymin, fb->_Ymax); 887117f1b4Smrg r1 = CLAMP(r1, fb->_Ymin, fb->_Ymax); 897117f1b4Smrg if (r0 == r1) { 907117f1b4Smrg return GL_FALSE; /* no height */ 917117f1b4Smrg } 927117f1b4Smrg 937117f1b4Smrg *x0 = c0; 947117f1b4Smrg *x1 = c1; 957117f1b4Smrg *y0 = r0; 967117f1b4Smrg *y1 = r1; 977117f1b4Smrg 987117f1b4Smrg return GL_TRUE; 997117f1b4Smrg} 1007117f1b4Smrg 1017117f1b4Smrg 1027117f1b4Smrg/** 1037117f1b4Smrg * Convert a zoomed x image coordinate back to an unzoomed x coord. 1047117f1b4Smrg * 'zx' is screen position of a pixel in the zoomed image, who's left edge 1057117f1b4Smrg * is at 'imageX'. 1067117f1b4Smrg * return corresponding x coord in the original, unzoomed image. 1077117f1b4Smrg * This can use this for unzooming X or Y values. 1087117f1b4Smrg */ 109af69d88dSmrgstatic inline GLint 1107117f1b4Smrgunzoom_x(GLfloat zoomX, GLint imageX, GLint zx) 1117117f1b4Smrg{ 1127117f1b4Smrg /* 1137117f1b4Smrg zx = imageX + (x - imageX) * zoomX; 1147117f1b4Smrg zx - imageX = (x - imageX) * zoomX; 1157117f1b4Smrg (zx - imageX) / zoomX = x - imageX; 1167117f1b4Smrg */ 1177117f1b4Smrg GLint x; 11801e04c3fSmrg if (zoomX < 0.0F) 1197117f1b4Smrg zx++; 1207117f1b4Smrg x = imageX + (GLint) ((zx - imageX) / zoomX); 1217117f1b4Smrg return x; 1227117f1b4Smrg} 1237117f1b4Smrg 1247117f1b4Smrg 1257117f1b4Smrg 1267117f1b4Smrg/** 1277117f1b4Smrg * Helper function called from _swrast_write_zoomed_rgba/rgb/ 1287117f1b4Smrg * index/depth_span(). 1297117f1b4Smrg */ 1307117f1b4Smrgstatic void 1313464ebd5Sriastradhzoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span, 1327117f1b4Smrg const GLvoid *src, GLenum format ) 1337117f1b4Smrg{ 134c1f859d4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 1357117f1b4Smrg SWspan zoomed; 1367117f1b4Smrg GLint x0, x1, y0, y1; 1377117f1b4Smrg GLint zoomedWidth; 1387117f1b4Smrg 1397117f1b4Smrg if (!compute_zoomed_bounds(ctx, imgX, imgY, span->x, span->y, span->end, 1407117f1b4Smrg &x0, &x1, &y0, &y1)) { 1417117f1b4Smrg return; /* totally clipped */ 1427117f1b4Smrg } 1437117f1b4Smrg 144c1f859d4Smrg if (!swrast->ZoomedArrays) { 145c1f859d4Smrg /* allocate on demand */ 146af69d88dSmrg swrast->ZoomedArrays = (SWspanarrays *) calloc(1, sizeof(SWspanarrays)); 147c1f859d4Smrg if (!swrast->ZoomedArrays) 148c1f859d4Smrg return; 149c1f859d4Smrg } 150c1f859d4Smrg 1517117f1b4Smrg zoomedWidth = x1 - x0; 15201e04c3fSmrg assert(zoomedWidth > 0); 15301e04c3fSmrg assert(zoomedWidth <= SWRAST_MAX_WIDTH); 1547117f1b4Smrg 1557117f1b4Smrg /* no pixel arrays! must be horizontal spans. */ 15601e04c3fSmrg assert((span->arrayMask & SPAN_XY) == 0); 15701e04c3fSmrg assert(span->primitive == GL_BITMAP); 1587117f1b4Smrg 159c1f859d4Smrg INIT_SPAN(zoomed, GL_BITMAP); 1607117f1b4Smrg zoomed.x = x0; 1617117f1b4Smrg zoomed.end = zoomedWidth; 162c1f859d4Smrg zoomed.array = swrast->ZoomedArrays; 163c1f859d4Smrg zoomed.array->ChanType = span->array->ChanType; 164c1f859d4Smrg if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) 165c1f859d4Smrg zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8; 166c1f859d4Smrg else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) 167c1f859d4Smrg zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16; 168c1f859d4Smrg else 169af69d88dSmrg zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[VARYING_SLOT_COL0]; 1707117f1b4Smrg 171af69d88dSmrg COPY_4V(zoomed.attrStart[VARYING_SLOT_POS], span->attrStart[VARYING_SLOT_POS]); 172af69d88dSmrg COPY_4V(zoomed.attrStepX[VARYING_SLOT_POS], span->attrStepX[VARYING_SLOT_POS]); 173af69d88dSmrg COPY_4V(zoomed.attrStepY[VARYING_SLOT_POS], span->attrStepY[VARYING_SLOT_POS]); 1747117f1b4Smrg 175af69d88dSmrg zoomed.attrStart[VARYING_SLOT_FOGC][0] = span->attrStart[VARYING_SLOT_FOGC][0]; 176af69d88dSmrg zoomed.attrStepX[VARYING_SLOT_FOGC][0] = span->attrStepX[VARYING_SLOT_FOGC][0]; 177af69d88dSmrg zoomed.attrStepY[VARYING_SLOT_FOGC][0] = span->attrStepY[VARYING_SLOT_FOGC][0]; 1787117f1b4Smrg 1797117f1b4Smrg if (format == GL_RGBA || format == GL_RGB) { 1807117f1b4Smrg /* copy Z info */ 1817117f1b4Smrg zoomed.z = span->z; 1827117f1b4Smrg zoomed.zStep = span->zStep; 1837117f1b4Smrg /* we'll generate an array of colorss */ 1847117f1b4Smrg zoomed.interpMask = span->interpMask & ~SPAN_RGBA; 1857117f1b4Smrg zoomed.arrayMask |= SPAN_RGBA; 186af69d88dSmrg zoomed.arrayAttribs |= VARYING_BIT_COL0; /* we'll produce these values */ 18701e04c3fSmrg assert(span->arrayMask & SPAN_RGBA); 1887117f1b4Smrg } 1897117f1b4Smrg else if (format == GL_DEPTH_COMPONENT) { 1907117f1b4Smrg /* Copy color info */ 1917117f1b4Smrg zoomed.red = span->red; 1927117f1b4Smrg zoomed.green = span->green; 1937117f1b4Smrg zoomed.blue = span->blue; 1947117f1b4Smrg zoomed.alpha = span->alpha; 1957117f1b4Smrg zoomed.redStep = span->redStep; 1967117f1b4Smrg zoomed.greenStep = span->greenStep; 1977117f1b4Smrg zoomed.blueStep = span->blueStep; 1987117f1b4Smrg zoomed.alphaStep = span->alphaStep; 1997117f1b4Smrg /* we'll generate an array of depth values */ 2007117f1b4Smrg zoomed.interpMask = span->interpMask & ~SPAN_Z; 2017117f1b4Smrg zoomed.arrayMask |= SPAN_Z; 20201e04c3fSmrg assert(span->arrayMask & SPAN_Z); 2037117f1b4Smrg } 2047117f1b4Smrg else { 2057117f1b4Smrg _mesa_problem(ctx, "Bad format in zoom_span"); 2067117f1b4Smrg return; 2077117f1b4Smrg } 2087117f1b4Smrg 2097117f1b4Smrg /* zoom the span horizontally */ 2107117f1b4Smrg if (format == GL_RGBA) { 2117117f1b4Smrg if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) { 2127117f1b4Smrg const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) src; 2137117f1b4Smrg GLint i; 2147117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2157117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 21601e04c3fSmrg assert(j >= 0); 21701e04c3fSmrg assert(j < (GLint) span->end); 218c1f859d4Smrg COPY_4UBV(zoomed.array->rgba8[i], rgba[j]); 2197117f1b4Smrg } 2207117f1b4Smrg } 2217117f1b4Smrg else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { 2227117f1b4Smrg const GLushort (*rgba)[4] = (const GLushort (*)[4]) src; 2237117f1b4Smrg GLint i; 2247117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2257117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 22601e04c3fSmrg assert(j >= 0); 22701e04c3fSmrg assert(j < (GLint) span->end); 228c1f859d4Smrg COPY_4V(zoomed.array->rgba16[i], rgba[j]); 2297117f1b4Smrg } 2307117f1b4Smrg } 2317117f1b4Smrg else { 2327117f1b4Smrg const GLfloat (*rgba)[4] = (const GLfloat (*)[4]) src; 2337117f1b4Smrg GLint i; 2347117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2357117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 23601e04c3fSmrg assert(j >= 0); 23701e04c3fSmrg assert(j < (GLint) span->end); 238af69d88dSmrg COPY_4V(zoomed.array->attribs[VARYING_SLOT_COL0][i], rgba[j]); 2397117f1b4Smrg } 2407117f1b4Smrg } 2417117f1b4Smrg } 2427117f1b4Smrg else if (format == GL_RGB) { 2437117f1b4Smrg if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) { 2447117f1b4Smrg const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) src; 2457117f1b4Smrg GLint i; 2467117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2477117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 24801e04c3fSmrg assert(j >= 0); 24901e04c3fSmrg assert(j < (GLint) span->end); 250c1f859d4Smrg zoomed.array->rgba8[i][0] = rgb[j][0]; 251c1f859d4Smrg zoomed.array->rgba8[i][1] = rgb[j][1]; 252c1f859d4Smrg zoomed.array->rgba8[i][2] = rgb[j][2]; 253c1f859d4Smrg zoomed.array->rgba8[i][3] = 0xff; 2547117f1b4Smrg } 2557117f1b4Smrg } 2567117f1b4Smrg else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { 2577117f1b4Smrg const GLushort (*rgb)[3] = (const GLushort (*)[3]) src; 2587117f1b4Smrg GLint i; 2597117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2607117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 26101e04c3fSmrg assert(j >= 0); 26201e04c3fSmrg assert(j < (GLint) span->end); 263c1f859d4Smrg zoomed.array->rgba16[i][0] = rgb[j][0]; 264c1f859d4Smrg zoomed.array->rgba16[i][1] = rgb[j][1]; 265c1f859d4Smrg zoomed.array->rgba16[i][2] = rgb[j][2]; 266c1f859d4Smrg zoomed.array->rgba16[i][3] = 0xffff; 2677117f1b4Smrg } 2687117f1b4Smrg } 2697117f1b4Smrg else { 2707117f1b4Smrg const GLfloat (*rgb)[3] = (const GLfloat (*)[3]) src; 2717117f1b4Smrg GLint i; 2727117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2737117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 27401e04c3fSmrg assert(j >= 0); 27501e04c3fSmrg assert(j < (GLint) span->end); 276af69d88dSmrg zoomed.array->attribs[VARYING_SLOT_COL0][i][0] = rgb[j][0]; 277af69d88dSmrg zoomed.array->attribs[VARYING_SLOT_COL0][i][1] = rgb[j][1]; 278af69d88dSmrg zoomed.array->attribs[VARYING_SLOT_COL0][i][2] = rgb[j][2]; 279af69d88dSmrg zoomed.array->attribs[VARYING_SLOT_COL0][i][3] = 1.0F; 2807117f1b4Smrg } 2817117f1b4Smrg } 2827117f1b4Smrg } 2837117f1b4Smrg else if (format == GL_DEPTH_COMPONENT) { 2847117f1b4Smrg const GLuint *zValues = (const GLuint *) src; 2857117f1b4Smrg GLint i; 2867117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 2877117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 28801e04c3fSmrg assert(j >= 0); 28901e04c3fSmrg assert(j < (GLint) span->end); 2907117f1b4Smrg zoomed.array->z[i] = zValues[j]; 2917117f1b4Smrg } 292cdc920a0Smrg /* Now, fall into the RGB path below */ 293cdc920a0Smrg format = GL_RGBA; 2947117f1b4Smrg } 2957117f1b4Smrg 2967117f1b4Smrg /* write the span in rows [r0, r1) */ 2977117f1b4Smrg if (format == GL_RGBA || format == GL_RGB) { 2987117f1b4Smrg /* Writing the span may modify the colors, so make a backup now if we're 2997117f1b4Smrg * going to call _swrast_write_zoomed_span() more than once. 3007117f1b4Smrg * Also, clipping may change the span end value, so store it as well. 3017117f1b4Smrg */ 3027117f1b4Smrg const GLint end = zoomed.end; /* save */ 303af69d88dSmrg void *rgbaSave; 3047117f1b4Smrg const GLint pixelSize = 3057117f1b4Smrg (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : 3067117f1b4Smrg ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) 3077117f1b4Smrg : 4 * sizeof(GLfloat)); 308af69d88dSmrg 309af69d88dSmrg rgbaSave = malloc(zoomed.end * pixelSize); 310af69d88dSmrg if (!rgbaSave) { 311af69d88dSmrg return; 312af69d88dSmrg } 313af69d88dSmrg 3147117f1b4Smrg if (y1 - y0 > 1) { 315cdc920a0Smrg memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize); 3167117f1b4Smrg } 3177117f1b4Smrg for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) { 3187117f1b4Smrg _swrast_write_rgba_span(ctx, &zoomed); 3197117f1b4Smrg zoomed.end = end; /* restore */ 3207117f1b4Smrg if (y1 - y0 > 1) { 3217117f1b4Smrg /* restore the colors */ 322cdc920a0Smrg memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize); 3237117f1b4Smrg } 3247117f1b4Smrg } 325af69d88dSmrg 326af69d88dSmrg free(rgbaSave); 3277117f1b4Smrg } 3287117f1b4Smrg} 3297117f1b4Smrg 3307117f1b4Smrg 3317117f1b4Smrgvoid 3323464ebd5Sriastradh_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY, 3337117f1b4Smrg const SWspan *span, const GLvoid *rgba) 3347117f1b4Smrg{ 3357117f1b4Smrg zoom_span(ctx, imgX, imgY, span, rgba, GL_RGBA); 3367117f1b4Smrg} 3377117f1b4Smrg 3387117f1b4Smrg 3397117f1b4Smrgvoid 3403464ebd5Sriastradh_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY, 3417117f1b4Smrg const SWspan *span, const GLvoid *rgb) 3427117f1b4Smrg{ 3437117f1b4Smrg zoom_span(ctx, imgX, imgY, span, rgb, GL_RGB); 3447117f1b4Smrg} 3457117f1b4Smrg 3467117f1b4Smrg 3477117f1b4Smrgvoid 3483464ebd5Sriastradh_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY, 3497117f1b4Smrg const SWspan *span) 3507117f1b4Smrg{ 3517117f1b4Smrg zoom_span(ctx, imgX, imgY, span, 3527117f1b4Smrg (const GLvoid *) span->array->z, GL_DEPTH_COMPONENT); 3537117f1b4Smrg} 3547117f1b4Smrg 3557117f1b4Smrg 3567117f1b4Smrg/** 3577117f1b4Smrg * Zoom/write stencil values. 3587117f1b4Smrg * No per-fragment operations are applied. 3597117f1b4Smrg */ 3607117f1b4Smrgvoid 3613464ebd5Sriastradh_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY, 3627117f1b4Smrg GLint width, GLint spanX, GLint spanY, 363af69d88dSmrg const GLubyte stencil[]) 3647117f1b4Smrg{ 365af69d88dSmrg GLubyte *zoomedVals; 3667117f1b4Smrg GLint x0, x1, y0, y1, y; 3677117f1b4Smrg GLint i, zoomedWidth; 3687117f1b4Smrg 3697117f1b4Smrg if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width, 3707117f1b4Smrg &x0, &x1, &y0, &y1)) { 3717117f1b4Smrg return; /* totally clipped */ 3727117f1b4Smrg } 3737117f1b4Smrg 3747117f1b4Smrg zoomedWidth = x1 - x0; 37501e04c3fSmrg assert(zoomedWidth > 0); 37601e04c3fSmrg assert(zoomedWidth <= SWRAST_MAX_WIDTH); 377af69d88dSmrg 378af69d88dSmrg zoomedVals = malloc(zoomedWidth * sizeof(GLubyte)); 379af69d88dSmrg if (!zoomedVals) 380af69d88dSmrg return; 3817117f1b4Smrg 3827117f1b4Smrg /* zoom the span horizontally */ 3837117f1b4Smrg for (i = 0; i < zoomedWidth; i++) { 3847117f1b4Smrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; 38501e04c3fSmrg assert(j >= 0); 38601e04c3fSmrg assert(j < width); 3877117f1b4Smrg zoomedVals[i] = stencil[j]; 3887117f1b4Smrg } 3897117f1b4Smrg 3907117f1b4Smrg /* write the zoomed spans */ 3917117f1b4Smrg for (y = y0; y < y1; y++) { 3927117f1b4Smrg _swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals); 3937117f1b4Smrg } 394af69d88dSmrg 395af69d88dSmrg free(zoomedVals); 3967117f1b4Smrg} 3977117f1b4Smrg 3987117f1b4Smrg 3997117f1b4Smrg/** 400af69d88dSmrg * Zoom/write 32-bit Z values. 4017117f1b4Smrg * No per-fragment operations are applied. 4027117f1b4Smrg */ 4037117f1b4Smrgvoid 4043464ebd5Sriastradh_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY, 4057117f1b4Smrg GLint width, GLint spanX, GLint spanY, 406af69d88dSmrg const GLuint *zVals) 4077117f1b4Smrg{ 408af69d88dSmrg struct gl_renderbuffer *rb = 409af69d88dSmrg ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 410af69d88dSmrg GLuint *zoomedVals; 4117117f1b4Smrg GLint x0, x1, y0, y1, y; 4127117f1b4Smrg GLint i, zoomedWidth; 4137117f1b4Smrg 4147117f1b4Smrg if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width, 4157117f1b4Smrg &x0, &x1, &y0, &y1)) { 4167117f1b4Smrg return; /* totally clipped */ 4177117f1b4Smrg } 4187117f1b4Smrg 4197117f1b4Smrg zoomedWidth = x1 - x0; 42001e04c3fSmrg assert(zoomedWidth > 0); 42101e04c3fSmrg assert(zoomedWidth <= SWRAST_MAX_WIDTH); 422af69d88dSmrg 423af69d88dSmrg zoomedVals = malloc(zoomedWidth * sizeof(GLuint)); 424af69d88dSmrg if (!zoomedVals) 425af69d88dSmrg return; 4267117f1b4Smrg 4277117f1b4Smrg /* zoom the span horizontally */ 428af69d88dSmrg for (i = 0; i < zoomedWidth; i++) { 429af69d88dSmrg GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; 43001e04c3fSmrg assert(j >= 0); 43101e04c3fSmrg assert(j < width); 432af69d88dSmrg zoomedVals[i] = zVals[j]; 4337117f1b4Smrg } 4347117f1b4Smrg 4357117f1b4Smrg /* write the zoomed spans */ 4367117f1b4Smrg for (y = y0; y < y1; y++) { 437af69d88dSmrg GLubyte *dst = _swrast_pixel_address(rb, x0, y); 438af69d88dSmrg _mesa_pack_uint_z_row(rb->Format, zoomedWidth, zoomedVals, dst); 4397117f1b4Smrg } 440af69d88dSmrg 441af69d88dSmrg free(zoomedVals); 4427117f1b4Smrg} 443