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/device.hpp"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clover;
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace {
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   template<typename T>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   std::vector<T>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   get_compute_param(pipe_screen *pipe, pipe_compute_cap cap) {
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int sz = pipe->get_compute_param(pipe, cap, NULL);
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      std::vector<T> v(sz / sizeof(T));
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->get_compute_param(pipe, cap, &v.front());
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return v;
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::_cl_device_id(pipe_loader_device *ldev) : ldev(ldev) {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = pipe_loader_create_screen(ldev, PIPE_SEARCH_DIR);
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pipe || !pipe->get_param(pipe, PIPE_CAP_COMPUTE))
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      throw error(CL_INVALID_DEVICE);
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::_cl_device_id(_cl_device_id &&dev) : pipe(dev.pipe), ldev(dev.ldev) {
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dev.ldev = NULL;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dev.pipe = NULL;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::~_cl_device_id() {
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pipe)
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->destroy(pipe);
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ldev)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_loader_release(&ldev, 1);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_device_type
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::type() const {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ldev->type) {
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_LOADER_DEVICE_SOFTWARE:
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CL_DEVICE_TYPE_CPU;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_LOADER_DEVICE_PCI:
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CL_DEVICE_TYPE_GPU;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_uint
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::vendor_id() const {
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ldev->type) {
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_LOADER_DEVICE_SOFTWARE:
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_LOADER_DEVICE_PCI:
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ldev->u.pci.vendor_id;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsize_t
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_images_read() const {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return PIPE_MAX_SHADER_RESOURCES;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsize_t
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_images_write() const {
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return PIPE_MAX_SHADER_RESOURCES;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_uint
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_image_levels_2d() const {
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_uint
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_image_levels_3d() const {
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS);
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_uint
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_samplers() const {
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_ulong
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_mem_global() const {
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return get_compute_param<uint64_t>(pipe,
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0];
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_ulong
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_mem_local() const {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return get_compute_param<uint64_t>(pipe,
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0];
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_ulong
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_mem_input() const {
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return get_compute_param<uint64_t>(pipe,
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      PIPE_COMPUTE_CAP_MAX_INPUT_SIZE)[0];
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_ulong
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_const_buffer_size() const {
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 PIPE_SHADER_CAP_MAX_CONSTS) * 16;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcl_uint
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_const_buffers() const {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 PIPE_SHADER_CAP_MAX_CONST_BUFFERS);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsize_t
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_threads_per_block() const {
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return get_compute_param<uint64_t>(
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe, PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK)[0];
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::vector<size_t>
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::max_block_size() const {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   auto v = get_compute_param<uint64_t>(pipe, PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return { v.begin(), v.end() };
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::string
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::device_name() const {
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_name(pipe);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::string
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::vendor_name() const {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pipe->get_vendor(pipe);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum pipe_shader_ir
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::ir_format() const {
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (enum pipe_shader_ir) pipe->get_shader_param(pipe,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  PIPE_SHADER_COMPUTE,
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  PIPE_SHADER_CAP_PREFERRED_IR);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::string
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_cl_device_id::ir_target() const {
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   std::vector<char> target = get_compute_param<char>(pipe,
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    PIPE_COMPUTE_CAP_IR_TARGET);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return { target.data() };
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdevice_registry::device_registry() {
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int n = pipe_loader_probe(NULL, 0);
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   std::vector<pipe_loader_device *> ldevs(n);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_loader_probe(&ldevs.front(), n);
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (pipe_loader_device *ldev : ldevs) {
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      try {
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         devs.emplace_back(ldev);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } catch (error &) {}
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
189