shithub: gpufs

Download patch

ref: 10954ee4177af81e1892b833d8b33140629f68a4
parent: 676c163887770438587b64aae2679a93ba836de2
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Feb 16 07:39:12 EST 2024

adds read/write support for shaders and buffers

--- a/gpufs.c
+++ b/gpufs.c
@@ -174,6 +174,7 @@
 fsread(Req *r)
 {
 	//char buf[1024];
+	//int n;
 	Gpufid *f;
 	
 	f = r->fid->aux;
@@ -190,6 +191,14 @@
 		readrctl(r);
 		respond(r, nil);
 		return;
+	case Qshader:
+		r->ofcall.count = readshader(OBJECTID(f), r->ofcall.data, r->ifcall.count, r->ifcall.offset);
+		respond(r, nil);
+		return;
+	case Qbuffer:
+		r->ofcall.count = readbuffer(OBJECTID(f), r->ofcall.data, r->ifcall.count, r->ifcall.offset);
+		respond(r, nil);
+		return;
 	}
 	respond(r, "not implemented");
 }
@@ -369,6 +378,7 @@
 	Gpufid *f;
 	int n;
 	char *s;
+	char err[256];
 	
 	f = r->fid->aux;
 	switch (f->level) {
@@ -377,6 +387,24 @@
 		s = emalloc(n+1);
 		memmove(s, r->ifcall.data, n);
 		rootcommand(r, s);
+		return;
+	case Qshader:
+		r->ofcall.count = writeshader(OBJECTID(f), r->ifcall.data, r->ifcall.count, r->ifcall.offset);
+		if (r->ofcall.count > 0) {
+			respond(r, nil);
+			return;
+		}
+		snprint(err, 256, "%r");
+		respond(r, err);
+		return;
+	case Qbuffer:
+		r->ofcall.count = writebuffer(OBJECTID(f), r->ifcall.data, r->ifcall.count, r->ifcall.offset);
+		if (r->ofcall.count > 0) {
+			respond(r, nil);
+			return;
+		}
+		snprint(err, 256, "%r");
+		respond(r, err);
 		return;
 	}
 	respond(r, "not implemented");
--- a/vm.c
+++ b/vm.c
@@ -6,6 +6,8 @@
 
 extern int debug;
 
+#define IDVALID(c) (c < numobjects)
+
 Frame *stack = nil;
 
 u32int
@@ -83,10 +85,10 @@
 Object objects[256];
 int numobjects = 0;
 
