mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-03 08:25:34 +00:00
gpu: [compute] pre-transform images before rendering
We're about to change the last stage of the compute pipeline to only accept images, not sampled textures. This change prepares materials for pixel-aligned image copying by pre-rendering images to a texture, applying transforms. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+36
-40
@@ -8,9 +8,7 @@
|
||||
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#ifdef VULKAN
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#endif
|
||||
|
||||
#include "mem.h"
|
||||
#include "setup.h"
|
||||
@@ -25,10 +23,10 @@ layout(set = 0, binding = 1) readonly buffer ConfigBuf {
|
||||
|
||||
layout(rgba8, set = 0, binding = 2) uniform writeonly image2D image;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(set = 0, binding = 3) uniform sampler2D textures[];
|
||||
#if GL_EXT_nonuniform_qualifier
|
||||
layout(rgba8, set = 0, binding = 3) uniform readonly image2D images[];
|
||||
#else
|
||||
layout(set = 0, binding = 3) uniform sampler2D atlas;
|
||||
layout(rgba8, set = 0, binding = 3) uniform readonly image2D images[1];
|
||||
#endif
|
||||
|
||||
#include "ptcl.h"
|
||||
@@ -92,25 +90,6 @@ float[CHUNK] computeArea(vec2 xy, int backdrop, uint tile_ref) {
|
||||
return area;
|
||||
}
|
||||
|
||||
vec4[CHUNK] fillTexture(vec2 xy, CmdSolidTexture cmd_tex) {
|
||||
vec2 uvmin = unpackUnorm2x16(cmd_tex.uv_bounds.x);
|
||||
vec2 uvmax = unpackUnorm2x16(cmd_tex.uv_bounds.y);
|
||||
vec4 rgba[CHUNK];
|
||||
for (uint i = 0; i < CHUNK; i++) {
|
||||
float dy = float(i * CHUNK_DY);
|
||||
vec2 uv = vec2(xy.x, xy.y + dy) + vec2(0.5, 0.5);
|
||||
uv = cmd_tex.mat.xy * uv.x + cmd_tex.mat.zw * uv.y + cmd_tex.translate;
|
||||
uv = clamp(uv, uvmin, uvmax);
|
||||
#ifdef VULKAN
|
||||
vec4 fg_rgba = textureGrad(textures[0], uv, cmd_tex.mat.xy, cmd_tex.mat.zw);
|
||||
#else
|
||||
vec4 fg_rgba = textureGrad(atlas, uv, cmd_tex.mat.xy, cmd_tex.mat.zw);
|
||||
#endif
|
||||
rgba[i] = fg_rgba;
|
||||
}
|
||||
return rgba;
|
||||
}
|
||||
|
||||
vec3 tosRGB(vec3 rgb) {
|
||||
bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308));
|
||||
vec3 below = vec3(12.92)*rgb;
|
||||
@@ -118,17 +97,19 @@ vec3 tosRGB(vec3 rgb) {
|
||||
return mix(below, above, cutoff);
|
||||
}
|
||||
|
||||
vec3 fromsRGB(vec3 srgb) {
|
||||
// Formula from EXT_sRGB.
|
||||
bvec3 cutoff = greaterThanEqual(srgb, vec3(0.04045));
|
||||
vec3 below = srgb/vec3(12.92);
|
||||
vec3 above = pow((srgb + vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
return mix(below, above, cutoff);
|
||||
}
|
||||
|
||||
// unpacksRGB unpacks a color in the sRGB color space to a vec4 in the linear color
|
||||
// space.
|
||||
vec4 unpacksRGB(uint srgba) {
|
||||
vec4 color = unpackUnorm4x8(srgba).wzyx;
|
||||
// Formula from EXT_sRGB.
|
||||
vec3 rgb = color.rgb;
|
||||
bvec3 cutoff = greaterThanEqual(rgb, vec3(0.04045));
|
||||
vec3 below = rgb/vec3(12.92);
|
||||
vec3 above = pow((rgb + vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
rgb = mix(below, above, cutoff);
|
||||
return vec4(rgb, color.a);
|
||||
return vec4(fromsRGB(color.rgb), color.a);
|
||||
}
|
||||
|
||||
// packsRGB packs a color in the linear color space into its 8-bit sRGB equivalent.
|
||||
@@ -137,6 +118,21 @@ uint packsRGB(vec4 rgba) {
|
||||
return packUnorm4x8(rgba.wzyx);
|
||||
}
|
||||
|
||||
vec4[CHUNK] fillImage(uvec2 xy, CmdSolidImage cmd_img) {
|
||||
vec4 rgba[CHUNK];
|
||||
for (uint i = 0; i < CHUNK; i++) {
|
||||
ivec2 uv = ivec2(xy.x, xy.y + i * CHUNK_DY) + cmd_img.offset;
|
||||
#ifdef ENABLE_IMAGE_INDICES
|
||||
vec4 fg_rgba = imageLoad(images[cmd_img.index], uv);
|
||||
#else
|
||||
vec4 fg_rgba = imageLoad(images[0], uv);
|
||||
#endif
|
||||
fg_rgba.rgb = fromsRGB(fg_rgba.rgb);
|
||||
rgba[i] = fg_rgba;
|
||||
}
|
||||
return rgba;
|
||||
}
|
||||
|
||||
void main() {
|
||||
if (mem_error != NO_ERROR) {
|
||||
return;
|
||||
@@ -156,9 +152,9 @@ void main() {
|
||||
Alloc clip_tos = new_alloc(0, 0);
|
||||
for (uint i = 0; i < CHUNK; i++) {
|
||||
rgb[i] = vec3(0.5);
|
||||
#ifdef VULKAN
|
||||
#ifdef ENABLE_IMAGE_INDICES
|
||||
if (xy_uint.x < 1024 && xy_uint.y < 1024) {
|
||||
rgb[i] = texture(textures[gl_WorkGroupID.x / 64], vec2(xy_uint.x, xy_uint.y + CHUNK_DY * i) / 1024.0).rgb;
|
||||
rgb[i] = imageLoad(images[gl_WorkGroupID.x / 64], ivec2(xy_uint.x, xy_uint.y + CHUNK_DY * i)/4).rgb;
|
||||
}
|
||||
#endif
|
||||
mask[i] = 1.0;
|
||||
@@ -212,10 +208,10 @@ void main() {
|
||||
rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * area[k] * fg_rgba.a);
|
||||
}
|
||||
break;
|
||||
case Cmd_FillTexture:
|
||||
CmdFillTexture fill_tex = Cmd_FillTexture_read(cmd_alloc, cmd_ref);
|
||||
area = computeArea(xy, fill_tex.backdrop, fill_tex.tile_ref);
|
||||
vec4 rgba[CHUNK] = fillTexture(xy, CmdSolidTexture(fill_tex.mat, fill_tex.translate, fill_tex.uv_bounds));
|
||||
case Cmd_FillImage:
|
||||
CmdFillImage fill_img = Cmd_FillImage_read(cmd_alloc, cmd_ref);
|
||||
area = computeArea(xy, fill_img.backdrop, fill_img.tile_ref);
|
||||
vec4 rgba[CHUNK] = fillImage(xy_uint, CmdSolidImage(fill_img.index, fill_img.offset));
|
||||
for (uint k = 0; k < CHUNK; k++) {
|
||||
rgb[k] = mix(rgb[k], rgba[k].rgb, mask[k] * area[k] * rgba[k].a);
|
||||
}
|
||||
@@ -275,9 +271,9 @@ void main() {
|
||||
rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * fg_rgba.a);
|
||||
}
|
||||
break;
|
||||
case Cmd_SolidTexture:
|
||||
CmdSolidTexture solid_tex = Cmd_SolidTexture_read(cmd_alloc, cmd_ref);
|
||||
rgba = fillTexture(xy, solid_tex);
|
||||
case Cmd_SolidImage:
|
||||
CmdSolidImage solid_img = Cmd_SolidImage_read(cmd_alloc, cmd_ref);
|
||||
rgba = fillImage(xy_uint, solid_img);
|
||||
for (uint k = 0; k < CHUNK; k++) {
|
||||
rgb[k] = mix(rgb[k], rgba[k].rgb, mask[k] * rgba[k].a);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user