ilo: replace a boolean by bool
[mesa.git] / src / gallium / state_trackers / vega / vg_context.c
index 19f4e71e0d9c8899984c470da6187206e0f26869..c63618816835143e79ea9bc9d958edea200954ff 100644 (file)
 #include "renderer.h"
 #include "shaders_cache.h"
 #include "shader.h"
-#include "asm_util.h"
-#include "st_inlines.h"
 #include "vg_manager.h"
 #include "api.h"
 #include "mask.h"
+#include "handle.h"
 
 #include "pipe/p_context.h"
 #include "util/u_inlines.h"
 
 #include "cso_cache/cso_context.h"
 
-#include "util/u_simple_shaders.h"
 #include "util/u_memory.h"
 #include "util/u_blit.h"
 #include "util/u_sampler.h"
+#include "util/u_surface.h"
 #include "util/u_format.h"
 
 struct vg_context *_vg_context = 0;
@@ -62,15 +61,15 @@ choose_depth_stencil_format(struct vg_context *ctx)
 {
    struct pipe_screen *screen = ctx->pipe->screen;
    enum pipe_format formats[] = {
-      PIPE_FORMAT_Z24_UNORM_S8_USCALED,
-      PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+      PIPE_FORMAT_Z24_UNORM_S8_UINT,
+      PIPE_FORMAT_S8_UINT_Z24_UNORM,
       PIPE_FORMAT_NONE
    };
    enum pipe_format *fmt;
 
    for (fmt = formats; *fmt != PIPE_FORMAT_NONE; fmt++) {
       if (screen->is_format_supported(screen, *fmt,
-               PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0))
+               PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL))
          break;
    }
 
@@ -184,42 +183,49 @@ void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_objec
 {
    obj->type = type;
    obj->ctx = ctx;
+   obj->handle = create_handle(obj);
+}
+
+/** free object resources, but not the object itself */
+void vg_free_object(struct vg_object *obj)
+{
+   obj->type = 0;
+   obj->ctx = NULL;
+   destroy_handle(obj->handle);
 }
 
 VGboolean vg_context_is_object_valid(struct vg_context *ctx,
                                 enum vg_object_type type,
-                                void *ptr)
+                                VGHandle handle)
 {
     if (ctx) {
        struct cso_hash *hash = ctx->owned_objects[type];
        if (!hash)
           return VG_FALSE;
-       return cso_hash_contains(hash, (unsigned)(long)ptr);
+       return cso_hash_contains(hash, (unsigned) handle);
     }
     return VG_FALSE;
 }
 
 void vg_context_add_object(struct vg_context *ctx,
-                           enum vg_object_type type,
-                           void *ptr)
+                           struct vg_object *obj)
 {
     if (ctx) {
-       struct cso_hash *hash = ctx->owned_objects[type];
+       struct cso_hash *hash = ctx->owned_objects[obj->type];
        if (!hash)
           return;
-       cso_hash_insert(hash, (unsigned)(long)ptr, ptr);
+       cso_hash_insert(hash, (unsigned) obj->handle, obj);
     }
 }
 
 void vg_context_remove_object(struct vg_context *ctx,
-                              enum vg_object_type type,
-                              void *ptr)
+                              struct vg_object *obj)
 {
    if (ctx) {
-      struct cso_hash *hash = ctx->owned_objects[type];
+      struct cso_hash *hash = ctx->owned_objects[obj->type];
       if (!hash)
          return;
-      cso_hash_take(hash, (unsigned)(long)ptr);
+      cso_hash_take(hash, (unsigned) obj->handle);
    }
 }
 
@@ -242,6 +248,7 @@ create_texture(struct pipe_context *pipe, enum pipe_format format,
    templ.width0 = width;
    templ.height0 = height;
    templ.depth0 = 1;
+   templ.array_size = 1;
    templ.last_level = 0;
 
    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
@@ -277,11 +284,11 @@ create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
 }
 
 static void
