diff options
Diffstat (limited to 'src/mesa/state_tracker/st_cb_drawpixels.c')
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 258 |
1 files changed, 133 insertions, 125 deletions
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 5fcfa86904..e059002f15 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -59,7 +59,6 @@ #include "util/u_draw_quad.h" #include "util/u_format.h" #include "util/u_math.h" -#include "util/u_rect.h" #include "shader/prog_instruction.h" #include "cso_cache/cso_context.h" @@ -293,10 +292,55 @@ base_format(GLenum format) /** + * Create a temporary texture to hold an image of the given size. + * If width, height are not POT and the driver only handles POT textures, + * allocate the next larger size of texture that is POT. + */ +static struct pipe_resource * +alloc_texture(struct st_context *st, GLsizei width, GLsizei height, + enum pipe_format texFormat) +{ + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_resource *pt; + int ptw, pth; + + ptw = width; + pth = height; + + /* Need to use POT texture? */ + 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_BIND_SAMPLER_VIEW); + + return pt; +} + + +/** * Make texture containing an image for glDrawPixels image. * If 'pixels' is NULL, leave the texture image data undefined. */ -static struct pipe_texture * +static struct pipe_resource * make_texture(struct st_context *st, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, @@ -304,13 +348,11 @@ make_texture(struct st_context *st, { GLcontext *ctx = st->ctx; struct pipe_context *pipe = st->pipe; - struct pipe_screen *screen = pipe->screen; gl_format mformat; - struct pipe_texture *pt; + struct pipe_resource *pt; enum pipe_format pipeFormat; GLuint cpp; GLenum baseFormat; - int ptw, pth; baseFormat = base_format(format); @@ -325,29 +367,8 @@ make_texture(struct st_context *st, if (!pixels) return NULL; - /* 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); + /* alloc temporary texture */ + pt = alloc_texture(st, width, height, pipeFormat); if (!pt) { _mesa_unmap_pbo_source(ctx, unpack); return NULL; @@ -368,7 +389,7 @@ make_texture(struct st_context *st, width, height); /* map texture transfer */ - dest = screen->transfer_map(screen, transfer); + dest = pipe_transfer_map(pipe, transfer); /* Put image into texture transfer. @@ -388,8 +409,8 @@ make_texture(struct st_context *st, unpack); /* unmap */ - screen->transfer_unmap(screen, transfer); - screen->tex_transfer_destroy(transfer); + pipe_transfer_unmap(pipe, transfer); + pipe->transfer_destroy(pipe, transfer); assert(success); @@ -481,10 +502,11 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z, } { - struct pipe_buffer *buf; + struct pipe_resource *buf; /* allocate/load buffer object with vertex data */ - buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, + buf = pipe_buffer_create(pipe->screen, + PIPE_BIND_VERTEX_BUFFER, sizeof(verts)); st_no_flush_pipe_buffer_write(st, buf, 0, sizeof(verts), verts); @@ -492,7 +514,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z, PIPE_PRIM_QUADS, 4, /* verts */ 3); /* attribs/vert */ - pipe_buffer_reference(&buf, NULL); + pipe_resource_reference(&buf, NULL); } } @@ -502,7 +524,7 @@ static void draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, GLfloat zoomX, GLfloat zoomY, - struct pipe_texture *pt, + struct pipe_sampler_view *sv, void *driver_vp, void *driver_fp, const GLfloat *color, @@ -525,9 +547,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_viewport(cso); cso_save_samplers(cso); - cso_save_sampler_textures(cso); + cso_save_fragment_sampler_views(cso); cso_save_fragment_shader(cso); cso_save_vertex_shader(cso); + cso_save_vertex_elements(cso); /* rasterizer state: just scissor */ { @@ -580,15 +603,17 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_set_viewport(cso, &vp); } + cso_set_vertex_elements(cso, 3, st->velems_util_draw); + /* texture state: */ if (st->pixel_xfer.pixelmap_enabled) { - struct pipe_texture *textures[2]; - textures[0] = pt; - textures[1] = st->pixel_xfer.pixelmap_texture; - pipe->set_fragment_sampler_textures(pipe, 2, textures); + struct pipe_sampler_view *sampler_views[2]; + sampler_views[0] = sv; + sampler_views[1] = st->pixel_xfer.pixelmap_sampler_view; + cso_set_fragment_sampler_views(cso, 2, sampler_views); } else { - pipe->set_fragment_sampler_textures(pipe, 1, &pt); + cso_set_fragment_sampler_views(cso, 1, &sv); } /* Compute Gallium window coords (y=0=top) with pixel zoom. @@ -609,16 +634,17 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, z = z * 2.0 - 1.0; draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, - (GLfloat) width / pt->width0, - (GLfloat) height / pt->height0); + (GLfloat) width / sv->texture->width0, + (GLfloat) height / sv->texture->height0); /* restore state */ cso_restore_rasterizer(cso); cso_restore_viewport(cso); cso_restore_samplers(cso); - cso_restore_sampler_textures(cso); + cso_restore_fragment_sampler_views(cso); cso_restore_fragment_shader(cso); cso_restore_vertex_shader(cso); + cso_restore_vertex_elements(cso); } @@ -630,7 +656,6 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, { 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; @@ -664,7 +689,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, usage, x, y, width, height); - stmap = screen->transfer_map(screen, pt); + stmap = pipe_transfer_map(pipe, pt); pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels); assert(pixels); @@ -709,15 +734,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } /* now pack the stencil (and Z) values in the dest format */ - switch (pt->texture->format) { - case PIPE_FORMAT_S8_UNORM: + switch (pt->resource->format) { + case PIPE_FORMAT_S8_USCALED: { ubyte *dest = stmap + spanY * pt->stride + spanX; assert(usage == PIPE_TRANSFER_WRITE); memcpy(dest, sValues, spanWidth); } break; - case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; @@ -735,7 +760,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } } break; - case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: if (format == GL_DEPTH_STENCIL) { uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; @@ -764,8 +789,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, _mesa_unmap_pbo_source(ctx, &clippedUnpack); /* unmap the stencil buffer */ - screen->transfer_unmap(screen, pt); - screen->tex_transfer_destroy(pt); + pipe_transfer_unmap(pipe, pt); + pipe->transfer_destroy(pipe, pt); } @@ -806,16 +831,21 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* draw with textured quad */ { - struct pipe_texture *pt + struct pipe_resource *pt = 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, - pt, - driver_vp, - driver_fp, - color, GL_FALSE); - pipe_texture_reference(&pt, NULL); + struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt); + + if (sv) { + draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], + width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, + sv, + driver_vp, + driver_fp, + color, GL_FALSE); + pipe_sampler_view_reference(&sv, NULL); + } + pipe_resource_reference(&pt, NULL); } } } @@ -828,7 +858,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint dstx, GLint dsty) { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); - struct pipe_screen *screen = ctx->st->pipe->screen; + struct pipe_context *pipe = st_context(ctx)->pipe; enum pipe_transfer_usage usage; struct pipe_transfer *ptDraw; ubyte *drawMap; @@ -860,11 +890,11 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, usage, dstx, dsty, width, height); - assert(util_format_get_blockwidth(ptDraw->texture->format) == 1); - assert(util_format_get_blockheight(ptDraw->texture->format) == 1); + assert(util_format_get_blockwidth(ptDraw->resource->format) == 1); + assert(util_format_get_blockheight(ptDraw->resource->format) == 1); /* map the stencil buffer */ - drawMap = screen->transfer_map(screen, ptDraw); + drawMap = pipe_transfer_map(pipe, ptDraw); /* draw */ /* XXX PixelZoom not handled yet */ @@ -882,8 +912,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, dst = drawMap + y * ptDraw->stride; src = buffer + i * width; - switch (ptDraw->texture->format) { - case PIPE_FORMAT_Z24S8_UNORM: + switch (ptDraw->resource->format) { + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: { uint *dst4 = (uint *) dst; int j; @@ -894,7 +924,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } } break; - case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: { uint *dst4 = (uint *) dst; int j; @@ -905,7 +935,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } } break; - case PIPE_FORMAT_S8_UNORM: + case PIPE_FORMAT_S8_USCALED: assert(usage == PIPE_TRANSFER_WRITE); memcpy(dst, src, width); break; @@ -917,8 +947,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, free(buffer); /* unmap the stencil buffer */ - screen->transfer_unmap(screen, ptDraw); - screen->tex_transfer_destroy(ptDraw); + pipe_transfer_unmap(pipe, ptDraw); + pipe->transfer_destroy(pipe, ptDraw); } @@ -932,10 +962,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *rbRead; void *driver_vp, *driver_fp; - struct pipe_texture *pt; + struct pipe_resource *pt; + struct pipe_sampler_view *sv; GLfloat *color; enum pipe_format srcFormat, texFormat; - int ptw, pth; GLboolean invertTex = GL_FALSE; GLint readX, readY, readW, readH; struct gl_pixelstore_attrib pack = ctx->DefaultPacking; @@ -967,7 +997,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, srcFormat = rbRead->texture->format; if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_SAMPLER, 0)) { + PIPE_BIND_SAMPLER_VIEW, 0)) { texFormat = srcFormat; } else { @@ -975,13 +1005,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (type == GL_DEPTH) { texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL); + PIPE_BIND_DEPTH_STENCIL); assert(texFormat != PIPE_FORMAT_NONE); } else { /* default color format */ texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_SAMPLER); + PIPE_BIND_SAMPLER_VIEW); assert(texFormat != PIPE_FORMAT_NONE); } } @@ -1006,60 +1036,37 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, readW = MAX2(0, readW); readH = MAX2(0, readH); - /* 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); + /* alloc temporary texture */ + pt = alloc_texture(st, width, height, texFormat); if (!pt) return; + sv = st_create_texture_sampler_view(st->pipe, pt); + if (!sv) { + pipe_resource_reference(&pt, NULL); + return; + } + /* Make temporary texture which is a copy of the src region. */ if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ struct pipe_surface *psRead = screen->get_tex_surface(screen, rbRead->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BIND_BLIT_SOURCE); struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE ); - if (pipe->surface_copy) { - pipe->surface_copy(pipe, - psTex, /* dest surf */ - pack.SkipPixels, pack.SkipRows, /* dest pos */ - psRead, /* src surf */ - readX, readY, readW, readH); /* src region */ - } else { - util_surface_copy(pipe, FALSE, - psTex, - pack.SkipPixels, pack.SkipRows, - psRead, - readX, readY, readW, readH); - } + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_BLIT_DESTINATION); + pipe->surface_copy(pipe, + psTex, /* dest surf */ + pack.SkipPixels, pack.SkipRows, /* dest pos */ + psRead, /* src surf */ + readX, readY, readW, readH); /* src region */ if (0) { /* debug */ - debug_dump_surface("copypixsrcsurf", psRead); - debug_dump_surface("copypixtemptex", psTex); + debug_dump_surface(pipe, "copypixsrcsurf", psRead); + debug_dump_surface(pipe, "copypixtemptex", psTex); } pipe_surface_reference(&psRead, NULL); @@ -1089,22 +1096,22 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (type == GL_COLOR) { /* alternate path using get/put_tile() */ GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(ptRead, readX, readY, readW, readH, buf); - pipe_put_tile_rgba(ptTex, pack.SkipPixels, pack.SkipRows, + pipe_get_tile_rgba(pipe, ptRead, readX, readY, readW, readH, buf); + pipe_put_tile_rgba(pipe, ptTex, pack.SkipPixels, pack.SkipRows, readW, readH, buf); free(buf); } else { /* GL_DEPTH */ GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); - pipe_get_tile_z(ptRead, readX, readY, readW, readH, buf); - pipe_put_tile_z(ptTex, pack.SkipPixels, pack.SkipRows, - readW, readH, buf); + pipe_get_tile_z(pipe, ptRead, readX, readY, readW, readH, buf); + pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows, + readW, readH, buf); free(buf); } - screen->tex_transfer_destroy(ptRead); - screen->tex_transfer_destroy(ptTex); + pipe->transfer_destroy(pipe, ptRead); + pipe->transfer_destroy(pipe, ptTex); } /* OK, the texture 'pt' contains the src image/pixels. Now draw a @@ -1112,12 +1119,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, + sv, driver_vp, driver_fp, color, invertTex); - pipe_texture_reference(&pt, NULL); + pipe_resource_reference(&pt, NULL); + pipe_sampler_view_reference(&sv, NULL); } |