Compare commits

...

5 Commits

Author SHA1 Message Date
bjorn 16860e8ef5 rm stats;
These stats don't make sense right now.
2022-08-04 07:59:07 -07:00
bjorn 7c7f8ed907 Free ModelData metadata; 2022-08-04 00:31:39 -07:00
bjorn eac3299bd0 ModelData:getMetadata; 2022-08-04 00:27:20 -07:00
bjorn a6d843c642 Fix desktop driver; 2022-08-04 00:12:41 -07:00
bjorn acd87a5e5c lovr.graphics.present;
It's nice to have an explicit action for presentation.
2022-08-04 00:06:54 -07:00
12 changed files with 109 additions and 82 deletions

View File

@ -132,6 +132,7 @@ function lovr.run()
pass:reset()
local skip = lovr.mirror(pass)
if not skip then lovr.graphics.submit(pass) end
lovr.graphics.present()
end
end
if lovr.headset then lovr.headset.submit() end

View File

@ -62,6 +62,18 @@ static ModelAnimation* luax_checkanimation(lua_State* L, int index, ModelData* m
}
}
static int l_lovrModelDataGetMetadata(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
if (!model->metadata || model->metadataSize == 0) {
lua_pushnil(L);
} else {
lua_pushlstring(L, model->metadata, model->metadataSize);
}
return 1;
}
static int l_lovrModelDataGetBlobCount(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, model->blobCount);
@ -731,6 +743,7 @@ static int l_lovrModelDataGetSkinInverseBindMatrix(lua_State* L) {
}
const luaL_Reg lovrModelData[] = {
{ "getMetadata", l_lovrModelDataGetMetadata },
{ "getBlobCount", l_lovrModelDataGetBlobCount },
{ "getBlob", l_lovrModelDataGetBlob },
{ "getImageCount", l_lovrModelDataGetImageCount },

View File

@ -703,6 +703,11 @@ static int l_lovrGraphicsSubmit(lua_State* L) {
return 1;
}
static int l_lovrGraphicsPresent(lua_State* L) {
lovrGraphicsPresent();
return 0;
}
static int l_lovrGraphicsWait(lua_State* L) {
lovrGraphicsWait();
return 0;
@ -795,17 +800,6 @@ static int l_lovrGraphicsGetLimits(lua_State* L) {
return 1;
}
static int l_lovrGraphicsGetStats(lua_State* L) {
GraphicsStats stats;
lovrGraphicsGetStats(&stats);
lua_newtable(L);
lua_pushinteger(L, stats.pipelineSwitches), lua_setfield(L, -2, "pipelineSwitches");
lua_pushinteger(L, stats.bundleSwitches), lua_setfield(L, -2, "bundleSwitches");
return 1;
}
static int l_lovrGraphicsIsFormatSupported(lua_State* L) {
TextureFormat format = luax_checkenum(L, 1, TextureFormat, NULL);
uint32_t features = 0;
@ -1488,11 +1482,11 @@ static int l_lovrGraphicsNewPass(lua_State* L) {
static const luaL_Reg lovrGraphics[] = {
{ "init", l_lovrGraphicsInit },
{ "submit", l_lovrGraphicsSubmit },
{ "present", l_lovrGraphicsPresent },
{ "wait", l_lovrGraphicsWait },
{ "getDevice", l_lovrGraphicsGetDevice },
{ "getFeatures", l_lovrGraphicsGetFeatures },
{ "getLimits", l_lovrGraphicsGetLimits },
{ "getStats", l_lovrGraphicsGetStats },
{ "isFormatSupported", l_lovrGraphicsIsFormatSupported },
{ "getWindowPass", l_lovrGraphicsGetWindowPass },
{ "getDefaultFont", l_lovrGraphicsGetDefaultFont },

View File

@ -57,6 +57,10 @@ static int l_lovrModelGetData(lua_State* L) {
return 1;
}
static int l_lovrModelGetMetadata(lua_State* L) {
return luax_callmodeldata(L, "getMetadata", 1);
}
static int l_lovrModelGetRootNode(lua_State* L) {
return luax_callmodeldata(L, "getRootNode", 1);
}
@ -356,6 +360,7 @@ static int l_lovrModelGetTexture(lua_State* L) {
const luaL_Reg lovrModel[] = {
{ "getData", l_lovrModelGetData },
{ "getMetadata", l_lovrModelGetMetadata },
{ "getRootNode", l_lovrModelGetRootNode },
{ "getNodeCount", l_lovrModelGetNodeCount },
{ "getNodeName", l_lovrModelGetNodeName },

View File

@ -700,7 +700,8 @@ typedef struct {
bool gpu_init(gpu_config* config);
void gpu_destroy(void);
uint32_t gpu_begin(void);
void gpu_submit(gpu_stream** streams, uint32_t count, bool present);
void gpu_submit(gpu_stream** streams, uint32_t count);
void gpu_present(void);
bool gpu_is_complete(uint32_t tick);
bool gpu_wait_tick(uint32_t tick);
void gpu_wait_idle(void);

View File

@ -2315,7 +2315,7 @@ uint32_t gpu_begin() {
return state.tick[CPU];
}
void gpu_submit(gpu_stream** streams, uint32_t count, bool present) {
void gpu_submit(gpu_stream** streams, uint32_t count) {
gpu_tick* tick = &state.ticks[state.tick[CPU] & TICK_MASK];
VkCommandBuffer commands[COUNTOF(tick->streams)];
@ -2323,35 +2323,43 @@ void gpu_submit(gpu_stream** streams, uint32_t count, bool present) {
commands[i] = streams[i]->commands;
}
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submit = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = present,
.waitSemaphoreCount = !!state.surfaceSemaphore,
.pWaitSemaphores = &state.surfaceSemaphore,
.pWaitDstStageMask = &waitMask,
.pWaitDstStageMask = &waitStage,
.commandBufferCount = count,
.pCommandBuffers = commands,
.signalSemaphoreCount = present,
.pSignalSemaphores = &tick->semaphores[1]
.pCommandBuffers = commands
};
VK(vkQueueSubmit(state.queue, 1, &submit, tick->fence), "Queue submit failed") {}
state.surfaceSemaphore = VK_NULL_HANDLE;
}
if (present) {
VkPresentInfoKHR presentInfo = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &tick->semaphores[1],
.swapchainCount = 1,
.pSwapchains = &state.swapchain,
.pImageIndices = &state.currentSurfaceTexture
};
void gpu_present() {
VkSemaphore semaphore = state.ticks[state.tick[CPU] & TICK_MASK].semaphores[1];
VK(vkQueuePresentKHR(state.queue, &presentInfo), "Queue present failed") {}
state.surfaceSemaphore = VK_NULL_HANDLE;
state.currentSurfaceTexture = ~0u;
}
VkSubmitInfo submit = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &semaphore
};
VK(vkQueueSubmit(state.queue, 1, &submit, VK_NULL_HANDLE), "Queue submit failed") {}
VkPresentInfoKHR present = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &semaphore,
.swapchainCount = 1,
.pSwapchains = &state.swapchain,
.pImageIndices = &state.currentSurfaceTexture
};
VK(vkQueuePresentKHR(state.queue, &present), "Queue present failed") {}
state.currentSurfaceTexture = ~0u;
}
bool gpu_is_complete(uint32_t tick) {

View File

@ -105,6 +105,7 @@ void lovrModelDataDestroy(void* ref) {
map_free(&model->nodeMap);
free(model->vertices);
free(model->indices);
free(model->metadata);
free(model->data);
free(model);
}

View File

@ -156,6 +156,9 @@ typedef struct ModelData {
uint32_t ref;
void* data;
char* metadata;
size_t metadataSize;
struct Blob** blobs;
struct Image** images;
ModelBuffer* buffers;

View File

@ -230,6 +230,11 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
binOffset = 0;
}
model->metadata = malloc(jsonLength);
lovrAssert(model->metadata, "Out of memory");
memcpy(model->metadata, json, jsonLength);
model->metadataSize = jsonLength;
// Parse JSON
jsmn_parser parser;
jsmn_init(&parser);

View File

@ -361,7 +361,6 @@ static struct {
gpu_device_info device;
gpu_features features;
gpu_limits limits;
GraphicsStats stats;
Texture* window;
Pass* windowPass;
Font* defaultFont;
@ -736,10 +735,6 @@ void lovrGraphicsGetLimits(GraphicsLimits* limits) {
limits->pointSize = state.limits.pointSize;
}
void lovrGraphicsGetStats(GraphicsStats* stats) {
*stats = state.stats;
}
bool lovrGraphicsIsFormatSupported(uint32_t format, uint32_t features) {
uint8_t supports = state.features.formats[format];
if (!features) return supports;
@ -763,7 +758,6 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
return;
}
bool present = false;
uint32_t total = count + 1;
gpu_stream** streams = tempAlloc(total * sizeof(gpu_stream*));
gpu_barrier* barriers = tempAlloc(count * sizeof(gpu_barrier));
@ -819,26 +813,24 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
Canvas* canvas = &pass->info.canvas;
for (uint32_t j = 0; j < COUNTOF(canvas->textures) && canvas->textures[j]; j++) {
if (canvas->mipmap && canvas->textures[j]->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_COLOR;
if (canvas->mipmap) {
for (uint32_t j = 0; j < COUNTOF(canvas->textures) && canvas->textures[j]; j++) {
if (canvas->textures[j]->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_COLOR;
barriers[i].next |= GPU_PHASE_TRANSFER;
barriers[i].flush |= GPU_CACHE_COLOR_WRITE;
barriers[i].clear |= GPU_CACHE_TRANSFER_READ;
mipmapTexture(pass->stream, canvas->textures[j], 0, ~0u);
}
}
if (canvas->depth.texture && canvas->depth.texture->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_DEPTH_LATE;
barriers[i].next |= GPU_PHASE_TRANSFER;
barriers[i].flush |= GPU_CACHE_COLOR_WRITE;
barriers[i].flush |= GPU_CACHE_DEPTH_WRITE;
barriers[i].clear |= GPU_CACHE_TRANSFER_READ;
mipmapTexture(pass->stream, canvas->textures[j], 0, ~0u);
mipmapTexture(pass->stream, canvas->depth.texture, 0, ~0u);
}
if (canvas->textures[j] == state.window) {
present = true;
}
}
if (canvas->mipmap && canvas->depth.texture && canvas->depth.texture->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_DEPTH_LATE;
barriers[i].next |= GPU_PHASE_TRANSFER;
barriers[i].flush |= GPU_CACHE_DEPTH_WRITE;
barriers[i].clear |= GPU_CACHE_TRANSFER_READ;
mipmapTexture(pass->stream, canvas->depth.texture, 0, ~0u);
}
break;
case PASS_COMPUTE:
@ -958,20 +950,20 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
gpu_stream_end(streams[i]);
}
gpu_submit(streams, total, present);
state.stats.pipelineSwitches = 0;
state.stats.bundleSwitches = 0;
if (present) {
state.window->gpu = NULL;
state.window->renderView = NULL;
}
gpu_submit(streams, total);
state.stream = NULL;
state.active = false;
}
void lovrGraphicsPresent() {
if (state.window->gpu) {
state.window->gpu = NULL;
state.window->renderView = NULL;
gpu_present();
}
}
void lovrGraphicsWait() {
gpu_wait_idle();
}
@ -2857,8 +2849,6 @@ static void lovrModelReskin(Model* model) {
gpu_compute(state.stream, (skin->vertexCount + subgroupSize - 1) / subgroupSize, 1, 1);
gpu_compute_end(state.stream);
baseVertex += skin->vertexCount;
state.stats.pipelineSwitches++;
state.stats.bundleSwitches++;
}
state.hasReskin = true;
@ -3040,8 +3030,6 @@ static void lovrTallyResolve(Tally* tally, uint32_t index, uint32_t count, gpu_b
gpu_push_constants(stream, shader, &constants, sizeof(constants));
gpu_compute(stream, (count + 31) / 32, 1, 1);
gpu_compute_end(stream);
state.stats.pipelineSwitches++;
state.stats.bundleSwitches++;
}
// Pass
@ -4022,7 +4010,6 @@ static void flushPipeline(Pass* pass, Draw* draw, Shader* shader) {
}
gpu_bind_pipeline(pass->stream, state.pipelines.data[index], false);
state.stats.pipelineSwitches++;
pipeline->dirty = false;
}
@ -4055,7 +4042,6 @@ static void flushBindings(Pass* pass, Shader* shader) {
gpu_bundle* bundle = getBundle(shader->layout);
gpu_bundle_write(&bundle, &info, 1);
gpu_bind_bundle(pass->stream, shader->gpu, set, bundle, NULL, 0);
state.stats.bundleSwitches++;
tempPop(stack);
}
@ -4100,7 +4086,6 @@ static void flushBuiltins(Pass* pass, Draw* draw, Shader* shader) {
gpu_bundle* bundle = getBundle(state.builtinLayout);
gpu_bundle_write(&bundle, &bundleInfo, 1);
gpu_bind_bundle(pass->stream, shader->gpu, 0, bundle, NULL, 0);
state.stats.bundleSwitches++;
}
float m[16];
@ -4128,12 +4113,10 @@ static void flushBuiltins(Pass* pass, Draw* draw, Shader* shader) {
static void flushMaterial(Pass* pass, Draw* draw, Shader* shader) {
if (draw->material && draw->material != pass->pipeline->material) {
gpu_bind_bundle(pass->stream, shader->gpu, 1, draw->material->bundle, NULL, 0);
state.stats.bundleSwitches++;
pass->materialDirty = true;
} else if (pass->materialDirty) {
Material* material = pass->pipeline->material ? pass->pipeline->material : state.defaultMaterial;
gpu_bind_bundle(pass->stream, shader->gpu, 1, material->bundle, NULL, 0);
state.stats.bundleSwitches++;
pass->materialDirty = false;
}
}
@ -5077,7 +5060,6 @@ void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* ind
if (pass->pipeline->dirty) {
gpu_bind_pipeline(pass->stream, pipeline, true);
state.stats.pipelineSwitches++;
pass->pipeline->dirty = false;
}

View File

@ -83,11 +83,6 @@ typedef struct {
float pointSize;
} GraphicsLimits;
typedef struct {
uint32_t pipelineSwitches;
uint32_t bundleSwitches;
} GraphicsStats;
enum {
TEXTURE_FEATURE_SAMPLE = (1 << 0),
TEXTURE_FEATURE_FILTER = (1 << 1),
@ -105,11 +100,11 @@ void lovrGraphicsDestroy(void);
void lovrGraphicsGetDevice(GraphicsDevice* device);
void lovrGraphicsGetFeatures(GraphicsFeatures* features);
void lovrGraphicsGetLimits(GraphicsLimits* limits);
void lovrGraphicsGetStats(GraphicsStats* stats);
bool lovrGraphicsIsFormatSupported(uint32_t format, uint32_t features);
void lovrGraphicsGetShaderCache(void* data, size_t* size);
void lovrGraphicsSubmit(Pass** passes, uint32_t count);
void lovrGraphicsPresent(void);
void lovrGraphicsWait(void);
// Buffer

View File

@ -193,7 +193,26 @@ static Texture* desktop_getTexture(void) {
}
static Pass* desktop_getPass(void) {
return lovrGraphicsGetWindowPass();
Pass* pass = lovrGraphicsGetWindowPass();
lovrPassReset(pass);
float position[4], orientation[4];
desktop_getViewPose(0, position, orientation);
float viewMatrix[16];
mat4_fromQuat(viewMatrix, orientation);
memcpy(viewMatrix + 12, position, 3 * sizeof(float));
mat4_invert(viewMatrix);
float projection[16];
float left, right, up, down;
desktop_getViewAngles(0, &left, &right, &up, &down);
mat4_fov(projection, left, right, up, down, state.clipNear, state.clipFar);
lovrPassSetViewMatrix(pass, 0, viewMatrix);
lovrPassSetProjection(pass, 0, projection);
return pass;
}
static void desktop_submit(void) {