-vg_context_update_alpha_mask_view(struct vg_context *ctx,
-                                  uint width, uint height)
+vg_context_update_surface_mask_view(struct vg_context *ctx,
+                                    uint width, uint height)
 {
    struct st_framebuffer *stfb = ctx->draw_buffer;
-   struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
+   struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view;
    struct pipe_context *pipe = ctx->pipe;
 
    if (old_sampler_view &&
@@ -294,10 +301,10 @@ vg_context_update_alpha_mask_view(struct vg_context *ctx,
      this texture and use it as a sampler, so while this wastes some
      space it makes both of those a lot simpler
    */
-   stfb->alpha_mask_view = create_tex_and_view(pipe,
+   stfb->surface_mask_view = create_tex_and_view(pipe,
          PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
 
-   if (!stfb->alpha_mask_view) {
+   if (!stfb->surface_mask_view) {
       if (old_sampler_view)
          pipe_sampler_view_reference(&old_sampler_view, NULL);
       return;
@@ -311,22 +318,18 @@ vg_context_update_alpha_mask_view(struct vg_context *ctx,
 
    /* if we had an old surface copy it over */
    if (old_sampler_view) {
-      struct pipe_subresource subsurf, subold_surf;
-      subsurf.face = 0;
-      subsurf.level = 0;
-      subold_surf.face = 0;
-      subold_surf.level = 0;
+      struct pipe_box src_box;
+      u_box_origin_2d(MIN2(old_sampler_view->texture->width0,
+                           stfb->surface_mask_view->texture->width0),
+                      MIN2(old_sampler_view->texture->height0,
+                           stfb->surface_mask_view->texture->height0),
+                      &src_box);
+
       pipe->resource_copy_region(pipe,
-                                 stfb->alpha_mask_view->texture,
-                                 subsurf,
-                                 0, 0, 0,
+                                 stfb->surface_mask_view->texture,
+                                 0, 0, 0, 0,
                                  old_sampler_view->texture,
-                                 subold_surf,
-                                 0, 0, 0,
-                                 MIN2(old_sampler_view->texture->width0,
-                                      stfb->alpha_mask_view->texture->width0),
-                                 MIN2(old_sampler_view->texture->height0,
-                                      stfb->alpha_mask_view->texture->height0));
+                                 0, &src_box);
    }
 
    /* Free the old texture
@@ -360,7 +363,7 @@ vg_context_update_depth_stencil_rb(struct vg_context * ctx,
 {
    struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
    struct pipe_context *pipe = ctx->pipe;
-   unsigned surface_usage;
+   struct pipe_surface surf_tmpl;
 
    if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
       return FALSE;
@@ -370,18 +373,14 @@ vg_context_update_depth_stencil_rb(struct vg_context * ctx,
    pipe_resource_reference(&dsrb->texture, NULL);
    dsrb->width = dsrb->height = 0;
 
-   /* Probably need dedicated flags for surface usage too:
-    */
-   surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */
-
    dsrb->texture = create_texture(pipe, dsrb->format, width, height);
    if (!dsrb->texture)
       return TRUE;
 
-   dsrb->surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                 dsrb->texture,
-                                                 0, 0, 0,
-                                                 surface_usage);
+   u_surface_default_template(&surf_tmpl, dsrb->texture);
+   dsrb->surface = pipe->create_surface(pipe,
+                                        dsrb->texture,
+                                        &surf_tmpl);
    if (!dsrb->surface) {
       pipe_resource_reference(&dsrb->texture, NULL);
       return TRUE;
@@ -405,23 +404,25 @@ void vg_validate_state(struct vg_context *ctx)
    if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height))
       ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
 
-   /* TODO create as needed */
-   vg_context_update_alpha_mask_view(ctx, stfb->width, stfb->height);
-   vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
+   /* blend state depends on fb format and paint color */
+   if ((ctx->state.dirty & FRAMEBUFFER_DIRTY) ||
+       (ctx->state.dirty & PAINT_DIRTY))
+      ctx->state.dirty |= BLEND_DIRTY;
 
    renderer_validate(ctx->renderer, ctx->state.dirty,
          ctx->draw_buffer, &ctx->state.vg);
 
-   ctx->state.dirty = NONE_DIRTY;
+   ctx->state.dirty = 0;
 
    shader_set_masking(ctx->shader, ctx->state.vg.masking);
    shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode);
+   shader_set_color_transform(ctx->shader, ctx->state.vg.color_transform);
 }
 
-VGboolean vg_object_is_valid(void *ptr, enum vg_object_type type)
+VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type)
 {
-   struct vg_object *obj = ptr;
-   if (ptr && is_aligned(obj) && obj->type == type)
+   struct vg_object *obj = handle_to_object(object);
+   if (obj && is_aligned(obj) && obj->type == type)
       return VG_TRUE;
    else
       return VG_FALSE;
@@ -438,73 +439,92 @@ void vg_set_error(struct vg_context *ctx,
       ctx->_error = code;
 }
 
-void vg_prepare_blend_surface(struct vg_context *ctx)
+static void vg_prepare_blend_texture(struct vg_context *ctx,
+                                     struct pipe_sampler_view *src)
+{
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+   struct pipe_surface *surf;
+   struct pipe_surface surf_tmpl;
+
+   vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
+
+   u_surface_default_template(&surf_tmpl, stfb->blend_texture_view->texture);
+   surf = ctx->pipe->create_surface(ctx->pipe,
+                                    stfb->blend_texture_view->texture,
+                                    &surf_tmpl);
+   if (surf) {
+      util_blit_pixels_tex(ctx->blit,
+                           src, 0, 0, stfb->width, stfb->height,
+                           surf, 0, 0, stfb->width, stfb->height,
+                           0.0, PIPE_TEX_MIPFILTER_NEAREST);
+
+      pipe_surface_reference(&surf, NULL);
+   }
+}
+
+struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx)
 {
-   struct pipe_surface *dest_surface = NULL;
    struct pipe_context *pipe = ctx->pipe;
    struct pipe_sampler_view *view;
    struct pipe_sampler_view view_templ;
    struct st_framebuffer *stfb = ctx->draw_buffer;
    struct st_renderbuffer *strb = stfb->strb;
 
-   /* first finish all pending rendering */
-   vgFinish();
+   vg_validate_state(ctx);
 
    u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format);
    view = pipe->create_sampler_view(pipe, strb->texture, &view_templ);
 
-   dest_surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                stfb->blend_texture_view->texture,
-                                                0, 0, 0,
-                                                PIPE_BIND_RENDER_TARGET);
-   util_blit_pixels_tex(ctx->blit,
-                        view,
-                        0, 0,
-                        strb->width, strb->height,
-                        dest_surface,
-                        0, 0,
-                        strb->width, strb->height,
-                        0.0, PIPE_TEX_MIPFILTER_NEAREST);
-
-   if (dest_surface)
-      pipe_surface_reference(&dest_surface, NULL);
-
-   /* make sure it's complete */
-   vgFinish();
+   vg_prepare_blend_texture(ctx, view);
 
    pipe_sampler_view_reference(&view, NULL);
+
+   return stfb->blend_texture_view;
 }
 
 
