/**
* @file
- * Blitter utility to facilitate acceleration of the clear, surface_copy,
- * and surface_fill functions.
+ * Blitter utility to facilitate acceleration of the clear, resource_copy_region,
+ * and resource_fill_region functions.
*
* @author Marek Olšák
*/
#include "util/u_draw_quad.h"
#include "util/u_pack_color.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
+#include "util/u_surface.h"
#include "util/u_texture.h"
#define INVALID_PTR ((void*)~0)
struct blitter_context blitter;
struct pipe_context *pipe; /**< pipe context */
- struct pipe_buffer *vbuf; /**< quad */
+ struct pipe_resource *vbuf; /**< quad */
float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
/* Rasterizer state. */
void *rs_state;
+
+ struct pipe_sampler_view *sampler_view;
+
+ /* Viewport state. */
+ struct pipe_viewport_state viewport;
+
+ /* Clip state. */
+ struct pipe_clip_state clip;
};
struct blitter_context *util_blitter_create(struct pipe_context *pipe)
{
struct blitter_context_priv *ctx;
- struct pipe_blend_state blend = { 0 };
- struct pipe_depth_stencil_alpha_state dsa = { { 0 } };
- struct pipe_rasterizer_state rs_state = { 0 };
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_rasterizer_state rs_state;
struct pipe_sampler_state *sampler_state;
struct pipe_vertex_element velem[2];
unsigned i;
ctx->blitter.saved_vs = INVALID_PTR;
ctx->blitter.saved_velem_state = INVALID_PTR;
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
- ctx->blitter.saved_num_textures = ~0;
+ ctx->blitter.saved_num_sampler_views = ~0;
ctx->blitter.saved_num_sampler_states = ~0;
+ ctx->blitter.saved_num_vertex_buffers = ~0;
/* blend state objects */
+ memset(&blend, 0, sizeof(blend));
ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
blend.rt[0].colormask = PIPE_MASK_RGBA;
ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
/* depth stencil alpha state objects */
+ memset(&dsa, 0, sizeof(dsa));
ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state->normalized_coords = TRUE;
/* The sampler state objects which sample from a specified mipmap level
* are created on-demand. */
memset(&rs_state, 0, sizeof(rs_state));
rs_state.front_winding = PIPE_WINDING_CW;
rs_state.cull_mode = PIPE_WINDING_NONE;
- rs_state.bypass_vs_clip_and_viewport = 1;
rs_state.gl_rasterization_rules = 1;
rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
/* create the vertex buffer */
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
- 32,
- PIPE_BUFFER_USAGE_VERTEX,
+ PIPE_BIND_VERTEX_BUFFER,
sizeof(ctx->vertices));
return &ctx->blitter;
if (ctx->sampler_state[i])
pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
- pipe_buffer_reference(&ctx->vbuf, NULL);
+ if (ctx->sampler_view) {
+ pipe_sampler_view_reference(&ctx->sampler_view, NULL);
+ }
+
+ pipe_resource_reference(&ctx->vbuf, NULL);
FREE(ctx);
}
pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref);
+ pipe->set_viewport_state(pipe, &ctx->blitter.saved_viewport);
+ pipe->set_clip_state(pipe, &ctx->blitter.saved_clip);
+
/* restore the state objects which are required to be saved before copy/fill
*/
if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
ctx->blitter.saved_num_sampler_states = ~0;
}
- if (ctx->blitter.saved_num_textures != ~0) {
- pipe->set_fragment_sampler_textures(pipe,
- ctx->blitter.saved_num_textures,
- ctx->blitter.saved_textures);
- ctx->blitter.saved_num_textures = ~0;
+ if (ctx->blitter.saved_num_sampler_views != ~0) {
+ pipe->set_fragment_sampler_views(pipe,
+ ctx->blitter.saved_num_sampler_views,
+ ctx->blitter.saved_sampler_views);
+ ctx->blitter.saved_num_sampler_views = ~0;
+ }
+
+ if (ctx->blitter.saved_num_vertex_buffers != ~0) {
+ pipe->set_vertex_buffers(pipe,
+ ctx->blitter.saved_num_vertex_buffers,
+ ctx->blitter.saved_vertex_buffers);
+ ctx->blitter.saved_num_vertex_buffers = ~0;
}
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
+ unsigned width, unsigned height,
float depth)
{
int i;
/* set vertex positions */
- ctx->vertices[0][0][0] = x1; /*v0.x*/
- ctx->vertices[0][0][1] = y1; /*v0.y*/
+ ctx->vertices[0][0][0] = (float)x1 / width * 2.0f - 1.0f; /*v0.x*/
+ ctx->vertices[0][0][1] = (float)y1 / height * 2.0f - 1.0f; /*v0.y*/
- ctx->vertices[1][0][0] = x2; /*v1.x*/
- ctx->vertices[1][0][1] = y1; /*v1.y*/
+ ctx->vertices[1][0][0] = (float)x2 / width * 2.0f - 1.0f; /*v1.x*/
+ ctx->vertices[1][0][1] = (float)y1 / height * 2.0f - 1.0f; /*v1.y*/
- ctx->vertices[2][0][0] = x2; /*v2.x*/
- ctx->vertices[2][0][1] = y2; /*v2.y*/
+ ctx->vertices[2][0][0] = (float)x2 / width * 2.0f - 1.0f; /*v2.x*/
+ ctx->vertices[2][0][1] = (float)y2 / height * 2.0f - 1.0f; /*v2.y*/
- ctx->vertices[3][0][0] = x1; /*v3.x*/
- ctx->vertices[3][0][1] = y2; /*v3.y*/
+ ctx->vertices[3][0][0] = (float)x1 / width * 2.0f - 1.0f; /*v3.x*/
+ ctx->vertices[3][0][1] = (float)y2 / height * 2.0f - 1.0f; /*v3.y*/
for (i = 0; i < 4; i++)
ctx->vertices[i][0][2] = depth; /*z*/
+
+ /* viewport */
+ ctx->viewport.scale[0] = 0.5f * width;
+ ctx->viewport.scale[1] = 0.5f * height;
+ ctx->viewport.scale[2] = 1.0f;
+ ctx->viewport.scale[3] = 1.0f;
+ ctx->viewport.translate[0] = 0.5f * width;
+ ctx->viewport.translate[1] = 0.5f * height;
+ ctx->viewport.translate[2] = 0.0f;
+ ctx->viewport.translate[3] = 0.0f;
+ ctx->pipe->set_viewport_state(ctx->pipe, &ctx->viewport);
+
+ /* clip */
+ ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip);
}
static void blitter_set_clear_color(struct blitter_context_priv *ctx,
struct pipe_context *pipe = ctx->pipe;
/* write vertices and draw them */
- pipe_buffer_write(pipe->screen, ctx->vbuf,
+ pipe_buffer_write(pipe, ctx->vbuf,
0, sizeof(ctx->vertices), ctx->vertices);
util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
pipe->bind_vs_state(pipe, ctx->vs_col);
blitter_set_clear_color(ctx, rgba);
- blitter_set_rectangle(ctx, 0, 0, width, height, depth);
+ blitter_set_rectangle(ctx, 0, 0, width, height, width, height, depth);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_framebuffer_state fb_state;
+ struct pipe_sampler_view viewTempl, *view;
assert(blitter->saved_fb_state.nr_cbufs != ~0);
- assert(blitter->saved_num_textures != ~0);
+ assert(blitter->saved_num_sampler_views != ~0);
assert(blitter->saved_num_sampler_states != ~0);
assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES);
fb_state.zsbuf = 0;
}
+ u_sampler_view_default_template(&viewTempl,
+ src->texture,
+ src->texture->format);
+ view = pipe->create_sampler_view(pipe,
+ src->texture,
+ &viewTempl);
+
+ if (ctx->sampler_view) {
+ pipe_sampler_view_reference(&ctx->sampler_view, NULL);
+ }
+ ctx->sampler_view = view;
+
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs_tex);
pipe->bind_fragment_sampler_states(pipe, 1,
blitter_get_sampler_state(ctx, src->level));
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
- pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
+ pipe->set_fragment_sampler_views(pipe, 1, &view);
pipe->set_framebuffer_state(pipe, &fb_state);
/* set texture coordinates */
assert(0);
}
- blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
+ blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, dst->width, dst->height, 0);
blitter_draw_quad(ctx);
}
-static void util_blitter_overlap_copy(struct blitter_context *blitter,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- struct pipe_surface *src,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
-{
- struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
-
- struct pipe_texture texTemp;
- struct pipe_texture *texture;
- struct pipe_surface *tex_surf;
-
- /* check whether the states are properly saved */
- blitter_check_saved_CSOs(ctx);
-
- memset(&texTemp, 0, sizeof(texTemp));
- texTemp.target = PIPE_TEXTURE_2D;
- texTemp.format = dst->texture->format; /* XXX verify supported by driver! */
- texTemp.last_level = 0;
- texTemp.width0 = width;
- texTemp.height0 = height;
- texTemp.depth0 = 1;
-
- texture = screen->texture_create(screen, &texTemp);
- if (!texture)
- return;
-
- tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* blit from the src to the temp */
- util_blitter_do_copy(blitter, tex_surf, 0, 0,
- src, srcx, srcy,
- width, height,
- FALSE);
- util_blitter_do_copy(blitter, dst, dstx, dsty,
- tex_surf, 0, 0,
- width, height,
- FALSE);
- pipe_surface_reference(&tex_surf, NULL);
- pipe_texture_reference(&texture, NULL);
- blitter_restore_CSOs(ctx);
-}
void util_blitter_copy(struct blitter_context *blitter,
struct pipe_surface *dst,
return;
if (dst->texture == src->texture) {
- if (is_overlap(srcx, srcx + width, srcy, srcy + height,
- dstx, dstx + width, dsty, dsty + height)) {
- util_blitter_overlap_copy(blitter, dst, dstx, dsty, src, srcx, srcy,
- width, height);
- return;
+ assert(!is_overlap(srcx, srcx + width, srcy, srcy + height,
+ dstx, dstx + width, dsty, dsty + height))
}
}
-
+
is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;
- dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
- PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ dst_tex_usage = is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL :
+ PIPE_BIND_RENDER_TARGET;
/* check if we can sample from and render to the surfaces */
/* (assuming copying a stencil buffer is not possible) */
if ((!ignore_stencil && is_stencil) ||
!screen->is_format_supported(screen, dst->format, dst->texture->target,
- dst_tex_usage, 0) ||
+ dst->texture->nr_samples, dst_tex_usage, 0) ||
!screen->is_format_supported(screen, src->format, src->texture->target,
- PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
- util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
- width, height);
+ src->texture->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
+ struct pipe_subresource subdst, subsrc;
+ subdst.face = dst->face;
+ subdst.level = dst->level;
+ subsrc.face = src->face;
+ subsrc.level = src->level;
+ util_resource_copy_region(pipe, dst, subdst, dstx, dsty, dst->zslice,
+ src, subsrc, srcx, srcy, src->zslice,
+ width, height);
return;
}
/* check if we can render to the surface */
if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
!screen->is_format_supported(screen, dst->format, dst->texture->target,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
- util_surface_fill(pipe, dst, dstx, dsty, width, height, value);
+ dst->texture->nr_samples,
+ PIPE_BIND_RENDER_TARGET, 0)) {
+ struct pipe_subresource subdst;
+ subdst.face = dst->face;
+ subdst.level = dst->level;
+ util_resource_fill_region(pipe, dst->texture, subdst, dstx, dsty,
+ dst->zslice, width, height, value);
return;
}
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_clear_color(ctx, rgba);
- blitter_set_rectangle(ctx, 0, 0, width, height, 0);
+ blitter_set_rectangle(ctx, 0, 0, width, height, dst->width, dst->height, 0);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}