-int
+vlong
 genshader(void)
 {
-	int id;
+	vlong id;
 	if (numobjects >= 256) {
 		werrstr("not enough free objects!");
 		return -1;
@@ -99,10 +101,10 @@
 	return id;
 }
 
-int
+vlong
 genbuffer(long size)
 {
-	int id;
+	vlong id;
 	if (numobjects >= 256) {
 		werrstr("not enough free objects!");
 		return -1;
@@ -120,7 +122,7 @@
 	return id;
 }
 
-int
+vlong
 getnumobjects()
 {
 	return numobjects;
@@ -127,7 +129,7 @@
 }
 
 long
-getbufferlength(int id)
+getbufferlength(vlong id)
 {
 	if (objects[id].type != BUFFER) {
 		werrstr("invalid object type!");
@@ -137,7 +139,7 @@
 }
 
 long
-getshaderlength(int id)
+getshaderlength(vlong id)
 {
 	long len;
 	if (objects[id].type != SHADER) {
@@ -149,17 +151,144 @@
 }
 
 int
-getobjecttype(int id)
+getobjecttype(vlong id)
 {
 	return objects[id].type;
 }
 
 vlong
-getobjectid(int num)
+getobjectid(vlong num)
 {
 	if (num >= numobjects) {
-		werrstr("invalid object number: %d", num);
+		werrstr("invalid object number: %lld", num);
 		return -1;
 	}
 	return objects[num].id;
+}
+
+int
+writeshader(vlong id, void *data, long n, long offset)
+{
+	char *buf;
+	
+	if (!IDVALID(id)) {
+		werrstr("invalid object id %lld", id);
+		return 0;
+	}
+	
+	if (objects[id].type != SHADER) {
+		werrstr("invalid object type: %lld != SHADER", id);
+		return 0;
+	}
+	
+	buf = (char*)objects[id].s.buffer;
+	if (!buf) {
+		objects[id].s.len = n+offset;
+		objects[id].s.buffer = malloc(objects[id].s.len);
+		buf = (char*)objects[id].s.buffer;
+	}
+	if (!buf) {
+		sysfatal("out of memory");
+		return 0;
+	}
+	if (offset+n > objects[id].s.len) {
+		objects[id].s.len = n+offset;
+		objects[id].s.buffer = realloc(objects[id].s.buffer, objects[id].s.len);
+		buf = (char*)objects[id].s.buffer;
+	}
+	if (!buf) {
+		sysfatal("out of memory!");
+		return 0;
+	}
+	buf += offset;
+	memcpy(buf, data, n);
+	return n;
+}
+
+int
+writebuffer(vlong id, void *data, long n, long offset)
+{
+	char *buf;
+	
+	if (!IDVALID(id)) {
+		werrstr("invalid object id %lld", id);
+		return 0;
+	}
+	
+	if (objects[id].type != BUFFER) {
+		werrstr("invalid object type: %lld != BUFFER", id);
+		return 0;
+	}
+	
+	if (offset+n > objects[id].b.len) {
+		return -1;
+	}
+	
+	buf = &objects[id].b.buffer[offset];
+	memcpy(buf, data, n);
+	return n;
+}
+
+int
+compileshader(vlong id)
+{
+	return -1;
+}
+
+int
+readshader(vlong id, void *data, long n, long offset)
+{
+	char *buf;
+	
+	if (!IDVALID(id)) {
+		werrstr("invalid id %lld", id);
+		return 0;
+	}
+	
+	if (objects[id].type != SHADER) {
+		werrstr("invalid object type: %lld != SHADER", id);
+		return 0;
+	}
+	
+	buf = (char*)objects[id].s.buffer;
+	
+	if (!buf) {
+		werrstr("shader is empty");
+		return 0;
+	}
+	
+	if (offset+n > objects[id].b.len) {
+		n = objects[id].s.len - offset;
+	}
+	if (n <= 0)
+		return 0;
+	
+	buf = &buf[offset];
+	memcpy(data, buf, n);
+	return n;
+}
+
+int readbuffer(vlong id, void *data, long n, long offset)
+{
+	char *buf;
+	
+	if (!IDVALID(id)) {
+		werrstr("invalid id %lld", id);
+		return 0;
+	}
+	
+	if (objects[id].type != BUFFER) {
+		werrstr("invalid object type: %lld != BUFFER", id);
+		return 0;
+	}
+	
+	if (offset+n > objects[id].b.len) {
+		n = objects[id].b.len - offset;
+	}
+	if (n <= 0)
+		return 0;
+	
+	buf = &objects[id].b.buffer[offset];
+	memcpy(data, buf, n);
+	return n;
 }
--- a/vm.h
+++ b/vm.h
@@ -7,11 +7,21 @@
 	SHADER,
 };
 
-int genshader(void);
-int genbuffer(long size);
+// object id
+vlong genshader(void);
+vlong genbuffer(long size);
 
-int getnumobjects(void);
-vlong getobjectid(int num);
-long getshaderlength(int id);
-long getbufferlength(int id);
-int getobjecttype(int id);
+vlong getnumobjects(void);
+vlong getobjectid(vlong num);
+long getshaderlength(vlong id);
+long getbufferlength(vlong id);
+int getobjecttype(vlong id);
+
+// length data written, success
+int writeshader(vlong id, void *data, long n, long offset);
+int writebuffer(vlong id, void *data, long n, long offset);
+int compileshader(vlong id);
+
+// length data written
+int readshader(vlong id, void *data, long n, long offset);
+int readbuffer(vlong id, void *data, long n, long offset);