1fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri/**************************************************************************
2fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
3fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * Copyright 2010 Luca Barbieri
4fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
5fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * Permission is hereby granted, free of charge, to any person obtaining
6fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * a copy of this software and associated documentation files (the
7fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * "Software"), to deal in the Software without restriction, including
8fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * without limitation the rights to use, copy, modify, merge, publish,
9fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * distribute, sublicense, and/or sell copies of the Software, and to
10fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * permit persons to whom the Software is furnished to do so, subject to
11fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * the following conditions:
12fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
13fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * The above copyright notice and this permission notice (including the
14fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * next paragraph) shall be included in all copies or substantial
15fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * portions of the Software.
16fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
17fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
25fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri **************************************************************************/
26fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri
27ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri#include "u_surfaces.h"
28ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri#include "util/u_hash_table.h"
29ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri#include "util/u_inlines.h"
30ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri#include "util/u_memory.h"
31ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
32af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantryboolean
334c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggerutil_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
34e3256ccb045032960f099318938991392b896b44Xavier Chantry                     struct pipe_context *ctx, struct pipe_resource *pt,
35af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry                     unsigned level, unsigned layer, unsigned flags,
36af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry                     struct pipe_surface **res)
37ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri{
38ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   struct pipe_surface *ps;
39ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
40ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
41e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri   {    /* or 2D array */
42e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri      if(!us->u.hash)
43e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         us->u.hash = cso_hash_create();
44e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri
454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      ps = cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level));
46ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   }
47ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   else
48ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   {
49ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      if(!us->u.array)
50e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *));
51ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      ps = us->u.array[level];
52ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   }
53ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
54e3256ccb045032960f099318938991392b896b44Xavier Chantry   if(ps && ps->context == ctx)
55ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   {
56ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      p_atomic_inc(&ps->reference.count);
57af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry      *res = ps;
58af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry      return FALSE;
59ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   }
60ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
61ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   ps = (struct pipe_surface *)CALLOC(1, surface_struct_size);
62ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   if(!ps)
63af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry   {
64af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry      *res = NULL;
65af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry      return FALSE;
66af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry   }
67ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
68e3256ccb045032960f099318938991392b896b44Xavier Chantry   pipe_surface_init(ctx, ps, pt, level, layer, flags);
69ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
70ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
714c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      cso_hash_insert(us->u.hash, (layer << 8) | level, ps);
72ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   else
73ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      us->u.array[level] = ps;
74ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
75af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry   *res = ps;
76af5345d9371e927019d51ce3ad198958f8cd42a9Xavier Chantry   return TRUE;
77ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri}
78ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
79ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbierivoid
80ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieriutil_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps)
81ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri{
82ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   struct pipe_resource *pt = ps->texture;
83ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
84e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri   {    /* or 2D array */
854c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, (ps->u.tex.first_layer << 8) | ps->u.tex.level));
86ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   }
87ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   else
884c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      us->u.array[ps->u.tex.level] = 0;
89ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri}
90ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri
91ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbierivoid
92ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieriutil_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *))
93ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri{
94ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
95e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri   {    /* or 2D array */
96e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri      if(us->u.hash)
97ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      {
98e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         struct cso_hash_iter iter;
99e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         iter = cso_hash_first_node(us->u.hash);
100e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         while (!cso_hash_iter_is_null(iter)) {
101e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri            destroy_surface(cso_hash_iter_data(iter));
102e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri            iter = cso_hash_iter_next(iter);
103e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         }
104e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri
105e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         cso_hash_delete(us->u.hash);
106e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         us->u.hash = NULL;
107ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      }
108ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   }
109ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   else
110ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   {
111ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      if(us->u.array)
112ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      {
113e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         unsigned i;
114e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         for(i = 0; i <= pt->last_level; ++i)
115e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         {
116e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri            struct pipe_surface *ps = us->u.array[i];
117e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri            if(ps)
118e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri               destroy_surface(ps);
119e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         }
120e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         FREE(us->u.array);
121e45b2ce2c3a52e9f8e6fb7e933ab2f95eec15be1Luca Barbieri         us->u.array = NULL;
122ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri      }
123ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri   }
124ac4b8db62d056fa5b85661f67ba5e1d1d29e3fcfLuca Barbieri}
125