1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  * Authors:
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  *   Keith Whitwell <keith@tungstengraphics.com>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  *   Michel Dänzer <michel@tungstengraphics.com>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  */
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_transfer.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_context.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_flush.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_texture.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_screen.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "state_tracker/sw_winsys.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Conventional allocation path for non-display textures:
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Use a simple, maximally packed layout.
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_resource_layout(struct pipe_screen *screen,
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct softpipe_resource *spr)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *pt = &spr->base;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned level;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned width = pt->width0;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned height = pt->height0;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned depth = pt->depth0;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned buffer_size = 0;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (level = 0; level <= pt->last_level; level++) {
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned slices;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pt->target == PIPE_TEXTURE_CUBE)
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         slices = 6;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (pt->target == PIPE_TEXTURE_3D)
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         slices = depth;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         slices = pt->array_size;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      spr->stride[level] = util_format_get_stride(pt->format, width);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      spr->level_offset[level] = buffer_size;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      buffer_size += (util_format_get_nblocksy(pt->format, height) *
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      slices * spr->stride[level]);
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      width  = u_minify(width, 1);
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      height = u_minify(height, 1);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      depth = u_minify(depth, 1);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->data = align_malloc(buffer_size, 16);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return spr->data != NULL;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Texture layout for simple color buffers.
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_displaytarget_layout(struct pipe_screen *screen,
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              struct softpipe_resource *spr)
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Round up the surface size to a multiple of the tile size?
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->dt = winsys->displaytarget_create(winsys,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          spr->base.bind,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          spr->base.format,
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          spr->base.width0,
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          spr->base.height0,
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          16,
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &spr->stride[0] );
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return spr->dt != NULL;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create new pipe_resource given the template information.
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_resource *
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_resource_create(struct pipe_screen *screen,
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct pipe_resource *templat)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr = CALLOC_STRUCT(softpipe_resource);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!spr)
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(templat->format != PIPE_FORMAT_NONE);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base = *templat;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_reference_init(&spr->base.reference, 1);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.screen = screen;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->pot = (util_is_power_of_two(templat->width0) &&
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               util_is_power_of_two(templat->height0) &&
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               util_is_power_of_two(templat->depth0));
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (spr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 PIPE_BIND_SCANOUT |
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 PIPE_BIND_SHARED)) {
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!softpipe_displaytarget_layout(screen, spr))
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto fail;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!softpipe_resource_layout(screen, spr))
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto fail;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &spr->base;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail:
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(spr);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_resource_destroy(struct pipe_screen *pscreen,
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct pipe_resource *pt)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_screen *screen = softpipe_screen(pscreen);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr = softpipe_resource(pt);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (spr->dt) {
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* display target */
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct sw_winsys *winsys = screen->winsys;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      winsys->displaytarget_destroy(winsys, spr->dt);
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (!spr->userBuffer) {
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* regular texture */
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      align_free(spr->data);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(spr);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_resource *
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_resource_from_handle(struct pipe_screen *screen,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const struct pipe_resource *templat,
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              struct winsys_handle *whandle)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr = CALLOC_STRUCT(softpipe_resource);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!spr)
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base = *templat;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_reference_init(&spr->base.reference, 1);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.screen = screen;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->pot = (util_is_power_of_two(templat->width0) &&
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               util_is_power_of_two(templat->height0) &&
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               util_is_power_of_two(templat->depth0));
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->dt = winsys->displaytarget_from_handle(winsys,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               templat,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               whandle,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               &spr->stride[0]);
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!spr->dt)
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &spr->base;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail:
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(spr);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_resource_get_handle(struct pipe_screen *screen,
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             struct pipe_resource *pt,
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             struct winsys_handle *whandle)
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr = softpipe_resource(pt);
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(spr->dt);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!spr->dt)
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return winsys->displaytarget_get_handle(winsys, spr->dt, whandle);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Helper function to compute offset (in bytes) for a particular
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * texture level/face/slice from the start of the buffer.
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_get_tex_image_offset(const struct softpipe_resource *spr,
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        unsigned level, unsigned layer)
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned hgt = u_minify(spr->base.height0, level);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned offset = spr->level_offset[level];
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (spr->base.target == PIPE_TEXTURE_CUBE ||
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       spr->base.target == PIPE_TEXTURE_3D ||
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       spr->base.target == PIPE_TEXTURE_2D_ARRAY) {
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset += layer * nblocksy * spr->stride[level];
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (spr->base.target == PIPE_TEXTURE_1D_ARRAY) {
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset += layer * spr->stride[level];
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(layer == 0);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return offset;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get a pipe_surface "view" into a texture resource.
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_surface *
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_create_surface(struct pipe_context *pipe,
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        struct pipe_resource *pt,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct pipe_surface *surf_tmpl)
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_surface *ps;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned level = surf_tmpl->u.tex.level;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(level <= pt->last_level);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ps = CALLOC_STRUCT(pipe_surface);
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ps) {
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_reference_init(&ps->reference, 1);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&ps->texture, pt);
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->context = pipe;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->format = surf_tmpl->format;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->width = u_minify(pt->width0, level);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->height = u_minify(pt->height0, level);
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->usage = surf_tmpl->usage;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->u.tex.level = level;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ps;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free a pipe_surface which was created with softpipe_create_surface().
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_surface_destroy(struct pipe_context *pipe,
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct pipe_surface *surf)
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Effectively do the texture_update work here - if texture images
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * needed post-processing to put them into hardware layout, this is
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * where it would happen.  For softpipe, nothing to do.
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(surf->texture);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&surf->texture, NULL);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(surf);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Geta pipe_transfer object which is used for moving data in/out of
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a resource object.
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param pipe  rendering context
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param resource  the resource to transfer in/out of
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param level  which mipmap level
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param usage  bitmask of PIPE_TRANSFER_x flags
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param box  the 1D/2D/3D region of interest
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_transfer *
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_get_transfer(struct pipe_context *pipe,
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct pipe_resource *resource,
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned level,
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned usage,
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct pipe_box *box)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr = softpipe_resource(resource);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_transfer *spt;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(resource);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(level <= resource->last_level);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make sure the requested region is in the image bounds */
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(box->x + box->width <= u_minify(resource->width0, level));
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(box->y + box->height <= resource->array_size);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(box->y + box->height <= u_minify(resource->height0, level));
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(box->z + box->depth <= resource->array_size);
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (resource->target == PIPE_TEXTURE_CUBE) {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(box->z < 6);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Transfers, like other pipe operations, must happen in order, so flush the
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * context if necessary.
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!softpipe_flush_resource(pipe, resource,
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   level, box->depth > 1 ? -1 : box->z,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   0, /* flush_flags */
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   read_only,
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   TRUE, /* cpu_access */
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   do_not_block)) {
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * It would have blocked, but state tracker requested no to.
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(do_not_block);
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spt = CALLOC_STRUCT(softpipe_transfer);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (spt) {
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct pipe_transfer *pt = &spt->base;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      enum pipe_format format = resource->format;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned hgt = u_minify(spr->base.height0, level);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&pt->resource, resource);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pt->level = level;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pt->usage = usage;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pt->box = *box;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pt->stride = spr->stride[level];
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pt->layer_stride = pt->stride * nblocksy;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      spt->offset = sp_get_tex_image_offset(spr, level, box->z);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      spt->offset +=
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         box->y / util_format_get_blockheight(format) * spt->base.stride +
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return pt;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free a pipe_transfer object which was created with
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * softpipe_get_transfer().
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_transfer_destroy(struct pipe_context *pipe,
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct pipe_transfer *transfer)
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&transfer->resource, NULL);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(transfer);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create memory mapping for given pipe_transfer object.
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_transfer_map(struct pipe_context *pipe,
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct pipe_transfer *transfer)
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_transfer *spt = softpipe_transfer(transfer);
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr = softpipe_resource(transfer->resource);
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint8_t *map;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* resources backed by display target treated specially:
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (spr->dt) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      map = winsys->displaytarget_map(winsys, spr->dt, transfer->usage);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      map = spr->data;
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (map == NULL)
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return map + spt->offset;
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Unmap memory mapping for given pipe_transfer object.
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_transfer_unmap(struct pipe_context *pipe,
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        struct pipe_transfer *transfer)
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr;
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(transfer->resource);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr = softpipe_resource(transfer->resource);
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (spr->dt) {
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* display target */
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      winsys->displaytarget_unmap(winsys, spr->dt);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (transfer->usage & PIPE_TRANSFER_WRITE) {
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Mark the texture as dirty to expire the tile caches. */
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      spr->timestamp++;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create buffer which wraps user-space data.
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource *
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_user_buffer_create(struct pipe_screen *screen,
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            void *ptr,
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            unsigned bytes,
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    unsigned bind_flags)
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_resource *spr;
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr = CALLOC_STRUCT(softpipe_resource);
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!spr)
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_reference_init(&spr->base.reference, 1);
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.screen = screen;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.bind = bind_flags;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.usage = PIPE_USAGE_IMMUTABLE;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.flags = 0;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.width0 = bytes;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.height0 = 1;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.depth0 = 1;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->base.array_size = 1;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->userBuffer = TRUE;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spr->data = ptr;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &spr->base;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_init_texture_funcs(struct pipe_context *pipe)
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->get_transfer = softpipe_get_transfer;
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->transfer_destroy = softpipe_transfer_destroy;
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->transfer_map = softpipe_transfer_map;
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->transfer_unmap = softpipe_transfer_unmap;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->transfer_flush_region = u_default_transfer_flush_region;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->transfer_inline_write = u_default_transfer_inline_write;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->create_surface = softpipe_create_surface;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe->surface_destroy = softpipe_surface_destroy;
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_init_screen_texture_funcs(struct pipe_screen *screen)
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen->resource_create = softpipe_resource_create;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen->resource_destroy = softpipe_resource_destroy;
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen->resource_from_handle = softpipe_resource_from_handle;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen->resource_get_handle = softpipe_resource_get_handle;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
510