Shader:clone;

This commit is contained in:
bjorn 2022-05-22 15:10:07 -07:00
parent a64fd216ea
commit a0db01959d
3 changed files with 60 additions and 0 deletions

View File

@ -3,6 +3,7 @@
#include "util.h"
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
static int l_lovrShaderGetType(lua_State* L) {
Shader* shader = luax_checktype(L, 1, Shader);
@ -11,7 +12,36 @@ static int l_lovrShaderGetType(lua_State* L) {
return 1;
}
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;
arr_init(&flags, realloc);
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);
}
Shader* clone = lovrShaderClone(shader, flags.data, flags.length);
arr_free(&flags);
luax_pushtype(L, Shader, clone);
lovrRelease(clone, lovrShaderDestroy);
return 1;
}
const luaL_Reg lovrShader[] = {
{ "getType", l_lovrShaderGetType },
{ "clone", l_lovrShaderClone },
{ NULL, NULL }
};

View File

@ -56,8 +56,11 @@ typedef struct {
struct Shader {
uint32_t ref;
Shader* parent;
gpu_shader* gpu;
ShaderInfo info;
uint32_t layout;
uint32_t computePipeline;
uint32_t attributeMask;
uint32_t constantSize;
uint32_t constantCount;
@ -912,7 +915,33 @@ Shader* lovrShaderCreate(ShaderInfo* info) {
gpu_shader_init(shader->gpu, &gpu);
lovrShaderInit(shader);
return shader;
}
Shader* lovrShaderClone(Shader* parent, ShaderFlag* flags, uint32_t count) {
Shader* shader = calloc(1, sizeof(Shader) + gpu_sizeof_shader());
lovrAssert(shader, "Out of memory");
shader->ref = 1;
lovrRetain(parent);
shader->parent = parent;
shader->gpu = parent->gpu;
shader->info = parent->info;
shader->info.flags = flags;
shader->info.flagCount = count;
shader->layout = parent->layout;
shader->attributeMask = parent->attributeMask;
shader->constantSize = parent->constantSize;
shader->constantCount = parent->constantCount;
shader->resourceCount = parent->resourceCount;
shader->flagCount = parent->flagCount;
shader->constants = parent->constants;
shader->resources = parent->resources;
shader->flags = malloc(shader->flagCount * sizeof(gpu_shader_flag));
shader->flagLookup = malloc(shader->flagCount * sizeof(uint32_t));
lovrAssert(shader->flags && shader->flagLookup, "Out of memory");
memcpy(shader->flags, parent->flags, shader->flagCount * sizeof(gpu_shader_flag));
memcpy(shader->flagLookup, parent->flagLookup, shader->flagCount * sizeof(uint32_t));
lovrShaderInit(shader);
return shader;
}

View File

@ -263,6 +263,7 @@ typedef struct {
struct Blob* lovrGraphicsCompileShader(ShaderStage stage, struct Blob* source);
Shader* lovrShaderCreate(ShaderInfo* info);
Shader* lovrShaderClone(Shader* parent, ShaderFlag* flags, uint32_t count);
void lovrShaderDestroy(void* ref);
const ShaderInfo* lovrShaderGetInfo(Shader* shader);