1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Copyright 2012 Francisco Jerez
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The above copyright notice and this permission notice shall be included in
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// all copies or substantial portions of the Software.
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// SOFTWARE.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "core/resource.hpp"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_sampler.h"
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clover;
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   class box {
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   public:
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      box(const resource::point &origin, const resource::point &size) :
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pipe({ (unsigned)origin[0], (unsigned)origin[1],
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                (unsigned)origin[2], (unsigned)size[0],
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                (unsigned)size[1], (unsigned)size[2] }) {
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      operator const pipe_box *() {
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return &pipe;
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   protected:
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_box pipe;
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::resource(clover::device &dev, clover::memory_obj &obj) :
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dev(dev), obj(obj), pipe(NULL), offset{0} {
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::~resource() {
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::copy(command_queue &q, const point &origin, const point &region,
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               resource &src_res, const point &src_origin) {
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   point p = offset + origin;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   q.pipe->resource_copy_region(q.pipe, pipe, 0, p[0], p[1], p[2],
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                src_res.pipe, 0,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                box(src_res.offset + src_origin, region));
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::add_map(command_queue &q, cl_map_flags flags, bool blocking,
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const point &origin, const point &region) {
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   maps.emplace_back(q, *this, flags, blocking, origin, region);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return maps.back();
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::del_map(void *p) {
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   auto it = std::find(maps.begin(), maps.end(), p);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (it != maps.end())
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      maps.erase(it);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::map_count() const {
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return maps.size();
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpipe_sampler_view *
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::bind_sampler_view(clover::command_queue &q) {
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_sampler_view info;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   u_sampler_view_default_template(&info, pipe, pipe->format);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return q.pipe->create_sampler_view(q.pipe, pipe, &info);
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::unbind_sampler_view(clover::command_queue &q,
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              pipe_sampler_view *st) {
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   q.pipe->sampler_view_destroy(q.pipe, st);
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpipe_surface *
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::bind_surface(clover::command_queue &q, bool rw) {
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_surface info {};
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info.format = pipe->format;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info.usage = pipe->bind;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info.writable = rw;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pipe->target == PIPE_BUFFER)
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.u.buf.last_element = pipe->width0 - 1;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return q.pipe->create_surface(q.pipe, pipe, &info);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource::unbind_surface(clover::command_queue &q, pipe_surface *st) {
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   q.pipe->surface_destroy(q.pipe, st);
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgroot_resource::root_resource(clover::device &dev, clover::memory_obj &obj,
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             clover::command_queue &q,
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const std::string &data) :
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resource(dev, obj) {
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource info {};
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (image *img = dynamic_cast<image *>(&obj)) {
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.format = translate_format(img->format());
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.width0 = img->width();
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.height0 = img->height();
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.depth0 = img->depth();
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.width0 = obj.size();
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.height0 = 1;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      info.depth0 = 1;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info.target = translate_target(obj.type());
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   info.bind = (PIPE_BIND_SAMPLER_VIEW |
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                PIPE_BIND_COMPUTE_RESOURCE |
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                PIPE_BIND_GLOBAL |
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                PIPE_BIND_TRANSFER_READ |
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                PIPE_BIND_TRANSFER_WRITE);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = dev.pipe->resource_create(dev.pipe, &info);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pipe)
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      throw error(CL_OUT_OF_RESOURCES);
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!data.empty()) {
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      box rect { { 0, 0, 0 }, { info.width0, info.height0, info.depth0 } };
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned cpp = util_format_get_blocksize(info.format);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      q.pipe->transfer_inline_write(q.pipe, pipe, 0, PIPE_TRANSFER_WRITE,
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    rect, data.data(), cpp * info.width0,
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    cpp * info.width0 * info.height0);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgroot_resource::root_resource(clover::device &dev, clover::memory_obj &obj,
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             clover::root_resource &r) :
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resource(dev, obj) {
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(0); // XXX -- resource shared among dev and r.dev
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgroot_resource::~root_resource() {
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dev.pipe->resource_destroy(dev.pipe, pipe);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsub_resource::sub_resource(clover::resource &r, point offset) :
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resource(r.dev, r.obj) {
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = r.pipe;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset = r.offset + offset;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmapping::mapping(command_queue &q, resource &r,
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 cl_map_flags flags, bool blocking,
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const resource::point &origin,
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const resource::point &region) :
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pctx(q.pipe) {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned usage = ((flags & CL_MAP_WRITE ? PIPE_TRANSFER_WRITE : 0 ) |
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     (flags & CL_MAP_READ ? PIPE_TRANSFER_READ : 0 ) |
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     (blocking ? PIPE_TRANSFER_UNSYNCHRONIZED : 0));
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pxfer = pctx->get_transfer(pctx, r.pipe, 0, usage,
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              box(origin + r.offset, region));
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pxfer)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      throw error(CL_OUT_OF_RESOURCES);
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   p = pctx->transfer_map(pctx, pxfer);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!p) {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pctx->transfer_destroy(pctx, pxfer);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      throw error(CL_OUT_OF_RESOURCES);
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmapping::mapping(mapping &&m) :
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pctx(m.pctx), pxfer(m.pxfer), p(m.p) {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   m.p = NULL;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   m.pxfer = NULL;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmapping::~mapping() {
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pxfer) {
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pctx->transfer_unmap(pctx, pxfer);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pctx->transfer_destroy(pctx, pxfer);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
204