83 lines
2.9 KiB
Plaintext
83 lines
2.9 KiB
Plaintext
#version 450
|
|
/* Copyright (c) 2020-2021, Holochip
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 the "License";
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
layout(local_size_x = 8, local_size_y = 8) in;
|
|
|
|
layout(binding = 0, rg8ui) uniform readonly uimage2D input_frequency;
|
|
layout(binding = 1, r8ui) uniform writeonly uimage2D output_sampling_rate;
|
|
|
|
layout(binding = 2) buffer FrequencyInformation
|
|
{
|
|
uvec4 settings; // {frame_width, frame_height, output_width, output_height}
|
|
uvec4 frequency_information; // { max_rate_x, max_rate_y, n_rates, ...}
|
|
uvec2 rates[];
|
|
}
|
|
params;
|
|
|
|
void main()
|
|
{
|
|
const uint x0 = gl_GlobalInvocationID.x,
|
|
y0 = gl_GlobalInvocationID.y,
|
|
frame_width = params.settings[0],
|
|
frame_height = params.settings[1],
|
|
output_width = params.settings[2],
|
|
output_height = params.settings[3];
|
|
|
|
const uint delta_x = max(1, uint(round(float(frame_width) / float(output_width)))),
|
|
delta_y = max(1, uint(round(float(frame_height) / float(output_height))));
|
|
if (x0 >= output_width || y0 >= output_height)
|
|
{
|
|
return;
|
|
}
|
|
|
|
vec2 max_freqs = vec2(0, 0);
|
|
for (uint i = 0; i < delta_x; ++i)
|
|
{
|
|
for (uint j = 0; j < delta_y; ++j)
|
|
{
|
|
ivec2 coord = ivec2(delta_x * x0 + i, delta_y * y0 + j);
|
|
vec2 freq = vec2(imageLoad(input_frequency, coord)) / 255.f;
|
|
max_freqs = max(max_freqs, freq);
|
|
}
|
|
}
|
|
|
|
vec2 freqs = min(1.25 * sqrt(max_freqs), vec2(1, 1));
|
|
|
|
const float min_rate = 1,
|
|
max_rate = max(params.frequency_information.x, params.frequency_information.y);
|
|
|
|
const vec2 optimal_rate = freqs * vec2(min_rate, min_rate) + (1 - freqs) * vec2(max_rate, max_rate); //round(frequency * min_rate + (1 - frequency) * max_rate);
|
|
|
|
const uint n_rates = params.frequency_information.z;
|
|
uint optimal_rate_index = 0;
|
|
float current_cost = 1 + 2 * max_rate * max_rate;
|
|
for (uint i = 0; i < n_rates; ++i)
|
|
{
|
|
uvec2 rate = params.rates[i];
|
|
float cost = (rate.x - optimal_rate.x) * (rate.x - optimal_rate.x) + (rate.y - optimal_rate.y) * (rate.y - optimal_rate.y);
|
|
if (cost < current_cost)
|
|
{
|
|
current_cost = cost;
|
|
optimal_rate_index = i;
|
|
}
|
|
}
|
|
|
|
uint optimal_rate_x = params.rates[optimal_rate_index].x, optimal_rate_y = params.rates[optimal_rate_index].y;
|
|
uint rate_code = uint(optimal_rate_y >> 1) | ((optimal_rate_x << 1) & 12);
|
|
imageStore(output_sampling_rate, ivec2(x0, y0), uvec4(rate_code));
|
|
} |