summaryrefslogtreecommitdiff
path: root/src/spirt.c
diff options
context:
space:
mode:
authorAiden Gall <aiden@aidengall.xyz>2024-02-04 21:50:16 +0000
committerAiden Gall <aiden@aidengall.xyz>2024-02-04 22:20:33 +0000
commitc0fb8bf2d8e25308eadff659564ad9600e5cb369 (patch)
treed4d33f069bc93dd01ea1912be4fc682be16f742a /src/spirt.c
parentc44d2805ba480fc7c2faf8ae07f2c1c9febf7e34 (diff)
raytraced background gradient
Diffstat (limited to 'src/spirt.c')
-rw-r--r--src/spirt.c105
1 files changed, 89 insertions, 16 deletions
diff --git a/src/spirt.c b/src/spirt.c
index fd6457b..527981f 100644
--- a/src/spirt.c
+++ b/src/spirt.c
@@ -33,7 +33,8 @@ struct kernel_context {
cl_context context;
cl_command_queue command_queue;
cl_program program;
- cl_kernel k_hello;
+ cl_kernel k_gen_rays;
+ cl_kernel k_ray_colour;
};
struct opts {
@@ -43,8 +44,16 @@ struct opts {
long devidx;
};
-static unsigned char *kernel_hello(struct kernel_context *runtime,
- size_t image_width, size_t image_height);
+struct camera {
+ cl_float3 centre;
+ cl_float3 pixel_delta_u;
+ cl_float3 pixel_delta_v;
+ cl_float3 corner00;
+};
+
+static unsigned char *kernel_render(struct kernel_context *runtime,
+ size_t image_width, size_t image_height,
+ struct camera cam);
static struct kernel_context kernel_context_init(size_t platidx, size_t devidx);
static void kernel_context_clean(struct kernel_context *runtime);
@@ -55,18 +64,24 @@ extern const char *SPIRV_START[];
extern const char *SPIRV_END[];
static unsigned char *
-kernel_hello(struct kernel_context *const runtime, const size_t image_width,
- const size_t image_height)
+kernel_render(struct kernel_context *const runtime, const size_t image_width,
+ const size_t image_height, const struct camera cam)
{
cl_int err;
size_t global_item_size[2];
unsigned char *h_canvas;
- cl_mem d_canvas;
- size_t canvas_size;
+ cl_mem d_canvas, d_rays;
+ size_t rays_size, canvas_size;
canvas_size = (sizeof("RGBA") - 1) * image_width * image_height;
+ rays_size = 2 * image_width * image_height;
+
+ d_rays = clCreateBuffer(runtime->context, CL_MEM_READ_WRITE,
+ sizeof(cl_float3) * rays_size, NULL, &err);
+ if (err != CL_SUCCESS)
+ die("clCreateBuffer: %s\n", cl_strerror(err));
h_canvas = calloc(canvas_size, sizeof(*h_canvas));
if (!h_canvas)
@@ -77,15 +92,38 @@ kernel_hello(struct kernel_context *const runtime, const size_t image_width,
if (err != CL_SUCCESS)
die("clCreateBuffer: %s\n", cl_strerror(err));
- err = clSetKernelArg(runtime->k_hello, 0, sizeof(d_canvas), &d_canvas);
+ err = clSetKernelArg(runtime->k_gen_rays, 0, sizeof(d_rays), &d_rays);
+ err |= clSetKernelArg(runtime->k_gen_rays, 1, sizeof(cl_float3),
+ &cam.centre);
+ err |= clSetKernelArg(runtime->k_gen_rays, 2, sizeof(cl_float3),
+ &cam.pixel_delta_u);
+ err |= clSetKernelArg(runtime->k_gen_rays, 3, sizeof(cl_float3),
+ &cam.pixel_delta_v);
+ err |= clSetKernelArg(runtime->k_gen_rays, 4, sizeof(cl_float3),
+ &cam.corner00);
if (err != CL_SUCCESS)
die("clSetKernelArg: %s\n", cl_strerror(err));
global_item_size[0] = image_width;
global_item_size[1] = image_height;
- err = clEnqueueNDRangeKernel(runtime->command_queue, runtime->k_hello,
- 2, NULL, global_item_size, NULL, 0, NULL,
- NULL);
+ err = clEnqueueNDRangeKernel(runtime->command_queue,
+ runtime->k_gen_rays, 2, NULL,
+ global_item_size, NULL, 0, NULL, NULL);
+ if (err != CL_SUCCESS)
+ die("clEnqueueNDRangeKernel: %s\n", cl_strerror(err));
+
+ err = clSetKernelArg(runtime->k_ray_colour, 0, sizeof(d_canvas),
+ &d_canvas);
+ err |= clSetKernelArg(runtime->k_ray_colour, 1, sizeof(d_rays),
+ &d_rays);
+ if (err != CL_SUCCESS)
+ die("clSetKernelArg: %s\n", cl_strerror(err));
+
+ global_item_size[0] = image_width;
+ global_item_size[1] = image_height;
+ err = clEnqueueNDRangeKernel(runtime->command_queue,
+ runtime->k_ray_colour, 2, NULL,
+ global_item_size, NULL, 0, NULL, NULL);
if (err != CL_SUCCESS)
die("clEnqueueNDRangeKernel: %s\n", cl_strerror(err));
@@ -95,6 +133,7 @@ kernel_hello(struct kernel_context *const runtime, const size_t image_width,
if (err != CL_SUCCESS)
die("clEnqueueReadBuffer: %s\n", cl_strerror(err));
+ clReleaseMemObject(d_rays);
clReleaseMemObject(d_canvas);
return h_canvas;
@@ -138,7 +177,11 @@ kernel_context_init(const size_t platidx, const size_t devidx)
runtime.program = compile_spirv_program(runtime.context, runtime.device,
SPIRV_START, SPIRV_SIZE);
- runtime.k_hello = clCreateKernel(runtime.program, "hello", &err);
+ runtime.k_gen_rays = clCreateKernel(runtime.program, "gen_rays", &err);
+ if (err != CL_SUCCESS)
+ die("clCreateKernel: %s\n", cl_strerror(err));
+ runtime.k_ray_colour =
+ clCreateKernel(runtime.program, "ray_colour", &err);
if (err != CL_SUCCESS)
die("clCreateKernel: %s\n", cl_strerror(err));
@@ -151,7 +194,8 @@ kernel_context_clean(struct kernel_context *const runtime)
clFlush(runtime->command_queue);
clFinish(runtime->command_queue);
- clReleaseKernel(runtime->k_hello);
+ clReleaseKernel(runtime->k_gen_rays);
+ clReleaseKernel(runtime->k_ray_colour);
clReleaseProgram(runtime->program);
clReleaseCommandQueue(runtime->command_queue);
clReleaseContext(runtime->context);
@@ -164,8 +208,8 @@ get_args(int argc, char *argv[])
opts.platidx = 0;
opts.devidx = 0;
- opts.width = 256;
- opts.height = 256;
+ opts.width = 1024;
+ opts.height = 576;
if (argv[0])
argv++, argc--;
@@ -213,6 +257,8 @@ main(int argc, char *argv[])
struct kernel_context runtime;
unsigned char *h_canvas;
+ struct camera cam;
+ float focal_length, viewport_width, viewport_height;
Image img;
Texture2D texture;
@@ -221,7 +267,34 @@ main(int argc, char *argv[])
runtime = kernel_context_init(opts.platidx, opts.devidx);
- h_canvas = kernel_hello(&runtime, opts.width, opts.height);
+ focal_length = 1.0f;
+ viewport_height = 2.0f;
+ viewport_width =
+ viewport_height * ((float)opts.width / (float)opts.height);
+
+ cam.centre.s[0] = 0.0f;
+ cam.centre.s[1] = 0.0f;
+ cam.centre.s[2] = 0.0f;
+
+ cam.pixel_delta_u.s[0] = viewport_width / (float)opts.width;
+ cam.pixel_delta_u.s[1] = 0.0f;
+ cam.pixel_delta_u.s[2] = 0.0f;
+
+ cam.pixel_delta_v.s[0] = 0.0f;
+ cam.pixel_delta_v.s[1] = -viewport_height / (float)opts.height;
+ cam.pixel_delta_v.s[2] = 0.0f;
+
+ cam.corner00.s[0] =
+ cam.centre.s[0] - viewport_width / 2.0f +
+ 0.5f * (cam.pixel_delta_u.s[0] + cam.pixel_delta_v.s[0]);
+ cam.corner00.s[1] =
+ cam.centre.s[1] + viewport_height / 2.0f +
+ 0.5f * (cam.pixel_delta_u.s[1] + cam.pixel_delta_v.s[1]);
+ cam.corner00.s[2] =
+ cam.centre.s[2] - focal_length +
+ 0.5f * (cam.pixel_delta_u.s[2] + cam.pixel_delta_v.s[2]);
+
+ h_canvas = kernel_render(&runtime, opts.width, opts.height, cam);
img.data = h_canvas;
img.width = opts.width;