// A simple kernel to create an image. // Right now, this kernel stores the image in a buffer, but a better // plan is to use a texture. This is because of limited support. #version 450 #extension GL_GOOGLE_include_directive : enable layout(local_size_x = 16, local_size_y = 16) in; layout(set = 0, binding = 0) readonly buffer SceneBuf { uint[] scene; }; layout(set = 0, binding = 1) buffer ImageBuf { uint[] image; }; #include "scene.h" // TODO: make the image size dynamic. #define IMAGE_WIDTH 2048 #define IMAGE_HEIGHT 1535 void main() { uvec2 xy = gl_GlobalInvocationID.xy; vec2 uv = vec2(xy) * vec2(1.0 / IMAGE_WIDTH, 1.0 / IMAGE_HEIGHT); vec4 rgba = vec4(uv.xyy, 1.0); // Render the scene. Right now, every pixel traverses the scene graph, // which is horribly wasteful, but the goal is to get *some* output and // then optimize. SimpleGroup group = SimpleGroup_read(SimpleGroupRef(0)); for (uint i = 0; i < group.n_items; i++) { // Writing this out by hand is illuminating the need for array access // in piet-gpu-derive. There is some support in the `_index` functions, // but those are only generated for structs, not for `Ref` or other // types. PietItemRef item_ref = PietItemRef(scene[(group.items.offset >> 2) + i]); uint tag = PietItem_tag(item_ref); if (tag == PietItem_Circle) { PietCircle = PietItem_Circle_read(item_ref); } } uvec4 s = uvec4(round(rgba * 255.0)); uint rgba_packed = s.x | (s.y << 8) | (s.z << 16) | (s.w << 24); image[xy.y * IMAGE_WIDTH + xy.x] = rgba_packed; if (xy.y == 0 && xy.x < 8) { image[xy.x] = scene[xy.x]; } }