Files
Jonathan Thomas 1414a4afeb - Added an optional vulkan-benchmark executable without changing normal libopenshot builds.
- Built a small benchmark matrix to compare CPU and GPU pipelines on the same video.
- Added --row so each path can run by itself for debugging and stable testing.
- Switched the benchmark to a more realistic preview-style workload instead of full-size-only transforms.
- Added PNG dump support so rows can save sample output frames for visual verification.
- The custom Vulkan path now does real preview scaling and alpha overlay, and can stay fully on-GPU for Vulkan decode.
- Added runtime detection for VAAPI, CUDA, and Vulkan, so unsupported rows skip cleanly on different systems.
- Added CUDA benchmark rows for NVIDIA systems, while keeping VAAPI and Vulkan conditional at runtime.
2026-03-25 13:13:52 -05:00

62 lines
2.0 KiB
Plaintext

#version 450
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout(binding = 0) uniform sampler2D video_y;
layout(binding = 1) uniform sampler2D video_u;
layout(binding = 2) uniform sampler2D video_v;
layout(binding = 3) uniform sampler2D overlay_tex;
layout(binding = 4, rgba8) uniform writeonly image2D output_img;
layout(push_constant) uniform PushConstants {
ivec2 output_size;
ivec2 overlay_origin;
ivec2 overlay_size;
int chroma_mode;
} push_constants;
vec3 yuv420p_to_rgb(vec2 uv) {
if (push_constants.chroma_mode == 2) {
return texture(video_y, uv).rgb;
}
float y = texture(video_y, uv).r;
float u;
float v;
if (push_constants.chroma_mode == 1) {
vec2 uv_pair = texture(video_u, uv).rg;
u = uv_pair.r - 0.5;
v = uv_pair.g - 0.5;
} else {
u = texture(video_u, uv).r - 0.5;
v = texture(video_v, uv).r - 0.5;
}
float yy = 1.16438356 * max(y - 0.0625, 0.0);
float r = yy + 1.79274107 * v;
float g = yy - 0.21324861 * u - 0.53290933 * v;
float b = yy + 2.11240179 * u;
return clamp(vec3(r, g, b), 0.0, 1.0);
}
void main() {
ivec2 pixel = ivec2(gl_GlobalInvocationID.xy);
if (pixel.x >= push_constants.output_size.x || pixel.y >= push_constants.output_size.y) {
return;
}
vec2 uv = (vec2(pixel) + vec2(0.5)) / vec2(push_constants.output_size);
vec3 base_rgb = yuv420p_to_rgb(uv);
vec4 out_color = vec4(base_rgb, 1.0);
ivec2 overlay_pixel = pixel - push_constants.overlay_origin;
if (overlay_pixel.x >= 0 && overlay_pixel.y >= 0 &&
overlay_pixel.x < push_constants.overlay_size.x &&
overlay_pixel.y < push_constants.overlay_size.y) {
vec2 overlay_uv = (vec2(overlay_pixel) + vec2(0.5)) / vec2(push_constants.overlay_size);
vec4 overlay = texture(overlay_tex, overlay_uv);
out_color.rgb = mix(out_color.rgb, overlay.rgb, overlay.a);
}
imageStore(output_img, pixel, out_color);
}