2016-11-19 09:28:01 +00:00
|
|
|
#include "graphics/graphics.h"
|
2022-04-21 07:27:13 +00:00
|
|
|
#include "core/gpu.h"
|
|
|
|
#include "util.h"
|
2022-04-20 07:38:21 +00:00
|
|
|
#include <string.h>
|
2019-06-28 05:17:50 +00:00
|
|
|
|
2019-06-27 08:47:08 +00:00
|
|
|
static struct {
|
|
|
|
bool initialized;
|
2022-04-22 20:28:59 +00:00
|
|
|
gpu_device_info device;
|
2022-04-21 09:16:17 +00:00
|
|
|
gpu_features features;
|
|
|
|
gpu_limits limits;
|
2019-06-27 08:47:08 +00:00
|
|
|
} state;
|
2016-07-07 07:04:24 +00:00
|
|
|
|
2022-04-21 07:27:13 +00:00
|
|
|
// Helpers
|
|
|
|
|
|
|
|
static void onMessage(void* context, const char* message, bool severe);
|
|
|
|
|
|
|
|
// Entry
|
|
|
|
|
|
|
|
bool lovrGraphicsInit(bool debug) {
|
2022-04-19 02:30:58 +00:00
|
|
|
if (state.initialized) return false;
|
2022-04-21 07:27:13 +00:00
|
|
|
|
|
|
|
gpu_config config = {
|
|
|
|
.debug = debug,
|
2022-04-21 09:16:17 +00:00
|
|
|
.callback = onMessage,
|
|
|
|
.device = &state.device,
|
|
|
|
.features = &state.features,
|
|
|
|
.limits = &state.limits
|
2022-04-21 07:27:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (!gpu_init(&config)) {
|
|
|
|
lovrThrow("Failed to initialize GPU");
|
|
|
|
}
|
|
|
|
|
2022-04-19 02:30:58 +00:00
|
|
|
state.initialized = true;
|
|
|
|
return true;
|
2016-09-28 03:20:08 +00:00
|
|
|
}
|
|
|
|
|
2016-10-04 22:13:57 +00:00
|
|
|
void lovrGraphicsDestroy() {
|
2018-02-23 03:18:36 +00:00
|
|
|
if (!state.initialized) return;
|
2022-04-21 07:27:13 +00:00
|
|
|
gpu_destroy();
|
2019-06-27 08:47:08 +00:00
|
|
|
memset(&state, 0, sizeof(state));
|
2016-07-07 07:04:24 +00:00
|
|
|
}
|
2022-04-21 07:27:13 +00:00
|
|
|
|
2022-04-21 09:16:17 +00:00
|
|
|
void lovrGraphicsGetDevice(GraphicsDevice* device) {
|
2022-04-22 20:28:59 +00:00
|
|
|
device->deviceId = state.device.deviceId;
|
|
|
|
device->vendorId = state.device.vendorId;
|
|
|
|
device->name = state.device.deviceName;
|
2022-04-21 09:16:17 +00:00
|
|
|
device->renderer = state.device.renderer;
|
|
|
|
device->subgroupSize = state.device.subgroupSize;
|
2022-04-22 20:28:59 +00:00
|
|
|
device->discrete = state.device.discrete;
|
2022-04-21 09:16:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsGetFeatures(GraphicsFeatures* features) {
|
2022-04-26 22:31:51 +00:00
|
|
|
features->textureBC = state.features.textureBC;
|
|
|
|
features->textureASTC = state.features.textureASTC;
|
2022-04-21 09:16:17 +00:00
|
|
|
features->wireframe = state.features.wireframe;
|
|
|
|
features->depthClamp = state.features.depthClamp;
|
|
|
|
features->indirectDrawFirstInstance = state.features.indirectDrawFirstInstance;
|
|
|
|
features->float64 = state.features.float64;
|
|
|
|
features->int64 = state.features.int64;
|
|
|
|
features->int16 = state.features.int16;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsGetLimits(GraphicsLimits* limits) {
|
|
|
|
limits->textureSize2D = state.limits.textureSize2D;
|
|
|
|
limits->textureSize3D = state.limits.textureSize3D;
|
|
|
|
limits->textureSizeCube = state.limits.textureSizeCube;
|
|
|
|
limits->textureLayers = state.limits.textureLayers;
|
|
|
|
limits->renderSize[0] = state.limits.renderSize[0];
|
|
|
|
limits->renderSize[1] = state.limits.renderSize[1];
|
|
|
|
limits->renderSize[2] = state.limits.renderSize[2];
|
|
|
|
limits->uniformBufferRange = state.limits.uniformBufferRange;
|
|
|
|
limits->storageBufferRange = state.limits.storageBufferRange;
|
|
|
|
limits->uniformBufferAlign = state.limits.uniformBufferAlign;
|
|
|
|
limits->storageBufferAlign = state.limits.storageBufferAlign;
|
|
|
|
limits->vertexAttributes = state.limits.vertexAttributes;
|
|
|
|
limits->vertexBufferStride = state.limits.vertexBufferStride;
|
|
|
|
limits->vertexShaderOutputs = state.limits.vertexShaderOutputs;
|
2022-04-26 22:31:51 +00:00
|
|
|
limits->clipDistances = state.limits.clipDistances;
|
|
|
|
limits->cullDistances = state.limits.cullDistances;
|
|
|
|
limits->clipAndCullDistances = state.limits.clipAndCullDistances;
|
2022-04-21 09:16:17 +00:00
|
|
|
memcpy(limits->computeDispatchCount, state.limits.computeDispatchCount, 3 * sizeof(uint32_t));
|
|
|
|
memcpy(limits->computeWorkgroupSize, state.limits.computeWorkgroupSize, 3 * sizeof(uint32_t));
|
|
|
|
limits->computeWorkgroupVolume = state.limits.computeWorkgroupVolume;
|
|
|
|
limits->computeSharedMemory = state.limits.computeSharedMemory;
|
|
|
|
limits->shaderConstantSize = state.limits.pushConstantSize;
|
|
|
|
limits->indirectDrawCount = state.limits.indirectDrawCount;
|
|
|
|
limits->instances = state.limits.instances;
|
|
|
|
limits->anisotropy = state.limits.anisotropy;
|
|
|
|
limits->pointSize = state.limits.pointSize;
|
|
|
|
}
|
|
|
|
|
2022-04-21 07:27:13 +00:00
|
|
|
// Helpers
|
|
|
|
|
|
|
|
static void onMessage(void* context, const char* message, bool severe) {
|
|
|
|
if (severe) {
|
|
|
|
lovrLog(LOG_ERROR, "GPU", message);
|
|
|
|
} else {
|
|
|
|
lovrLog(LOG_DEBUG, "GPU", message);
|
|
|
|
}
|
|
|
|
}
|