1 | // basisu_opencl.h |
2 | // Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. |
3 | // |
4 | // Note: Undefine or set BASISU_SUPPORT_OPENCL to 0 to completely OpenCL support. |
5 | // |
6 | // Licensed under the Apache License, Version 2.0 (the "License"); |
7 | // you may not use this file except in compliance with the License. |
8 | // You may obtain a copy of the License at |
9 | // |
10 | // http://www.apache.org/licenses/LICENSE-2.0 |
11 | // |
12 | // Unless required by applicable law or agreed to in writing, software |
13 | // distributed under the License is distributed on an "AS IS" BASIS, |
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | // See the License for the specific language governing permissions and |
16 | // limitations under the License. |
17 | #pragma once |
18 | #include "../transcoder/basisu.h" |
19 | #include "basisu_enc.h" |
20 | #include "basisu_etc.h" |
21 | |
22 | namespace basisu |
23 | { |
24 | bool opencl_init(bool force_serialization); |
25 | void opencl_deinit(); |
26 | bool opencl_is_available(); |
27 | |
28 | struct opencl_context; |
29 | |
30 | // Each thread calling OpenCL should have its own opencl_context_ptr. This corresponds to a OpenCL command queue. (Confusingly, we only use a single OpenCL device "context".) |
31 | typedef opencl_context* opencl_context_ptr; |
32 | |
33 | opencl_context_ptr opencl_create_context(); |
34 | void opencl_destroy_context(opencl_context_ptr context); |
35 | |
36 | #pragma pack(push, 1) |
37 | struct cl_pixel_block |
38 | { |
39 | color_rgba m_pixels[16]; // [y*4+x] |
40 | }; |
41 | #pragma pack(pop) |
42 | |
43 | // Must match BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE |
44 | const uint32_t OPENCL_ENCODE_ETC1S_MAX_PERMS = 165; |
45 | |
46 | bool opencl_set_pixel_blocks(opencl_context_ptr pContext, uint32_t total_blocks, const cl_pixel_block* pPixel_blocks); |
47 | |
48 | bool opencl_encode_etc1s_blocks(opencl_context_ptr pContext, etc_block* pOutput_blocks, bool perceptual, uint32_t total_perms); |
49 | |
50 | // opencl_encode_etc1s_pixel_clusters |
51 | |
52 | #pragma pack(push, 1) |
53 | struct cl_pixel_cluster |
54 | { |
55 | uint64_t m_total_pixels; |
56 | uint64_t m_first_pixel_index; |
57 | }; |
58 | #pragma pack(pop) |
59 | |
60 | bool opencl_encode_etc1s_pixel_clusters( |
61 | opencl_context_ptr pContext, |
62 | etc_block* pOutput_blocks, |
63 | uint32_t total_clusters, |
64 | const cl_pixel_cluster *pClusters, |
65 | uint64_t total_pixels, |
66 | const color_rgba *pPixels, |
67 | const uint32_t *pPixel_weights, |
68 | bool perceptual, uint32_t total_perms); |
69 | |
70 | // opencl_refine_endpoint_clusterization |
71 | |
72 | #pragma pack(push, 1) |
73 | struct cl_block_info_struct |
74 | { |
75 | uint16_t m_first_cluster_ofs; |
76 | uint16_t m_num_clusters; |
77 | uint16_t m_cur_cluster_index; |
78 | uint8_t m_cur_cluster_etc_inten; |
79 | }; |
80 | |
81 | struct cl_endpoint_cluster_struct |
82 | { |
83 | color_rgba m_unscaled_color; |
84 | uint8_t m_etc_inten; |
85 | uint16_t m_cluster_index; |
86 | }; |
87 | #pragma pack(pop) |
88 | |
89 | bool opencl_refine_endpoint_clusterization( |
90 | opencl_context_ptr pContext, |
91 | const cl_block_info_struct *pPixel_block_info, |
92 | uint32_t total_clusters, |
93 | const cl_endpoint_cluster_struct *pCluster_info, |
94 | const uint32_t *pSorted_block_indices, |
95 | uint32_t* pOutput_cluster_indices, |
96 | bool perceptual); |
97 | |
98 | // opencl_find_optimal_selector_clusters_for_each_block |
99 | |
100 | #pragma pack(push, 1) |
101 | struct fosc_selector_struct |
102 | { |
103 | uint32_t m_packed_selectors; // 4x4 grid of 2-bit selectors |
104 | }; |
105 | |
106 | struct fosc_block_struct |
107 | { |
108 | color_rgba m_etc_color5_inten; // unscaled 5-bit block color in RGB, alpha has block's intensity index |
109 | uint32_t m_first_selector; // offset into selector table |
110 | uint32_t m_num_selectors; // number of selectors to check |
111 | }; |
112 | |
113 | struct fosc_param_struct |
114 | { |
115 | uint32_t m_total_blocks; |
116 | int m_perceptual; |
117 | }; |
118 | #pragma pack(pop) |
119 | |
120 | bool opencl_find_optimal_selector_clusters_for_each_block( |
121 | opencl_context_ptr pContext, |
122 | const fosc_block_struct* pInput_block_info, // one per block |
123 | uint32_t total_input_selectors, |
124 | const fosc_selector_struct* pInput_selectors, |
125 | const uint32_t* pSelector_cluster_indices, |
126 | uint32_t* pOutput_selector_cluster_indices, // one per block |
127 | bool perceptual); |
128 | |
129 | #pragma pack(push, 1) |
130 | struct ds_param_struct |
131 | { |
132 | uint32_t m_total_blocks; |
133 | int m_perceptual; |
134 | }; |
135 | #pragma pack(pop) |
136 | |
137 | bool opencl_determine_selectors( |
138 | opencl_context_ptr pContext, |
139 | const color_rgba* pInput_etc_color5_and_inten, |
140 | etc_block* pOutput_blocks, |
141 | bool perceptual); |
142 | |
143 | } // namespace basisu |
144 | |