-void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
+struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
 {
-   struct pipe_surface *dest_surface = NULL;
-   struct pipe_context *pipe = ctx->pipe;
    struct st_framebuffer *stfb = ctx->draw_buffer;
-   struct st_renderbuffer *strb = stfb->strb;
 
    vg_validate_state(ctx);
 
-   /* first finish all pending rendering */
-   vgFinish();
+   vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
+   vg_prepare_blend_texture(ctx, stfb->surface_mask_view);
 
-   dest_surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                stfb->blend_texture_view->texture,
-                                                0, 0, 0,
-                                                PIPE_BIND_RENDER_TARGET);
+   return stfb->blend_texture_view;
+}
 
-   util_blit_pixels_tex(ctx->blit,
-                        stfb->alpha_mask_view,
-                        0, 0,
-                        strb->width, strb->height,
-                        dest_surface,
-                        0, 0,
-                        strb->width, strb->height,
-                        0.0, PIPE_TEX_MIPFILTER_NEAREST);
+struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx)
+{
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+
+   vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
+
+   return stfb->surface_mask_view;
+}
+
+/**
+ * A transformation from window coordinates to paint coordinates.
+ */
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+                              const struct matrix *paint_to_user,
+                              const struct matrix *user_to_surface,
+                              struct matrix *mat)
+{
+   struct matrix tmp;
+
+   /* get user-to-paint matrix */
+   memcpy(mat, paint_to_user, sizeof(*paint_to_user));
+   if (!matrix_invert(mat))
+      return VG_FALSE;
+
+   /* get surface-to-user matrix */
+   memcpy(&tmp, user_to_surface, sizeof(*user_to_surface));
+   if (!matrix_invert(&tmp))
+      return VG_FALSE;
 
-   /* make sure it's complete */
-   vgFinish();
+   matrix_mult(mat, &tmp);
 
-   if (dest_surface)
-      pipe_surface_reference(&dest_surface, NULL);
+   return VG_TRUE;
 }