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);