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
22namespace 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