2020-12-12 01:01:48 +11:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense
|
|
|
|
|
2020-04-17 11:14:09 +10:00
|
|
|
// Code auto-generated by piet-gpu-derive
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
struct LineSegRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct QuadSegRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CubicSegRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
struct FillColorRef {
|
2020-05-12 13:01:06 +10:00
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2021-06-24 04:50:51 +10:00
|
|
|
struct FillLinGradientRef {
|
|
|
|
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 FillImageRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
struct SetLineWidthRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TransformRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
struct ClipRef {
|
2020-11-20 06:53:59 +11:00
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2021-03-19 23:49:47 +11:00
|
|
|
struct SetFillModeRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
struct ElementRef {
|
|
|
|
uint offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LineSeg {
|
|
|
|
vec2 p0;
|
|
|
|
vec2 p1;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define LineSeg_size 16
|
|
|
|
|
|
|
|
LineSegRef LineSeg_index(LineSegRef ref, uint index) {
|
|
|
|
return LineSegRef(ref.offset + index * LineSeg_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct QuadSeg {
|
|
|
|
vec2 p0;
|
|
|
|
vec2 p1;
|
|
|
|
vec2 p2;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define QuadSeg_size 24
|
|
|
|
|
|
|
|
QuadSegRef QuadSeg_index(QuadSegRef ref, uint index) {
|
|
|
|
return QuadSegRef(ref.offset + index * QuadSeg_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CubicSeg {
|
|
|
|
vec2 p0;
|
|
|
|
vec2 p1;
|
|
|
|
vec2 p2;
|
|
|
|
vec2 p3;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define CubicSeg_size 32
|
|
|
|
|
|
|
|
CubicSegRef CubicSeg_index(CubicSegRef ref, uint index) {
|
|
|
|
return CubicSegRef(ref.offset + index * CubicSeg_size);
|
|
|
|
}
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
struct FillColor {
|
2020-05-12 13:01:06 +10:00
|
|
|
uint rgba_color;
|
|
|
|
};
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
#define FillColor_size 4
|
2020-05-12 13:01:06 +10:00
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
FillColorRef FillColor_index(FillColorRef ref, uint index) {
|
|
|
|
return FillColorRef(ref.offset + index * FillColor_size);
|
2020-05-12 13:01:06 +10:00
|
|
|
}
|
|
|
|
|
2021-06-24 04:50:51 +10:00
|
|
|
struct FillLinGradient {
|
|
|
|
uint index;
|
|
|
|
vec2 p0;
|
|
|
|
vec2 p1;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define FillLinGradient_size 20
|
|
|
|
|
|
|
|
FillLinGradientRef FillLinGradient_index(FillLinGradientRef ref, uint index) {
|
|
|
|
return FillLinGradientRef(ref.offset + index * FillLinGradient_size);
|
|
|
|
}
|
|
|
|
|
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 FillImage {
|
|
|
|
uint index;
|
|
|
|
ivec2 offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define FillImage_size 8
|
|
|
|
|
|
|
|
FillImageRef FillImage_index(FillImageRef ref, uint index) {
|
|
|
|
return FillImageRef(ref.offset + index * FillImage_size);
|
|
|
|
}
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
struct SetLineWidth {
|
|
|
|
float width;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define SetLineWidth_size 4
|
|
|
|
|
|
|
|
SetLineWidthRef SetLineWidth_index(SetLineWidthRef ref, uint index) {
|
|
|
|
return SetLineWidthRef(ref.offset + index * SetLineWidth_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Transform {
|
|
|
|
vec4 mat;
|
|
|
|
vec2 translate;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define Transform_size 24
|
|
|
|
|
|
|
|
TransformRef Transform_index(TransformRef ref, uint index) {
|
|
|
|
return TransformRef(ref.offset + index * Transform_size);
|
|
|
|
}
|
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
struct Clip {
|
2020-11-20 06:53:59 +11:00
|
|
|
vec4 bbox;
|
|
|
|
};
|
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
#define Clip_size 16
|
2020-11-20 06:53:59 +11:00
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
ClipRef Clip_index(ClipRef ref, uint index) {
|
|
|
|
return ClipRef(ref.offset + index * Clip_size);
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2021-03-19 23:49:47 +11:00
|
|
|
struct SetFillMode {
|
|
|
|
uint fill_mode;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define SetFillMode_size 4
|
|
|
|
|
|
|
|
SetFillModeRef SetFillMode_index(SetFillModeRef ref, uint index) {
|
|
|
|
return SetFillModeRef(ref.offset + index * SetFillMode_size);
|
|
|
|
}
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
#define Element_Nop 0
|
2021-03-17 21:08:28 +11:00
|
|
|
#define Element_Line 1
|
|
|
|
#define Element_Quad 2
|
|
|
|
#define Element_Cubic 3
|
|
|
|
#define Element_FillColor 4
|
2021-06-24 04:50:51 +10:00
|
|
|
#define Element_FillLinGradient 5
|
|
|
|
#define Element_FillImage 6
|
|
|
|
#define Element_SetLineWidth 7
|
|
|
|
#define Element_Transform 8
|
|
|
|
#define Element_BeginClip 9
|
|
|
|
#define Element_EndClip 10
|
|
|
|
#define Element_SetFillMode 11
|
2020-05-12 13:01:06 +10:00
|
|
|
#define Element_size 36
|
|
|
|
|
|
|
|
ElementRef Element_index(ElementRef ref, uint index) {
|
|
|
|
return ElementRef(ref.offset + index * Element_size);
|
|
|
|
}
|
|
|
|
|
2021-03-17 20:51:38 +11:00
|
|
|
struct ElementTag {
|
|
|
|
uint tag;
|
|
|
|
uint flags;
|
|
|
|
};
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
LineSeg LineSeg_read(LineSegRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
uint raw2 = scene[ix + 2];
|
|
|
|
uint raw3 = scene[ix + 3];
|
|
|
|
LineSeg s;
|
|
|
|
s.p0 = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
|
|
|
s.p1 = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
QuadSeg QuadSeg_read(QuadSegRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
uint raw2 = scene[ix + 2];
|
|
|
|
uint raw3 = scene[ix + 3];
|
|
|
|
uint raw4 = scene[ix + 4];
|
|
|
|
uint raw5 = scene[ix + 5];
|
|
|
|
QuadSeg s;
|
|
|
|
s.p0 = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
|
|
|
s.p1 = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
s.p2 = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
CubicSeg CubicSeg_read(CubicSegRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
uint raw2 = scene[ix + 2];
|
|
|
|
uint raw3 = scene[ix + 3];
|
|
|
|
uint raw4 = scene[ix + 4];
|
|
|
|
uint raw5 = scene[ix + 5];
|
|
|
|
uint raw6 = scene[ix + 6];
|
|
|
|
uint raw7 = scene[ix + 7];
|
|
|
|
CubicSeg s;
|
|
|
|
s.p0 = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
|
|
|
s.p1 = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
s.p2 = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5));
|
|
|
|
s.p3 = vec2(uintBitsToFloat(raw6), uintBitsToFloat(raw7));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
FillColor FillColor_read(FillColorRef ref) {
|
2020-05-12 13:01:06 +10:00
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
2021-03-17 21:08:28 +11:00
|
|
|
FillColor s;
|
2020-05-12 13:01:06 +10:00
|
|
|
s.rgba_color = raw0;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-06-24 04:50:51 +10:00
|
|
|
FillLinGradient FillLinGradient_read(FillLinGradientRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
uint raw2 = scene[ix + 2];
|
|
|
|
uint raw3 = scene[ix + 3];
|
|
|
|
uint raw4 = scene[ix + 4];
|
|
|
|
FillLinGradient s;
|
|
|
|
s.index = raw0;
|
|
|
|
s.p0 = vec2(uintBitsToFloat(raw1), uintBitsToFloat(raw2));
|
|
|
|
s.p1 = vec2(uintBitsToFloat(raw3), uintBitsToFloat(raw4));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
FillImage FillImage_read(FillImageRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
FillImage s;
|
|
|
|
s.index = raw0;
|
|
|
|
s.offset = ivec2(int(raw1 << 16) >> 16, int(raw1) >> 16);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
SetLineWidth SetLineWidth_read(SetLineWidthRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
SetLineWidth s;
|
|
|
|
s.width = uintBitsToFloat(raw0);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
Transform Transform_read(TransformRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
uint raw2 = scene[ix + 2];
|
|
|
|
uint raw3 = scene[ix + 3];
|
|
|
|
uint raw4 = scene[ix + 4];
|
|
|
|
uint raw5 = scene[ix + 5];
|
|
|
|
Transform s;
|
|
|
|
s.mat = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
s.translate = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
Clip Clip_read(ClipRef ref) {
|
2020-11-20 06:53:59 +11:00
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
uint raw1 = scene[ix + 1];
|
|
|
|
uint raw2 = scene[ix + 2];
|
|
|
|
uint raw3 = scene[ix + 3];
|
2020-11-21 04:26:02 +11:00
|
|
|
Clip s;
|
2020-11-20 06:53:59 +11:00
|
|
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-03-19 23:49:47 +11:00
|
|
|
SetFillMode SetFillMode_read(SetFillModeRef ref) {
|
|
|
|
uint ix = ref.offset >> 2;
|
|
|
|
uint raw0 = scene[ix + 0];
|
|
|
|
SetFillMode s;
|
|
|
|
s.fill_mode = raw0;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2021-03-17 20:51:38 +11:00
|
|
|
ElementTag Element_tag(ElementRef ref) {
|
|
|
|
uint tag_and_flags = scene[ref.offset >> 2];
|
|
|
|
return ElementTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
2020-05-12 13:01:06 +10:00
|
|
|
}
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
LineSeg Element_Line_read(ElementRef ref) {
|
2020-05-21 00:38:52 +10:00
|
|
|
return LineSeg_read(LineSegRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
QuadSeg Element_Quad_read(ElementRef ref) {
|
2020-05-12 13:01:06 +10:00
|
|
|
return QuadSeg_read(QuadSegRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
CubicSeg Element_Cubic_read(ElementRef ref) {
|
2020-05-12 13:01:06 +10:00
|
|
|
return CubicSeg_read(CubicSegRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
2021-03-17 21:08:28 +11:00
|
|
|
FillColor Element_FillColor_read(ElementRef ref) {
|
|
|
|
return FillColor_read(FillColorRef(ref.offset + 4));
|
2020-05-12 13:01:06 +10:00
|
|
|
}
|
|
|
|
|
2021-06-24 04:50:51 +10:00
|
|
|
FillLinGradient Element_FillLinGradient_read(ElementRef ref) {
|
|
|
|
return FillLinGradient_read(FillLinGradientRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
|
|
|
FillImage Element_FillImage_read(ElementRef ref) {
|
|
|
|
return FillImage_read(FillImageRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
2020-05-12 13:01:06 +10:00
|
|
|
SetLineWidth Element_SetLineWidth_read(ElementRef ref) {
|
|
|
|
return SetLineWidth_read(SetLineWidthRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
|
|
|
Transform Element_Transform_read(ElementRef ref) {
|
|
|
|
return Transform_read(TransformRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
Clip Element_BeginClip_read(ElementRef ref) {
|
|
|
|
return Clip_read(ClipRef(ref.offset + 4));
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2020-11-21 04:26:02 +11:00
|
|
|
Clip Element_EndClip_read(ElementRef ref) {
|
|
|
|
return Clip_read(ClipRef(ref.offset + 4));
|
2020-11-20 06:53:59 +11:00
|
|
|
}
|
|
|
|
|
2021-03-19 23:49:47 +11:00
|
|
|
SetFillMode Element_SetFillMode_read(ElementRef ref) {
|
|
|
|
return SetFillMode_read(SetFillModeRef(ref.offset + 4));
|
|
|
|
}
|
|
|
|
|