void renderer_copy_texture(struct renderer *ctx, struct pipe_texture *src, VGfloat sx1, VGfloat sy1, VGfloat sx2, VGfloat sy2, struct pipe_texture *dst, VGfloat dx1, VGfloat dy1, VGfloat dx2, VGfloat dy2) { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_buffer *buf; struct pipe_surface *dst_surf = screen->get_tex_surface( screen, dst, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); struct pipe_framebuffer_state fb; float s0, t0, s1, t1; assert(src->width0 != 0); assert(src->height0 != 0); assert(dst->width0 != 0); assert(dst->height0 != 0); #if 0 debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n", sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); #endif #if 1 s0 = sx1 / src->width0; s1 = sx2 / src->width0; t0 = sy1 / src->height0; t1 = sy2 / src->height0; #else s0 = 0; s1 = 1; t0 = 0; t1 = 1; #endif assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); /* save state (restored below) */ cso_save_blend(ctx->cso); cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); cso_save_viewport(ctx->cso); /* set misc state we care about */ { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(ctx->cso, &blend); } /* sampler */ { struct pipe_sampler_state sampler; memset(&sampler, 0, sizeof(sampler)); sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.normalized_coords = 1; cso_single_sampler(ctx->cso, 0, &sampler); cso_single_sampler_done(ctx->cso); } vg_set_viewport(ctx->owner, VEGA_Y0_TOP); /* texture */ cso_set_sampler_textures(ctx->cso, 1, &src); /* shaders */ cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner)); cso_set_fragment_shader_handle(ctx->cso, ctx->fs); /* drawing dest */ memset(&fb, 0, sizeof(fb)); fb.width = dst_surf->width; fb.height = dst_surf->height; fb.nr_cbufs = 1; fb.cbufs[0] = dst_surf; { VGint i; for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i) fb.cbufs[i] = 0; } cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ buf = setup_vertex_data_tex(ctx, dx1, dy1, dx2, dy2, s0, t0, s1, t1, 0.0f); if (buf) { util_draw_vertex_buffer(ctx->pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 2); /* attribs/vert */ pipe_buffer_reference( &buf, NULL ); } /* restore state we changed */ cso_restore_blend(ctx->cso); cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_vertex_shader(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_viewport(ctx->cso); pipe_surface_reference(&dst_surf, NULL); }
void renderer_copy_surface(struct renderer *ctx, struct pipe_surface *src, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, float z, unsigned filter) { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_buffer *buf; struct pipe_texture texTemp, *tex; struct pipe_surface *texSurf; struct pipe_framebuffer_state fb; struct st_framebuffer *stfb = ctx->owner->draw_buffer; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); if (srcLeft != srcX0) { /* left-right flip */ int tmp = dstX0; dstX0 = dstX1; dstX1 = tmp; } if (srcTop != srcY0) { /* up-down flip */ int tmp = dstY0; dstY0 = dstY1; dstY1 = tmp; } assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, 0)); assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, 0)); assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); /* * XXX for now we're always creating a temporary texture. * Strictly speaking that's not always needed. */ /* create temp texture */ memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; texTemp.format = src->format; texTemp.last_level = 0; texTemp.width0 = srcW; texTemp.height0 = srcH; texTemp.depth0 = 1; tex = screen->texture_create(screen, &texTemp); if (!tex) return; texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); /* load temp texture */ if (pipe->surface_copy) { pipe->surface_copy(pipe, texSurf, 0, 0, /* dest */ src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ } else { util_surface_copy(pipe, FALSE, texSurf, 0, 0, /* dest */ src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ } /* free the surface, update the texture if necessary.*/ screen->tex_surface_destroy(texSurf); /* save state (restored below) */ cso_save_blend(ctx->cso); cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); cso_save_viewport(ctx->cso); /* set misc state we care about */ { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(ctx->cso, &blend); } vg_set_viewport(ctx->owner, VEGA_Y0_TOP); /* sampler */ { struct pipe_sampler_state sampler; memset(&sampler, 0, sizeof(sampler)); sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.normalized_coords = 1; cso_single_sampler(ctx->cso, 0, &sampler); cso_single_sampler_done(ctx->cso); } /* texture */ cso_set_sampler_textures(ctx->cso, 1, &tex); /* shaders */ cso_set_fragment_shader_handle(ctx->cso, ctx->fs); cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner)); /* drawing dest */ if (stfb->strb->surface != dst) { memset(&fb, 0, sizeof(fb)); fb.width = dst->width; fb.height = dst->height; fb.nr_cbufs = 1; fb.cbufs[0] = dst; fb.zsbuf = stfb->dsrb->surface; cso_set_framebuffer(ctx->cso, &fb); } /* draw quad */ buf = setup_vertex_data(ctx, (float) dstX0, (float) dstY0, (float) dstX1, (float) dstY1, z); if (buf) { util_draw_vertex_buffer(ctx->pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 2); /* attribs/vert */ pipe_buffer_reference( &buf, NULL ); } /* restore state we changed */ cso_restore_blend(ctx->cso); cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); cso_restore_viewport(ctx->cso); pipe_texture_reference(&tex, NULL); }
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 st_vertex_program *stvp, struct st_fragment_program *stfp, 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; GLfloat x0, y0, x1, y1; GLsizei maxSize; /* limit checks */ /* 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); assert(width <= maxSize); assert(height <= maxSize); cso_save_rasterizer(cso); cso_save_viewport(cso); cso_save_samplers(cso); cso_save_sampler_textures(cso); cso_save_fragment_shader(cso); cso_save_vertex_shader(cso); /* rasterizer state: just scissor */ { struct pipe_rasterizer_state rasterizer; memset(&rasterizer, 0, sizeof(rasterizer)); rasterizer.gl_rasterization_rules = 1; rasterizer.scissor = ctx->Scissor.Enabled; cso_set_rasterizer(cso, &rasterizer); } /* fragment shader state: TEX lookup program */ cso_set_fragment_shader_handle(cso, stfp->driver_shader); /* vertex shader state: position + texcoord pass-through */ cso_set_vertex_shader_handle(cso, stvp->driver_shader); /* texture sampling state: */ { struct pipe_sampler_state sampler; memset(&sampler, 0, sizeof(sampler)); sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; sampler.wrap_r = PIPE_TEX_WRAP_CLAMP; sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.normalized_coords = 1; cso_single_sampler(cso, 0, &sampler); if (st->pixel_xfer.pixelmap_enabled) { cso_single_sampler(cso, 1, &sampler); } cso_single_sampler_done(cso); } /* viewport state: viewport matching window dims */ { const float width = (float) ctx->DrawBuffer->Width; const float height = (float) ctx->DrawBuffer->Height; struct pipe_viewport_state vp; vp.scale[0] = 0.5f * width; vp.scale[1] = -0.5f * height; vp.scale[2] = 1.0f; vp.scale[3] = 1.0f; vp.translate[0] = 0.5f * width; vp.translate[1] = 0.5f * height; vp.translate[2] = 0.0f; vp.translate[3] = 0.0f; cso_set_viewport(cso, &vp); } /* 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_sampler_textures(pipe, 2, textures); } else { pipe->set_sampler_textures(pipe, 1, &pt); } /* Compute window coords (y=0=bottom) with pixel zoom. * Recall that these coords are transformed by the current * vertex shader and viewport transformation. */ x0 = (GLfloat) x; x1 = x + width * ctx->Pixel.ZoomX; y0 = (GLfloat) y; y1 = y + height * ctx->Pixel.ZoomY; draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex); /* restore state */ cso_restore_rasterizer(cso); cso_restore_viewport(cso); cso_restore_samplers(cso); cso_restore_sampler_textures(cso); cso_restore_fragment_shader(cso); cso_restore_vertex_shader(cso); }