tu: Implement fallback linear staging blit for CopyImage
[mesa.git] / src / gallium / state_trackers / clover / core / program.cpp
1 //
2 // Copyright 2012 Francisco Jerez
3 //
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:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
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.
21 //
22
23 #include "core/compiler.hpp"
24 #include "core/program.hpp"
25
26 using namespace clover;
27
28 program::program(clover::context &ctx, const std::string &source) :
29 has_source(true), context(ctx), _devices(ctx.devices()), _source(source),
30 _kernel_ref_counter(0) {
31 }
32
33 program::program(clover::context &ctx,
34 const ref_vector<device> &devs,
35 const std::vector<module> &binaries) :
36 has_source(false), context(ctx),
37 _devices(devs), _kernel_ref_counter(0) {
38 for_each([&](device &dev, const module &bin) {
39 _builds[&dev] = { bin };
40 },
41 devs, binaries);
42 }
43
44 void
45 program::compile(const ref_vector<device> &devs, const std::string &opts,
46 const header_map &headers) {
47 if (has_source) {
48 _devices = devs;
49
50 for (auto &dev : devs) {
51 std::string log;
52
53 try {
54 const module m =
55 compiler::compile_program(_source, headers, dev, opts, log);
56 _builds[&dev] = { m, opts, log };
57 } catch (...) {
58 _builds[&dev] = { module(), opts, log };
59 throw;
60 }
61 }
62 }
63 }
64
65 void
66 program::link(const ref_vector<device> &devs, const std::string &opts,
67 const ref_vector<program> &progs) {
68 _devices = devs;
69
70 for (auto &dev : devs) {
71 const std::vector<module> ms = map([&](const program &prog) {
72 return prog.build(dev).binary;
73 }, progs);
74 std::string log = _builds[&dev].log;
75
76 try {
77 const module m = compiler::link_program(ms, dev, opts, log);
78 _builds[&dev] = { m, opts, log };
79 } catch (...) {
80 _builds[&dev] = { module(), opts, log };
81 throw;
82 }
83 }
84 }
85
86 const std::string &
87 program::source() const {
88 return _source;
89 }
90
91 program::device_range
92 program::devices() const {
93 return map(evals(), _devices);
94 }
95
96 cl_build_status
97 program::build::status() const {
98 if (!binary.secs.empty())
99 return CL_BUILD_SUCCESS;
100 else if (log.size())
101 return CL_BUILD_ERROR;
102 else
103 return CL_BUILD_NONE;
104 }
105
106 cl_program_binary_type
107 program::build::binary_type() const {
108 if (any_of(type_equals(module::section::text_intermediate), binary.secs))
109 return CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
110 else if (any_of(type_equals(module::section::text_library), binary.secs))
111 return CL_PROGRAM_BINARY_TYPE_LIBRARY;
112 else if (any_of(type_equals(module::section::text_executable), binary.secs))
113 return CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
114 else
115 return CL_PROGRAM_BINARY_TYPE_NONE;
116 }
117
118 const struct program::build &
119 program::build(const device &dev) const {
120 static const struct build null;
121 return _builds.count(&dev) ? _builds.find(&dev)->second : null;
122 }
123
124 const std::vector<module::symbol> &
125 program::symbols() const {
126 if (_builds.empty())
127 throw error(CL_INVALID_PROGRAM_EXECUTABLE);
128
129 return _builds.begin()->second.binary.syms;
130 }
131
132 unsigned
133 program::kernel_ref_count() const {
134 return _kernel_ref_counter.ref_count();
135 }