// Copyright 2021-2023, Collabora Ltd. // Author: Jakob Bornecrantz // SPDX-License-Identifier: BSL-1.0 #version 460 #extension GL_GOOGLE_include_directive : require #include "srgb.inc.glsl" layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; layout(set = 0, binding = 0) uniform sampler2D source; layout(set = 0, binding = 1, rgba8) uniform writeonly restrict image2D target; layout(push_constant) uniform Config { vec4 src_rect; ivec4 target_view; } push; vec2 position_to_uv(ivec2 extent, uint ix, uint iy) { // Turn the index into floating point. vec2 xy = vec2(float(ix), float(iy)); // The inverse of the extent of the target image is the pixel size in [0 .. 1] space. vec2 extent_pixel_size = vec2(1.0 / float(extent.x), 1.0 / float(extent.y)); // Per-target pixel we move the size of the pixels. vec2 uv = xy * extent_pixel_size; // Emulate a triangle sample position by offset half target pixel size. uv = uv + extent_pixel_size / 2.0; // Transform with the normalized sample rect. uv = push.src_rect.xy + (uv * push.src_rect.zw); return uv; } void main() { uint ix = gl_GlobalInvocationID.x; uint iy = gl_GlobalInvocationID.y; ivec2 offset = ivec2(push.target_view.xy); ivec2 extent = ivec2(push.target_view.zw); if (ix >= extent.x || iy >= extent.y) { return; } // Get the UV we should sample from. vec2 uv = position_to_uv(extent, ix, iy); // Do the sample. vec4 rgba = texture(source, uv); // Do colour correction here since there are no automatic conversion in hardware available. rgba = vec4(from_linear_to_srgb(rgba.rgb), rgba.a); // And finally write out. imageStore(target, ivec2(offset.x + ix, offset.y + iy), rgba); }