#include "vg_context.h"
#include "image.h"
+#include "api.h"
+#include "handle.h"
#include "renderer.h"
#include "shaders_cache.h"
-#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
-#include "pipe/p_shader_tokens.h"
#include "util/u_format.h"
-#include "util/u_memory.h"
-
+#include "util/u_sampler.h"
+#include "util/u_string.h"
#include "asm_filters.h"
const void *const_buffer;
VGint const_buffer_len;
VGTilingMode tiling_mode;
- struct pipe_texture *extra_texture;
+ struct pipe_sampler_view *extra_texture_view;
};
-static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
+static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx,
const VGuint *color_data,
const VGint color_data_len)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_texture *tex = 0;
- struct pipe_texture templ;
+ struct pipe_resource *tex = 0;
+ struct pipe_resource templ;
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_1D;
- templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
templ.last_level = 0;
templ.width0 = color_data_len;
templ.height0 = 1;
templ.depth0 = 1;
- templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
+ templ.array_size = 1;
+ templ.bind = PIPE_BIND_SAMPLER_VIEW;
- tex = screen->texture_create(screen, &templ);
+ tex = screen->resource_create(screen, &templ);
{ /* upload color_data */
- struct pipe_transfer *transfer =
- screen->get_tex_transfer(screen, tex,
- 0, 0, 0,
- PIPE_TRANSFER_READ_WRITE ,
- 0, 0, tex->width0, tex->height0);
- void *map = screen->transfer_map(screen, transfer);
+ struct pipe_transfer *transfer;
+ void *map =
+ pipe_transfer_map(pipe, tex,
+ 0, 0,
+ PIPE_TRANSFER_READ_WRITE ,
+ 0, 0, tex->width0, tex->height0,
+ &transfer);
memcpy(map, color_data, sizeof(VGint)*color_data_len);
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
}
return tex;
}
-static INLINE struct pipe_surface * setup_framebuffer(struct vg_image *dst)
+static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context *ctx,
+ const VGuint *color_data,
+ const VGint color_data_len)
{
- struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_framebuffer_state fb;
- struct pipe_surface *dst_surf = pipe->screen->get_tex_surface(
- pipe->screen, dst->texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst->x + dst_surf->width;
- fb.height = dst->y + 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_context, &fb);
-
- return dst_surf;
-}
-
-static void setup_viewport(struct vg_image *dst)
-{
- struct vg_context *ctx = vg_current_context();
- vg_set_viewport(ctx, VEGA_Y0_TOP);
-}
+ struct pipe_resource *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
-static void setup_blend()
-{
- struct vg_context *ctx = vg_current_context();
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- if (ctx->state.vg.filter_channel_mask & VG_RED)
- blend.colormask |= PIPE_MASK_R;
- if (ctx->state.vg.filter_channel_mask & VG_GREEN)
- blend.colormask |= PIPE_MASK_G;
- if (ctx->state.vg.filter_channel_mask & VG_BLUE)
- blend.colormask |= PIPE_MASK_B;
- if (ctx->state.vg.filter_channel_mask & VG_ALPHA)
- blend.colormask |= PIPE_MASK_A;
- blend.blend_enable = 1;
- cso_set_blend(ctx->cso_context, &blend);
-}
+ texture = create_texture_1d(ctx, color_data, color_data_len);
-static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
- VGint param_bytes)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_constant_buffer *cbuf = &ctx->filter.buffer;
-
- /* We always need to get a new buffer, to keep the drivers simple and
- * avoid gratuitous rendering synchronization. */
- pipe_buffer_reference(&cbuf->buffer, NULL);
+ if (!texture)
+ return NULL;
- cbuf->buffer = pipe_buffer_create(pipe->screen, 16,
- PIPE_BUFFER_USAGE_CONSTANT,
- param_bytes);
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_resource_reference(&texture, NULL);
- if (cbuf->buffer) {
- st_no_flush_pipe_buffer_write(ctx, cbuf->buffer,
- 0, param_bytes, buffer);
- }
-
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
-}
-
-static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
-{
- struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
- struct pipe_sampler_state sampler[3];
- int num_samplers = 0;
- int num_textures = 0;
-
- samplers[0] = NULL;
- samplers[1] = NULL;
- samplers[2] = NULL;
- samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[3] = NULL;
-
- memset(&sampler[0], 0, sizeof(struct pipe_sampler_state));
- sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
- sampler[0].mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
- sampler[0].normalized_coords = 1;
-
- switch(info->tiling_mode) {
- case VG_TILE_FILL:
- sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
- sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
- memcpy(sampler[0].border_color,
- ctx->state.vg.tile_fill_color,
- sizeof(VGfloat) * 4);
- break;
- case VG_TILE_PAD:
- sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- break;
- case VG_TILE_REPEAT:
- sampler[0].wrap_s = PIPE_TEX_WRAP_REPEAT;
- sampler[0].wrap_t = PIPE_TEX_WRAP_REPEAT;
- break;
- case VG_TILE_REFLECT:
- sampler[0].wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
- sampler[0].wrap_t = PIPE_TEX_WRAP_MIRROR_REPEAT;
- break;
- default:
- debug_assert(!"Unknown tiling mode");
- }
-
- samplers[0] = &sampler[0];
- textures[0] = info->src->texture;
- ++num_samplers;
- ++num_textures;
-
- if (info->extra_texture) {
- memcpy(&sampler[1], &sampler[0], sizeof(struct pipe_sampler_state));
- samplers[1] = &sampler[1];
- textures[1] = info->extra_texture;
- ++num_samplers;
- ++num_textures;
- }
-
-
- cso_set_samplers(ctx->cso_context, num_samplers, (const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, num_textures, textures);
+ return view;
}
static struct vg_shader * setup_color_matrix(struct vg_context *ctx, void *user_data)
struct vg_shader *shader =
shader_create_from_text(ctx->pipe, color_matrix_asm, 200,
PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
VGint num_consts = (VGint)(long)(user_data);
struct vg_shader *shader;
- snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
+ util_snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
shader = shader_create_from_text(ctx->pipe, buffer, 200,
PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
shader_create_from_text(ctx->pipe, lookup_asm,
200, PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
switch(channel) {
case VG_RED:
- snprintf(buffer, 1023, lookup_single_asm, "xxxx");
+ util_snprintf(buffer, 1023, lookup_single_asm, "xxxx");
break;
case VG_GREEN:
- snprintf(buffer, 1023, lookup_single_asm, "yyyy");
+ util_snprintf(buffer, 1023, lookup_single_asm, "yyyy");
break;
case VG_BLUE:
- snprintf(buffer, 1023, lookup_single_asm, "zzzz");
+ util_snprintf(buffer, 1023, lookup_single_asm, "zzzz");
break;
case VG_ALPHA:
- snprintf(buffer, 1023, lookup_single_asm, "wwww");
+ util_snprintf(buffer, 1023, lookup_single_asm, "wwww");
break;
default:
debug_assert(!"Unknown color channel");
shader = shader_create_from_text(ctx->pipe, buffer, 200,
PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
static void execute_filter(struct vg_context *ctx,
struct filter_info *info)
{
- struct pipe_surface *dst_surf;
struct vg_shader *shader;
+ const struct pipe_sampler_state *samplers[2];
+ struct pipe_sampler_view *views[2];
+ struct pipe_sampler_state sampler;
+ uint tex_wrap;
+
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.normalized_coords = 1;
+
+ switch (info->tiling_mode) {
+ case VG_TILE_FILL:
+ tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
+ /* copy border color */
+ memcpy(sampler.border_color.f, ctx->state.vg.tile_fill_color,
+ sizeof(sampler.border_color));
+ break;
+ case VG_TILE_PAD:
+ tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;;
+ break;
+ case VG_TILE_REPEAT:
+ tex_wrap = PIPE_TEX_WRAP_REPEAT;;
+ break;
+ case VG_TILE_REFLECT:
+ tex_wrap = PIPE_TEX_WRAP_MIRROR_REPEAT;
+ break;
+ default:
+ debug_assert(!"Unknown tiling mode");
+ tex_wrap = 0;
+ break;
+ }
+
+ sampler.wrap_s = tex_wrap;
+ sampler.wrap_t = tex_wrap;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+
+ samplers[0] = samplers[1] = &sampler;
+ views[0] = info->src->sampler_view;
+ views[1] = info->extra_texture_view;
- cso_save_framebuffer(ctx->cso_context);
- cso_save_fragment_shader(ctx->cso_context);
- cso_save_viewport(ctx->cso_context);
- cso_save_blend(ctx->cso_context);
- cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(ctx->cso_context);
-
- dst_surf = setup_framebuffer(info->dst);
- setup_viewport(info->dst);
- setup_blend();
- setup_constant_buffer(ctx, info->const_buffer, info->const_buffer_len);
shader = info->setup_shader(ctx, info->user_data);
- setup_samplers(ctx, info);
-
- renderer_draw_texture(ctx->renderer,
- info->src->texture,
- info->dst->x, info->dst->y,
- info->dst->x + info->dst->width,
- info->dst->y + info->dst->height,
- info->dst->x, info->dst->y,
- info->dst->x + info->dst->width,
- info->dst->y + info->dst->height);
-
- cso_restore_framebuffer(ctx->cso_context);
- cso_restore_fragment_shader(ctx->cso_context);
- cso_restore_viewport(ctx->cso_context);
- cso_restore_blend(ctx->cso_context);
- cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
- vg_shader_destroy(ctx, shader);
+ if (renderer_filter_begin(ctx->renderer,
+ info->dst->sampler_view->texture, VG_TRUE,
+ ctx->state.vg.filter_channel_mask,
+ samplers, views, (info->extra_texture_view) ? 2 : 1,
+ shader->driver, info->const_buffer, info->const_buffer_len)) {
+ renderer_filter(ctx->renderer,
+ info->dst->x, info->dst->y, info->dst->width, info->dst->height,
+ info->src->x, info->src->y, info->src->width, info->src->height);
+ renderer_filter_end(ctx->renderer);
+ }
- pipe_surface_reference(&dst_surf, NULL);
+ vg_shader_destroy(ctx, shader);
}
-void vgColorMatrix(VGImage dst, VGImage src,
- const VGfloat * matrix)
+void vegaColorMatrix(VGImage dst, VGImage src,
+ const VGfloat * matrix)
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
return;
}
- d = (struct vg_image*)dst;
- s = (struct vg_image*)src;
+ d = handle_to_image(dst);
+ s = handle_to_image(src);
if (vg_image_overlaps(d, s)) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
info.const_buffer = matrix;
info.const_buffer_len = 20 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
}
return diff / width;
}
-void vgConvolve(VGImage dst, VGImage src,
- VGint kernelWidth, VGint kernelHeight,
- VGint shiftX, VGint shiftY,
- const VGshort * kernel,
- VGfloat scale,
- VGfloat bias,
- VGTilingMode tilingMode)
+void vegaConvolve(VGImage dst, VGImage src,
+ VGint kernelWidth, VGint kernelHeight,
+ VGint shiftX, VGint shiftY,
+ const VGshort * kernel,
+ VGfloat scale,
+ VGfloat bias,
+ VGTilingMode tilingMode)
{
struct vg_context *ctx = vg_current_context();
VGfloat *buffer;
struct vg_image *d, *s;
VGint kernel_size = kernelWidth * kernelHeight;
struct filter_info info;
- const VGint max_kernel_size = vgGeti(VG_MAX_KERNEL_SIZE);
+ const VGint max_kernel_size = vegaGeti(VG_MAX_KERNEL_SIZE);
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
return;
}
- d = (struct vg_image*)dst;
- s = (struct vg_image*)src;
+ d = handle_to_image(dst);
+ s = handle_to_image(src);
if (vg_image_overlaps(d, s)) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
vg_validate_state(ctx);
buffer_len = 8 + 2 * 4 * kernel_size;
- buffer = (VGfloat*)malloc(buffer_len * sizeof(VGfloat));
+ buffer = malloc(buffer_len * sizeof(VGfloat));
buffer[0] = 0.f;
buffer[1] = 1.f;
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
}
-void vgSeparableConvolve(VGImage dst, VGImage src,
- VGint kernelWidth,
- VGint kernelHeight,
- VGint shiftX, VGint shiftY,
- const VGshort * kernelX,
- const VGshort * kernelY,
- VGfloat scale,
- VGfloat bias,
- VGTilingMode tilingMode)
+void vegaSeparableConvolve(VGImage dst, VGImage src,
+ VGint kernelWidth,
+ VGint kernelHeight,
+ VGint shiftX, VGint shiftY,
+ const VGshort * kernelX,
+ const VGshort * kernelY,
+ VGfloat scale,
+ VGfloat bias,
+ VGTilingMode tilingMode)
{
struct vg_context *ctx = vg_current_context();
VGshort *kernel;
VGint i, j, idx = 0;
- const VGint max_kernel_size = vgGeti(VG_MAX_SEPARABLE_KERNEL_SIZE);
+ const VGint max_kernel_size = vegaGeti(VG_MAX_SEPARABLE_KERNEL_SIZE);
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
++idx;
}
}
- vgConvolve(dst, src, kernelWidth, kernelHeight, shiftX, shiftY,
- kernel, scale, bias, tilingMode);
+ vegaConvolve(dst, src, kernelWidth, kernelHeight, shiftX, shiftY,
+ kernel, scale, bias, tilingMode);
free(kernel);
}
}
}
-void vgGaussianBlur(VGImage dst, VGImage src,
- VGfloat stdDeviationX,
- VGfloat stdDeviationY,
- VGTilingMode tilingMode)
+void vegaGaussianBlur(VGImage dst, VGImage src,
+ VGfloat stdDeviationX,
+ VGfloat stdDeviationY,
+ VGTilingMode tilingMode)
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
return;
}
- d = (struct vg_image*)dst;
- s = (struct vg_image*)src;
+ d = handle_to_image(dst);
+ s = handle_to_image(src);
if (vg_image_overlaps(d, s)) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
stdDeviationX, stdDeviationY);
buffer_len = 8 + 2 * 4 * kernel_size;
- buffer = (VGfloat*)malloc(buffer_len * sizeof(VGfloat));
+ buffer = malloc(buffer_len * sizeof(VGfloat));
buffer[0] = 0.f;
buffer[1] = 1.f;
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
free(kernel);
}
-void vgLookup(VGImage dst, VGImage src,
- const VGubyte * redLUT,
- const VGubyte * greenLUT,
- const VGubyte * blueLUT,
- const VGubyte * alphaLUT,
- VGboolean outputLinear,
- VGboolean outputPremultiplied)
+void vegaLookup(VGImage dst, VGImage src,
+ const VGubyte * redLUT,
+ const VGubyte * greenLUT,
+ const VGubyte * blueLUT,
+ const VGubyte * alphaLUT,
+ VGboolean outputLinear,
+ VGboolean outputPremultiplied)
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
VGuint color_data[256];
VGint i;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
return;
}
- d = (struct vg_image*)dst;
- s = (struct vg_image*)src;
+ d = handle_to_image(dst);
+ s = handle_to_image(src);
if (vg_image_overlaps(d, s)) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
color_data[i] = blueLUT[i] << 24 | greenLUT[i] << 16 |
redLUT[i] << 8 | alphaLUT[i];
}
- lut_texture = create_texture_1d(ctx, color_data, 255);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 255);
buffer[0] = 0.f;
buffer[1] = 0.f;
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
-void vgLookupSingle(VGImage dst, VGImage src,
- const VGuint * lookupTable,
- VGImageChannel sourceChannel,
- VGboolean outputLinear,
- VGboolean outputPremultiplied)
+void vegaLookupSingle(VGImage dst, VGImage src,
+ const VGuint * lookupTable,
+ VGImageChannel sourceChannel,
+ VGboolean outputLinear,
+ VGboolean outputPremultiplied)
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
VGuint color_data[256];
return;
}
- d = (struct vg_image*)dst;
- s = (struct vg_image*)src;
+ d = handle_to_image(dst);
+ s = handle_to_image(src);
if (vg_image_overlaps(d, s)) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
return;
}
+ vg_validate_state(ctx);
+
for (i = 0; i < 256; ++i) {
VGuint rgba = lookupTable[i];
VGubyte blue, green, red, alpha;
color_data[i] = blue << 24 | green << 16 |
red << 8 | alpha;
}
- lut_texture = create_texture_1d(ctx, color_data, 256);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 256);
buffer[0] = 0.f;
buffer[1] = 0.f;
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}