2020-12-12 01:01:48 +11:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense
|
|
|
|
|
2020-05-13 03:53:54 +10:00
|
|
|
// Code auto-generated by piet-gpu-derive
|
|
|
|
|
implement FillImage command and sRGB support
FillImage is like Fill, except that it takes its color from one or
more image atlases.
kernel4 uses a single image for non-Vulkan hosts, and the dynamic sized array
of image descriptors on Vulkan.
A previous version of this commit used textures. I think images are a better
choice for piet-gpu, for several reasons:
- Texture sampling, in particular textureGrad, is slow on lower spec devices
such as Google Pixel. Texture sampling is particularly slow and difficult to
implement for CPU fallbacks.
- Texture sampling need more parameters, in particular the full u,v
transformation matrix, leading to a large increase in the command size. Since
all commands use the same size, that memory penalty is paid by all scenes, not
just scenes with textures.
- It is unlikely that piet-gpu will support every kind of fill for every
client, because each kind must be added to kernel4.
With FillImage, a client will prepare the image(s) in separate shader stages,
sampling and applying transformations and special effects as needed. Textures
that align with the output pixel grid can be used directly, without
pre-processing.
Note that the pre-processing step can run concurrently with the piet-gpu pipeline;
Only the last stage, kernel4, needs the images.
Pre-processing most likely uses fixed function vertex/fragment programs,
which on some GPUs may run in parallel with piet-gpu's compute programs.
While here, fix a few validation errors:
- Explicitly enable EXT_descriptor_indexing, KHR_maintenance3,
KHR_get_physical_device_properties2.
- Specify a vkDescriptorSetVariableDescriptorCountAllocateInfo for
vkAllocateDescriptorSets. Otherwise, variable image2D arrays won't work (but
sampler2D arrays do, at least on my setup).
Updates #38
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-29 08:02:39 +11:00
|
|
|
struct AnnoFillImageRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
struct AnnoColorRef {
|
2020-05-13 03:53:54 +10:00
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2020-11-20 06:53:59 +11:00
|
|
|
struct AnnoClipRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2020-05-13 03:53:54 +10:00
|
|
|
struct AnnotatedRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
implement FillImage command and sRGB support
FillImage is like Fill, except that it takes its color from one or
more image atlases.
kernel4 uses a single image for non-Vulkan hosts, and the dynamic sized array
of image descriptors on Vulkan.
A previous version of this commit used textures. I think images are a better
choice for piet-gpu, for several reasons:
- Texture sampling, in particular textureGrad, is slow on lower spec devices
such as Google Pixel. Texture sampling is particularly slow and difficult to
implement for CPU fallbacks.
- Texture sampling need more parameters, in particular the full u,v
transformation matrix, leading to a large increase in the command size. Since
all commands use the same size, that memory penalty is paid by all scenes, not
just scenes with textures.
- It is unlikely that piet-gpu will support every kind of fill for every
client, because each kind must be added to kernel4.
With FillImage, a client will prepare the image(s) in separate shader stages,
sampling and applying transformations and special effects as needed. Textures
that align with the output pixel grid can be used directly, without
pre-processing.
Note that the pre-processing step can run concurrently with the piet-gpu pipeline;
Only the last stage, kernel4, needs the images.
Pre-processing most likely uses fixed function vertex/fragment programs,
which on some GPUs may run in parallel with piet-gpu's compute programs.
While here, fix a few validation errors:
- Explicitly enable EXT_descriptor_indexing, KHR_maintenance3,
KHR_get_physical_device_properties2.
- Specify a vkDescriptorSetVariableDescriptorCountAllocateInfo for
vkAllocateDescriptorSets. Otherwise, variable image2D arrays won't work (but
sampler2D arrays do, at least on my setup).
Updates #38
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-29 08:02:39 +11:00
|
|
|
struct AnnoFillImage {
|
|
|
|
vec4 bbox;
|
|
|
|
uint index;
|
|
|
|
ivec2 offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define AnnoFillImage_size 24
|
|
|
|
|
|
|
|
AnnoFillImageRef AnnoFillImage_index(AnnoFillImageRef ref, uint index) {
|
|
|
|
return AnnoFillImageRef(ref.offset + index * AnnoFillImage_size);
|
|
|
|
}
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
struct AnnoColor {
|
2020-05-13 03:53:54 +10:00
|
|
|
vec4 bbox;
|
2020-11-21 04:26:02 +11:00
|
|
|
uint rgba_color;
|
2020-05-13 03:53:54 +10:00
|
|
|
float linewidth;
|
|
|
|
};
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
#define AnnoColor_size 24
|
2020-05-13 03:53:54 +10:00
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
AnnoColorRef AnnoColor_index(AnnoColorRef ref, uint index) {
|
|
|
|
return AnnoColorRef(ref.offset + index * AnnoColor_size);
|
2020-05-13 03:53:54 +10:00
|
|
|
}
|
|
|
|
|
2020-11-20 06:53:59 +11:00
|
|
|
struct AnnoClip {
|
|
|
|
vec4 bbox;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define AnnoClip_size 16
|
|
|
|
|
|
|
|
AnnoClipRef AnnoClip_index(AnnoClipRef ref, uint index) {
|
|
|
|
return AnnoClipRef(ref.offset + index * AnnoClip_size);
|
|
|
|
}
|
|
|
|
|
2020-05-13 03:53:54 +10:00
|
|
|
#define Annotated_Nop 0
|
2021-03-17 22:02:41 +11:00
|
|
|
#define Annotated_Color 1
|
|
|
|
#define Annotated_FillImage 2
|
|
|
|
#define Annotated_BeginClip 3
|
|
|
|
#define Annotated_EndClip 4
|
2020-09-21 18:24:18 +10:00
|
|
|
#define Annotated_size 28
|
2020-05-13 03:53:54 +10:00
|
|
|
|
|
|
|
AnnotatedRef Annotated_index(AnnotatedRef ref, uint index) {
|
|
|
|
return AnnotatedRef(ref.offset + index * Annotated_size);
|
|
|
|
}
|
|
|
|
|
2021-03-17 20:51:38 +11:00
|
|
|
struct AnnotatedTag {
|
|
|
|
uint tag;
|
|
|
|
uint flags;
|
|
|
|
};
|
|
|
|
|
implement FillImage command and sRGB support
FillImage is like Fill, except that it takes its color from one or
more image atlases.
kernel4 uses a single image for non-Vulkan hosts, and the dynamic sized array
of image descriptors on Vulkan.
A previous version of this commit used textures. I think images are a better
choice for piet-gpu, for several reasons:
- Texture sampling, in particular textureGrad, is slow on lower spec devices
such as Google Pixel. Texture sampling is particularly slow and difficult to
implement for CPU fallbacks.
- Texture sampling need more parameters, in particular the full u,v
transformation matrix, leading to a large increase in the command size. Since
all commands use the same size, that memory penalty is paid by all scenes, not
just scenes with textures.
- It is unlikely that piet-gpu will support every kind of fill for every
client, because each kind must be added to kernel4.
With FillImage, a client will prepare the image(s) in separate shader stages,
sampling and applying transformations and special effects as needed. Textures
that align with the output pixel grid can be used directly, without
pre-processing.
Note that the pre-processing step can run concurrently with the piet-gpu pipeline;
Only the last stage, kernel4, needs the images.
Pre-processing most likely uses fixed function vertex/fragment programs,
which on some GPUs may run in parallel with piet-gpu's compute programs.
While here, fix a few validation errors:
- Explicitly enable EXT_descriptor_indexing, KHR_maintenance3,
KHR_get_physical_device_properties2.
- Specify a vkDescriptorSetVariableDescriptorCountAllocateInfo for
vkAllocateDescriptorSets. Otherwise, variable image2D arrays won't work (but
sampler2D arrays do, at least on my setup).
Updates #38
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-29 08:02:39 +11:00
|
|
|
AnnoFillImage AnnoFillImage_read(Alloc a, AnnoFillImageRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = read_mem(a, ix + 0);
|
|
|
|
uint raw1 = read_mem(a, ix + 1);
|
|
|
|
uint raw2 = read_mem(a, ix + 2);
|
|
|
|
uint raw3 = read_mem(a, ix + 3);
|
|
|
|
uint raw4 = read_mem(a, ix + 4);
|
|
|
|
uint raw5 = read_mem(a, ix + 5);
|
|
|
|
AnnoFillImage s;
|
|
|
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
s.index = raw4;
|
|
|
|
s.offset = ivec2(int(raw5 << 16) >> 16, int(raw5) >> 16);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AnnoFillImage_write(Alloc a, AnnoFillImageRef ref, AnnoFillImage s) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
|
|
|
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
|
|
|
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
|
|
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
|
|
|
write_mem(a, ix + 4, s.index);
|
|
|
|
write_mem(a, ix + 5, (uint(s.offset.x) & 0xffff) | (uint(s.offset.y) << 16));
|
|
|
|
}
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
AnnoColor AnnoColor_read(Alloc a, AnnoColorRef ref) {
|
2020-05-13 03:53:54 +10:00
|
|
|
uint ix = ref.offset >> 2;
|
2020-12-24 22:00:53 +11:00
|
|
|
uint raw0 = read_mem(a, ix + 0);
|
|
|
|
uint raw1 = read_mem(a, ix + 1);
|
|
|
|
uint raw2 = read_mem(a, ix + 2);
|
|
|
|
uint raw3 = read_mem(a, ix + 3);
|
|
|
|
uint raw4 = read_mem(a, ix + 4);
|
|
|
|
uint raw5 = read_mem(a, ix + 5);
|
2021-03-17 22:02:41 +11:00
|
|
|
AnnoColor s;
|
2020-11-21 04:26:02 +11:00
|
|
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
s.rgba_color = raw4;
|
2020-05-13 03:53:54 +10:00
|
|
|
s.linewidth = uintBitsToFloat(raw5);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
void AnnoColor_write(Alloc a, AnnoColorRef ref, AnnoColor s) {
|
2020-05-13 03:53:54 +10:00
|
|
|
uint ix = ref.offset >> 2;
|
2020-12-24 22:00:53 +11:00
|
|
|
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
|
|
|
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
|
|
|
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
|
|
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
|
|
|
write_mem(a, ix + 4, s.rgba_color);
|
|
|
|
write_mem(a, ix + 5, floatBitsToUint(s.linewidth));
|
2020-05-13 03:53:54 +10:00
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
AnnoClip AnnoClip_read(Alloc a, AnnoClipRef ref) {
|
2020-11-20 06:53:59 +11:00
|
|
|
uint ix = ref.offset >> 2;
|
2020-12-24 22:00:53 +11:00
|
|
|
uint raw0 = read_mem(a, ix + 0);
|
|
|
|
uint raw1 = read_mem(a, ix + 1);
|
|
|
|
uint raw2 = read_mem(a, ix + 2);
|
|
|
|
uint raw3 = read_mem(a, ix + 3);
|
2020-11-20 06:53:59 +11:00
|
|
|
AnnoClip s;
|
|
|
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
void AnnoClip_write(Alloc a, AnnoClipRef ref, AnnoClip s) {
|
2020-11-20 06:53:59 +11:00
|
|
|
uint ix = ref.offset >> 2;
|
2020-12-24 22:00:53 +11:00
|
|
|
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
|
|
|
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
|
|
|
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
|
|
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2021-03-17 20:51:38 +11:00
|
|
|
AnnotatedTag Annotated_tag(Alloc a, AnnotatedRef ref) {
|
|
|
|
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
|
|
|
return AnnotatedTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
2020-05-13 03:53:54 +10:00
|
|
|
}
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
AnnoColor Annotated_Color_read(Alloc a, AnnotatedRef ref) {
|
|
|
|
return AnnoColor_read(a, AnnoColorRef(ref.offset + 4));
|
2020-05-13 03:53:54 +10:00
|
|
|
}
|
|
|
|
|
implement FillImage command and sRGB support
FillImage is like Fill, except that it takes its color from one or
more image atlases.
kernel4 uses a single image for non-Vulkan hosts, and the dynamic sized array
of image descriptors on Vulkan.
A previous version of this commit used textures. I think images are a better
choice for piet-gpu, for several reasons:
- Texture sampling, in particular textureGrad, is slow on lower spec devices
such as Google Pixel. Texture sampling is particularly slow and difficult to
implement for CPU fallbacks.
- Texture sampling need more parameters, in particular the full u,v
transformation matrix, leading to a large increase in the command size. Since
all commands use the same size, that memory penalty is paid by all scenes, not
just scenes with textures.
- It is unlikely that piet-gpu will support every kind of fill for every
client, because each kind must be added to kernel4.
With FillImage, a client will prepare the image(s) in separate shader stages,
sampling and applying transformations and special effects as needed. Textures
that align with the output pixel grid can be used directly, without
pre-processing.
Note that the pre-processing step can run concurrently with the piet-gpu pipeline;
Only the last stage, kernel4, needs the images.
Pre-processing most likely uses fixed function vertex/fragment programs,
which on some GPUs may run in parallel with piet-gpu's compute programs.
While here, fix a few validation errors:
- Explicitly enable EXT_descriptor_indexing, KHR_maintenance3,
KHR_get_physical_device_properties2.
- Specify a vkDescriptorSetVariableDescriptorCountAllocateInfo for
vkAllocateDescriptorSets. Otherwise, variable image2D arrays won't work (but
sampler2D arrays do, at least on my setup).
Updates #38
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-29 08:02:39 +11:00
|
|
|
AnnoFillImage Annotated_FillImage_read(Alloc a, AnnotatedRef ref) {
|
|
|
|
return AnnoFillImage_read(a, AnnoFillImageRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
AnnoClip Annotated_BeginClip_read(Alloc a, AnnotatedRef ref) {
|
|
|
|
return AnnoClip_read(a, AnnoClipRef(ref.offset + 4));
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
AnnoClip Annotated_EndClip_read(Alloc a, AnnotatedRef ref) {
|
|
|
|
return AnnoClip_read(a, AnnoClipRef(ref.offset + 4));
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
void Annotated_Nop_write(Alloc a, AnnotatedRef ref) {
|
|
|
|
write_mem(a, ref.offset >> 2, Annotated_Nop);
|
2020-05-13 03:53:54 +10:00
|
|
|
}
|
|
|
|
|
2021-03-17 22:02:41 +11:00
|
|
|
void Annotated_Color_write(Alloc a, AnnotatedRef ref, uint flags, AnnoColor s) {
|
|
|
|
write_mem(a, ref.offset >> 2, (flags << 16) | Annotated_Color);
|
|
|
|
AnnoColor_write(a, AnnoColorRef(ref.offset + 4), s);
|
2020-05-13 03:53:54 +10:00
|
|
|
}
|
|
|
|
|
implement FillImage command and sRGB support
FillImage is like Fill, except that it takes its color from one or
more image atlases.
kernel4 uses a single image for non-Vulkan hosts, and the dynamic sized array
of image descriptors on Vulkan.
A previous version of this commit used textures. I think images are a better
choice for piet-gpu, for several reasons:
- Texture sampling, in particular textureGrad, is slow on lower spec devices
such as Google Pixel. Texture sampling is particularly slow and difficult to
implement for CPU fallbacks.
- Texture sampling need more parameters, in particular the full u,v
transformation matrix, leading to a large increase in the command size. Since
all commands use the same size, that memory penalty is paid by all scenes, not
just scenes with textures.
- It is unlikely that piet-gpu will support every kind of fill for every
client, because each kind must be added to kernel4.
With FillImage, a client will prepare the image(s) in separate shader stages,
sampling and applying transformations and special effects as needed. Textures
that align with the output pixel grid can be used directly, without
pre-processing.
Note that the pre-processing step can run concurrently with the piet-gpu pipeline;
Only the last stage, kernel4, needs the images.
Pre-processing most likely uses fixed function vertex/fragment programs,
which on some GPUs may run in parallel with piet-gpu's compute programs.
While here, fix a few validation errors:
- Explicitly enable EXT_descriptor_indexing, KHR_maintenance3,
KHR_get_physical_device_properties2.
- Specify a vkDescriptorSetVariableDescriptorCountAllocateInfo for
vkAllocateDescriptorSets. Otherwise, variable image2D arrays won't work (but
sampler2D arrays do, at least on my setup).
Updates #38
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-29 08:02:39 +11:00
|
|
|
void Annotated_FillImage_write(Alloc a, AnnotatedRef ref, AnnoFillImage s) {
|
|
|
|
write_mem(a, ref.offset >> 2, Annotated_FillImage);
|
|
|
|
AnnoFillImage_write(a, AnnoFillImageRef(ref.offset + 4), s);
|
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
void Annotated_BeginClip_write(Alloc a, AnnotatedRef ref, AnnoClip s) {
|
|
|
|
write_mem(a, ref.offset >> 2, Annotated_BeginClip);
|
|
|
|
AnnoClip_write(a, AnnoClipRef(ref.offset + 4), s);
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2020-12-24 22:00:53 +11:00
|
|
|
void Annotated_EndClip_write(Alloc a, AnnotatedRef ref, AnnoClip s) {
|
|
|
|
write_mem(a, ref.offset >> 2, Annotated_EndClip);
|
|
|
|
AnnoClip_write(a, AnnoClipRef(ref.offset + 4), s);
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|