clover: Add initial implementation of clCompileProgram for CL 1.2.
[mesa.git] / src / gallium / state_trackers / clover / core / program.cpp
index 5ac9f93480eaad84e3c540bd4fbde0ee94dd7e4f..8553ca7ec96c37104597ce2c7372e1787e89f100 100644 (file)
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
-// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
 //
 
 #include "core/program.hpp"
-#include "core/compiler.hpp"
 
 using namespace clover;
 
-_cl_program::_cl_program(clover::context &ctx,
-                         const std::string &source) :
-   ctx(ctx), __source(source) {
+program::program(clover::context &ctx, const std::string &source) :
+   has_source(true), context(ctx), _source(source), _kernel_ref_counter(0) {
 }
 
-_cl_program::_cl_program(clover::context &ctx,
-                         const std::vector<clover::device *> &devs,
-                         const std::vector<clover::module> &binaries) :
-   ctx(ctx) {
-   for_each([&](clover::device *dev, const clover::module &bin) {
-         __binaries.insert({ dev, bin });
+program::program(clover::context &ctx,
+                 const ref_vector<device> &devs,
+                 const std::vector<module> &binaries) :
+   has_source(false), context(ctx),
+   _devices(devs), _kernel_ref_counter(0) {
+   for_each([&](device &dev, const module &bin) {
+         _binaries.insert({ &dev, bin });
       },
-      devs.begin(), devs.end(), binaries.begin());
+      devs, binaries);
 }
 
 void
-_cl_program::build(const std::vector<clover::device *> &devs) {
-   __binaries.clear();
-   __logs.clear();
-
-   for (auto dev : devs) {
-      try {
-         auto module = (dev->ir_target() == "tgsi" ?
-                        compile_program_tgsi(__source, dev->ir_target()) :
-                        compile_program_llvm(__source, dev->ir_target()));
-         __binaries.insert({ dev, module });
-
-      } catch (build_error &e) {
-         __logs.insert({ dev, e.what() });
-         throw error(CL_BUILD_PROGRAM_FAILURE);
+program::build(const ref_vector<device> &devs, const char *opts,
+               const header_map &headers) {
+   if (has_source) {
+      _devices = devs;
+
+      for (auto &dev : devs) {
+         _binaries.erase(&dev);
+         _logs.erase(&dev);
+         _opts.erase(&dev);
+
+         _opts.insert({ &dev, opts });
+
+         compat::string log;
+
+         try {
+            auto module = (dev.ir_format() == PIPE_SHADER_IR_TGSI ?
+                           compile_program_tgsi(_source) :
+                           compile_program_llvm(_source, headers,
+                                                dev.ir_format(),
+                                                dev.ir_target(), build_opts(dev),
+                                                log));
+            _binaries.insert({ &dev, module });
+            _logs.insert({ &dev, log });
+         } catch (const build_error &) {
+            _logs.insert({ &dev, log });
+            throw;
+         }
       }
    }
 }
 
 const std::string &
-_cl_program::source() const {
-   return __source;
+program::source() const {
+   return _source;
+}
+
+program::device_range
+program::devices() const {
+   return map(evals(), _devices);
 }
 
-const std::map<clover::device *, clover::module> &
-_cl_program::binaries() const {
-   return __binaries;
+const module &
+program::binary(const device &dev) const {
+   return _binaries.find(&dev)->second;
 }
 
 cl_build_status
-_cl_program::build_status(clover::device *dev) const {
-   return __binaries.count(dev) ? CL_BUILD_SUCCESS : CL_BUILD_NONE;
+program::build_status(const device &dev) const {
+   if (_binaries.count(&dev))
+      return CL_BUILD_SUCCESS;
+   else
+      return CL_BUILD_NONE;
 }
 
 std::string
-_cl_program::build_opts(clover::device *dev) const {
-   return {};
+program::build_opts(const device &dev) const {
+   return _opts.count(&dev) ? _opts.find(&dev)->second : "";
 }
 
 std::string
-_cl_program::build_log(clover::device *dev) const {
-   return __logs.count(dev) ? __logs.find(dev)->second : "";
+program::build_log(const device &dev) const {
+   return _logs.count(&dev) ? _logs.find(&dev)->second : "";
+}
+
+const compat::vector<module::symbol> &
+program::symbols() const {
+   if (_binaries.empty())
+      throw error(CL_INVALID_PROGRAM_EXECUTABLE);
+
+   return _binaries.begin()->second.syms;
+}
+
+unsigned
+program::kernel_ref_count() const {
+   return _kernel_ref_counter.ref_count();
 }