isFormatSupported;

This commit is contained in:
bjorn 2022-04-29 17:12:10 -07:00
parent bc6b98123b
commit e53ddfa03b
6 changed files with 82 additions and 0 deletions

View File

@ -54,6 +54,7 @@ extern StringEntry lovrShaderType[];
extern StringEntry lovrShapeType[];
extern StringEntry lovrSmoothMode[];
extern StringEntry lovrStencilAction[];
extern StringEntry lovrTextureFeature[];
extern StringEntry lovrTextureFormat[];
extern StringEntry lovrTextureType[];
extern StringEntry lovrTimeUnit[];

View File

@ -1,6 +1,7 @@
#include "api.h"
#include "graphics/graphics.h"
#include "data/blob.h"
#include "data/image.h"
#include "util.h"
#include <lua.h>
#include <lauxlib.h>
@ -49,6 +50,18 @@ StringEntry lovrFieldType[] = {
{ 0 }
};
StringEntry lovrTextureFeature[] = {
[0] = ENTRY("sample"),
[1] = ENTRY("filter"),
[2] = ENTRY("render"),
[3] = ENTRY("blend"),
[4] = ENTRY("storage"),
[5] = ENTRY("atomic"),
[6] = ENTRY("blitsrc"),
[7] = ENTRY("blitdst"),
{ 0 }
};
static struct { uint32_t size, scalarAlign, baseAlign, components; } fieldInfo[] = {
[FIELD_I8x4] = { 4, 1, 4, 4 },
[FIELD_U8x4] = { 4, 1, 4, 4 },
@ -324,6 +337,18 @@ static int l_lovrGraphicsGetLimits(lua_State* L) {
return 1;
}
static int l_lovrGraphicsIsFormatSupported(lua_State* L) {
TextureFormat format = luax_checkenum(L, 1, TextureFormat, NULL);
uint32_t features = 0;
int top = lua_gettop(L);
for (int i = 2; i <= top; i++) {
features |= 1 << luax_checkenum(L, i, TextureFeature, NULL);
}
bool supported = lovrGraphicsIsFormatSupported(format, features);
lua_pushboolean(L, supported);
return 1;
}
static int l_lovrGraphicsNewBuffer(lua_State* L) {
BufferInfo info = { 0 };
@ -397,6 +422,7 @@ static const luaL_Reg lovrGraphics[] = {
{ "getDevice", l_lovrGraphicsGetDevice },
{ "getFeatures", l_lovrGraphicsGetFeatures },
{ "getLimits", l_lovrGraphicsGetLimits },
{ "isFormatSupported", l_lovrGraphicsIsFormatSupported },
{ "newBuffer", l_lovrGraphicsNewBuffer },
{ "buffer", l_lovrGraphicsBuffer },
{ NULL, NULL }

View File

@ -142,7 +142,19 @@ typedef struct {
bool discrete;
} gpu_device_info;
enum {
GPU_FEATURE_SAMPLE = (1 << 0),
GPU_FEATURE_RENDER = (1 << 1),
GPU_FEATURE_BLEND = (1 << 2),
GPU_FEATURE_FILTER = (1 << 3),
GPU_FEATURE_STORAGE = (1 << 4),
GPU_FEATURE_ATOMIC = (1 << 5),
GPU_FEATURE_BLIT_SRC = (1 << 6),
GPU_FEATURE_BLIT_DST = (1 << 7)
};
typedef struct {
uint8_t formats[GPU_FORMAT_COUNT];
bool textureBC;
bool textureASTC;
bool wireframe;

View File

@ -708,6 +708,23 @@ bool gpu_init(gpu_config* config) {
config->features->float64 = enable->shaderFloat64 = supports->shaderFloat64;
config->features->int64 = enable->shaderInt64 = supports->shaderInt64;
config->features->int16 = enable->shaderInt16 = supports->shaderInt16;
// Formats
for (uint32_t i = 0; i < GPU_FORMAT_COUNT; i++) {
VkFormatProperties formatProperties;
vkGetPhysicalDeviceFormatProperties(state.adapter, convertFormat(i, LINEAR), &formatProperties);
uint32_t renderMask = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
uint32_t flags = formatProperties.optimalTilingFeatures;
config->features->formats[i] =
((flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? GPU_FEATURE_SAMPLE : 0) |
((flags & renderMask) ? GPU_FEATURE_RENDER : 0) |
((flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? GPU_FEATURE_BLEND : 0) |
((flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ? GPU_FEATURE_FILTER : 0) |
((flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? GPU_FEATURE_STORAGE : 0) |
((flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? GPU_FEATURE_ATOMIC : 0) |
((flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? GPU_FEATURE_BLIT_SRC : 0) |
((flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? GPU_FEATURE_BLIT_DST : 0);
}
}
state.queueFamilyIndex = ~0u;

View File

@ -131,6 +131,20 @@ void lovrGraphicsGetLimits(GraphicsLimits* limits) {
limits->pointSize = state.limits.pointSize;
}
bool lovrGraphicsIsFormatSupported(uint32_t format, uint32_t features) {
uint8_t supports = state.features.formats[format];
if (!features) return supports;
if ((features & TEXTURE_FEATURE_SAMPLE) && !(supports & GPU_FEATURE_SAMPLE)) return false;
if ((features & TEXTURE_FEATURE_FILTER) && !(supports & GPU_FEATURE_FILTER)) return false;
if ((features & TEXTURE_FEATURE_RENDER) && !(supports & GPU_FEATURE_RENDER)) return false;
if ((features & TEXTURE_FEATURE_BLEND) && !(supports & GPU_FEATURE_BLEND)) return false;
if ((features & TEXTURE_FEATURE_STORAGE) && !(supports & GPU_FEATURE_STORAGE)) return false;
if ((features & TEXTURE_FEATURE_ATOMIC) && !(supports & GPU_FEATURE_ATOMIC)) return false;
if ((features & TEXTURE_FEATURE_BLIT_SRC) && !(supports & GPU_FEATURE_BLIT_SRC)) return false;
if ((features & TEXTURE_FEATURE_BLIT_DST) && !(supports & GPU_FEATURE_BLIT_DST)) return false;
return true;
}
void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
if (!state.active) {
return;

View File

@ -53,12 +53,24 @@ typedef struct {
float pointSize;
} GraphicsLimits;
enum {
TEXTURE_FEATURE_SAMPLE = (1 << 0),
TEXTURE_FEATURE_FILTER = (1 << 1),
TEXTURE_FEATURE_RENDER = (1 << 2),
TEXTURE_FEATURE_BLEND = (1 << 3),
TEXTURE_FEATURE_STORAGE = (1 << 4),
TEXTURE_FEATURE_ATOMIC = (1 << 5),
TEXTURE_FEATURE_BLIT_SRC = (1 << 6),
TEXTURE_FEATURE_BLIT_DST = (1 << 7)
};
bool lovrGraphicsInit(bool debug);
void lovrGraphicsDestroy(void);
void lovrGraphicsGetDevice(GraphicsDevice* device);
void lovrGraphicsGetFeatures(GraphicsFeatures* features);
void lovrGraphicsGetLimits(GraphicsLimits* limits);
bool lovrGraphicsIsFormatSupported(uint32_t format, uint32_t features);
void lovrGraphicsSubmit(Pass** passes, uint32_t count);
void lovrGraphicsWait(void);