2022-05-09 18:47:06 +00:00
|
|
|
#include "api.h"
|
|
|
|
#include "graphics/graphics.h"
|
|
|
|
#include "util.h"
|
2022-05-22 22:10:07 +00:00
|
|
|
#include <stdlib.h>
|
2022-05-09 18:47:06 +00:00
|
|
|
|
2022-05-22 22:10:07 +00:00
|
|
|
static int l_lovrShaderClone(lua_State* L) {
|
|
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
|
|
luaL_checktype(L, 2, LUA_TTABLE);
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
|
|
|
arr_t(ShaderFlag) flags;
|
2024-03-27 19:48:35 +00:00
|
|
|
arr_init(&flags);
|
2022-05-22 22:10:07 +00:00
|
|
|
|
|
|
|
while (lua_next(L, 2) != 0) {
|
|
|
|
ShaderFlag flag = { 0 };
|
|
|
|
flag.value = lua_isboolean(L, -1) ? (double) lua_toboolean(L, -1) : lua_tonumber(L, -1);
|
|
|
|
switch (lua_type(L, -2)) {
|
|
|
|
case LUA_TSTRING: flag.name = lua_tostring(L, -2); break;
|
|
|
|
case LUA_TNUMBER: flag.id = lua_tointeger(L, -2); break;
|
|
|
|
default: lovrThrow("Unexpected ShaderFlag key type (%s)", lua_typename(L, lua_type(L, -2)));
|
|
|
|
}
|
|
|
|
arr_push(&flags, flag);
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2022-08-07 01:05:30 +00:00
|
|
|
lovrCheck(flags.length < 1000, "Too many Shader flags");
|
|
|
|
|
|
|
|
Shader* clone = lovrShaderClone(shader, flags.data, (uint32_t) flags.length);
|
2022-05-22 22:10:07 +00:00
|
|
|
arr_free(&flags);
|
|
|
|
|
|
|
|
luax_pushtype(L, Shader, clone);
|
|
|
|
lovrRelease(clone, lovrShaderDestroy);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-02-20 23:07:30 +00:00
|
|
|
static int l_lovrShaderGetType(lua_State* L) {
|
|
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
|
|
const ShaderInfo* info = lovrShaderGetInfo(shader);
|
|
|
|
luax_pushenum(L, ShaderType, info->type);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-07-04 05:59:49 +00:00
|
|
|
static int l_lovrShaderHasStage(lua_State* L) {
|
|
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
|
|
ShaderStage stage = luax_checkenum(L, 2, ShaderStage, NULL);
|
|
|
|
bool present = lovrShaderHasStage(shader, stage);
|
|
|
|
lua_pushboolean(L, present);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-07-04 06:04:56 +00:00
|
|
|
static int l_lovrShaderHasAttribute(lua_State* L) {
|
|
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
|
|
const char* name;
|
|
|
|
uint32_t location;
|
|
|
|
if (lua_type(L, 2) == LUA_TNUMBER) {
|
|
|
|
location = luax_checku32(L, 2);
|
|
|
|
name = NULL;
|
|
|
|
} else {
|
|
|
|
name = lua_tostring(L, 2);
|
|
|
|
location = 0;
|
|
|
|
}
|
|
|
|
bool present = lovrShaderHasAttribute(shader, name, location);
|
|
|
|
lua_pushboolean(L, present);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-08-06 20:06:42 +00:00
|
|
|
static int l_lovrShaderGetWorkgroupSize(lua_State* L) {
|
2022-07-10 06:39:03 +00:00
|
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
|
|
|
|
|
|
if (!lovrShaderHasStage(shader, STAGE_COMPUTE)) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t size[3];
|
2022-08-06 20:06:42 +00:00
|
|
|
lovrShaderGetWorkgroupSize(shader, size);
|
2022-07-10 06:39:03 +00:00
|
|
|
lua_pushinteger(L, size[0]);
|
|
|
|
lua_pushinteger(L, size[1]);
|
|
|
|
lua_pushinteger(L, size[2]);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
2023-08-25 20:42:09 +00:00
|
|
|
static int l_lovrShaderGetBufferFormat(lua_State* L) {
|
|
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
2023-09-23 03:44:06 +00:00
|
|
|
const char* name = luaL_checkstring(L, 2);
|
2024-03-05 16:59:31 +00:00
|
|
|
|
2023-08-25 20:42:09 +00:00
|
|
|
uint32_t fieldCount;
|
|
|
|
const DataField* format = lovrShaderGetBufferFormat(shader, name, &fieldCount);
|
2024-03-05 16:59:31 +00:00
|
|
|
|
|
|
|
if (!format) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-08-25 20:42:09 +00:00
|
|
|
luax_pushbufferformat(L, format->fields, format->fieldCount);
|
|
|
|
lua_pushinteger(L, format->stride);
|
|
|
|
lua_setfield(L, -2, "stride");
|
2024-03-05 16:59:31 +00:00
|
|
|
|
2024-04-16 22:04:20 +00:00
|
|
|
if (format->length == 0 || format->length == ~0u) {
|
2024-03-05 16:59:31 +00:00
|
|
|
lua_pushnil(L);
|
|
|
|
} else {
|
2024-04-16 22:04:20 +00:00
|
|
|
lua_pushinteger(L, format->length);
|
2024-03-05 16:59:31 +00:00
|
|
|
}
|
|
|
|
|
2023-08-25 20:42:09 +00:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2022-05-09 18:47:06 +00:00
|
|
|
const luaL_Reg lovrShader[] = {
|
2022-05-22 22:10:07 +00:00
|
|
|
{ "clone", l_lovrShaderClone },
|
2024-02-20 23:07:30 +00:00
|
|
|
{ "getType", l_lovrShaderGetType },
|
2022-07-04 05:59:49 +00:00
|
|
|
{ "hasStage", l_lovrShaderHasStage },
|
2022-07-04 06:04:56 +00:00
|
|
|
{ "hasAttribute", l_lovrShaderHasAttribute },
|
2022-08-06 20:06:42 +00:00
|
|
|
{ "getWorkgroupSize", l_lovrShaderGetWorkgroupSize },
|
2023-08-25 20:42:09 +00:00
|
|
|
{ "getBufferFormat", l_lovrShaderGetBufferFormat },
|
2022-05-09 18:47:06 +00:00
|
|
|
{ NULL, NULL }
|
|
|
|
};
|