2 // Copyright 2012 Francisco Jerez
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
23 #include "core/resource.hpp"
24 #include "pipe/p_screen.h"
25 #include "util/u_sampler.h"
26 #include "util/u_format.h"
28 using namespace clover
;
33 box(const resource::point
&origin
, const resource::point
&size
) :
34 pipe({ (int)origin
[0], (int)origin
[1],
35 (int)origin
[2], (int)size
[0],
36 (int)size
[1], (int)size
[2] }) {
39 operator const pipe_box
*() {
48 resource::resource(clover::device
&dev
, clover::memory_obj
&obj
) :
49 dev(dev
), obj(obj
), pipe(NULL
), offset
{0} {
52 resource::~resource() {
56 resource::copy(command_queue
&q
, const point
&origin
, const point
®ion
,
57 resource
&src_res
, const point
&src_origin
) {
58 point p
= offset
+ origin
;
60 q
.pipe
->resource_copy_region(q
.pipe
, pipe
, 0, p
[0], p
[1], p
[2],
62 box(src_res
.offset
+ src_origin
, region
));
66 resource::add_map(command_queue
&q
, cl_map_flags flags
, bool blocking
,
67 const point
&origin
, const point
®ion
) {
68 maps
.emplace_back(q
, *this, flags
, blocking
, origin
, region
);
73 resource::del_map(void *p
) {
74 auto it
= std::find(maps
.begin(), maps
.end(), p
);
80 resource::map_count() const {
85 resource::bind_sampler_view(clover::command_queue
&q
) {
86 pipe_sampler_view info
;
88 u_sampler_view_default_template(&info
, pipe
, pipe
->format
);
89 return q
.pipe
->create_sampler_view(q
.pipe
, pipe
, &info
);
93 resource::unbind_sampler_view(clover::command_queue
&q
,
94 pipe_sampler_view
*st
) {
95 q
.pipe
->sampler_view_destroy(q
.pipe
, st
);
99 resource::bind_surface(clover::command_queue
&q
, bool rw
) {
100 pipe_surface info
{};
102 info
.format
= pipe
->format
;
105 if (pipe
->target
== PIPE_BUFFER
)
106 info
.u
.buf
.last_element
= pipe
->width0
- 1;
108 return q
.pipe
->create_surface(q
.pipe
, pipe
, &info
);
112 resource::unbind_surface(clover::command_queue
&q
, pipe_surface
*st
) {
113 q
.pipe
->surface_destroy(q
.pipe
, st
);
116 root_resource::root_resource(clover::device
&dev
, clover::memory_obj
&obj
,
117 clover::command_queue
&q
,
118 const std::string
&data
) :
120 pipe_resource info
{};
122 if (image
*img
= dynamic_cast<image
*>(&obj
)) {
123 info
.format
= translate_format(img
->format());
124 info
.width0
= img
->width();
125 info
.height0
= img
->height();
126 info
.depth0
= img
->depth();
128 info
.width0
= obj
.size();
133 info
.target
= translate_target(obj
.type());
134 info
.bind
= (PIPE_BIND_SAMPLER_VIEW
|
135 PIPE_BIND_COMPUTE_RESOURCE
|
137 PIPE_BIND_TRANSFER_READ
|
138 PIPE_BIND_TRANSFER_WRITE
);
140 pipe
= dev
.pipe
->resource_create(dev
.pipe
, &info
);
142 throw error(CL_OUT_OF_RESOURCES
);
145 box rect
{ { 0, 0, 0 }, { info
.width0
, info
.height0
, info
.depth0
} };
146 unsigned cpp
= util_format_get_blocksize(info
.format
);
148 q
.pipe
->transfer_inline_write(q
.pipe
, pipe
, 0, PIPE_TRANSFER_WRITE
,
149 rect
, data
.data(), cpp
* info
.width0
,
150 cpp
* info
.width0
* info
.height0
);
154 root_resource::root_resource(clover::device
&dev
, clover::memory_obj
&obj
,
155 clover::root_resource
&r
) :
157 assert(0); // XXX -- resource shared among dev and r.dev
160 root_resource::~root_resource() {
161 dev
.pipe
->resource_destroy(dev
.pipe
, pipe
);
164 sub_resource::sub_resource(clover::resource
&r
, point offset
) :
165 resource(r
.dev
, r
.obj
) {
167 offset
= r
.offset
+ offset
;
170 mapping::mapping(command_queue
&q
, resource
&r
,
171 cl_map_flags flags
, bool blocking
,
172 const resource::point
&origin
,
173 const resource::point
®ion
) :
175 unsigned usage
= ((flags
& CL_MAP_WRITE
? PIPE_TRANSFER_WRITE
: 0 ) |
176 (flags
& CL_MAP_READ
? PIPE_TRANSFER_READ
: 0 ) |
177 (blocking
? PIPE_TRANSFER_UNSYNCHRONIZED
: 0));
179 p
= pctx
->transfer_map(pctx
, r
.pipe
, 0, usage
,
180 box(origin
+ r
.offset
, region
), &pxfer
);
183 throw error(CL_OUT_OF_RESOURCES
);
187 mapping::mapping(mapping
&&m
) :
188 pctx(m
.pctx
), pxfer(m
.pxfer
), p(m
.p
) {
193 mapping::~mapping() {
195 pctx
->transfer_unmap(pctx
, pxfer
);