mirror of
https://github.com/love2d/love.git
synced 2026-08-12 00:20:52 +02:00
Add new Graphics::Features.
This commit is contained in:
@@ -2988,6 +2988,9 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
|
||||
{ "texelbuffer", Graphics::FEATURE_TEXEL_BUFFER },
|
||||
{ "copytexturetobuffer", Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER },
|
||||
{ "indirectdraw", Graphics::FEATURE_INDIRECT_DRAW },
|
||||
{ "vertexwrite", Graphics::FEATURE_VERTEX_WRITE },
|
||||
{ "pixelwrite", Graphics::FEATURE_PIXEL_WRITE },
|
||||
{ "imageatomics", Graphics::FEATURE_IMAGE_ATOMICS },
|
||||
}
|
||||
STRINGMAP_CLASS_END(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, feature)
|
||||
|
||||
|
||||
@@ -163,6 +163,9 @@ public:
|
||||
FEATURE_TEXEL_BUFFER,
|
||||
FEATURE_COPY_TEXTURE_TO_BUFFER,
|
||||
FEATURE_INDIRECT_DRAW,
|
||||
FEATURE_VERTEX_WRITE,
|
||||
FEATURE_PIXEL_WRITE,
|
||||
FEATURE_IMAGE_ATOMICS,
|
||||
FEATURE_MAX_ENUM
|
||||
};
|
||||
|
||||
|
||||
@@ -1307,6 +1307,7 @@ bool Shader::validateInternal(StrongRef<ShaderStage> stages[], std::string &err,
|
||||
reflection.textureCount = 0;
|
||||
reflection.bufferCount = 0;
|
||||
|
||||
auto &capabilities = Module::getInstance<Graphics>(Module::M_GRAPHICS)->getCapabilities();
|
||||
for (int i = 0; i < program.getNumUniformVariables(); i++)
|
||||
{
|
||||
const glslang::TObjectReflection &info = program.getUniform(i);
|
||||
@@ -1349,12 +1350,24 @@ bool Shader::validateInternal(StrongRef<ShaderStage> stages[], std::string &err,
|
||||
}
|
||||
else if (type->isImage())
|
||||
{
|
||||
if ((info.stages & (~EShLangComputeMask)) != 0 && !options.features[FEATURE_STORAGE_TEXTURES])
|
||||
if ((info.stages & (~EShLangComputeMask)) != 0 && !options.features[FEATURE_WRITE])
|
||||
{
|
||||
err = "Shader validation error:\nStorage Texture uniform variables (image2D, etc) are only allowed in compute shaders unless explicitly enabled.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && ((info.stages & (~EShLangFragmentMask)) != 0) && !capabilities.features[Graphics::FEATURE_PIXEL_WRITE])
|
||||
{
|
||||
err = "Shader validation error:\nPlatform does not have writable Storage Texture uniform variables (image2D, etc) capabilities in pixel shaders.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && ((info.stages & (~EShLangVertexMask)) != 0) && !capabilities.features[Graphics::FEATURE_VERTEX_WRITE])
|
||||
{
|
||||
err = "Shader validation error:\nPlatform does not have writable Storage Texture uniform variables (image2D, etc) capabilities in vertex shaders.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!qualifiers.hasFormat())
|
||||
{
|
||||
err = "Shader validation error:\nStorage Texture '" + u.name + "' must have an explicit format set in its layout declaration.";
|
||||
@@ -1467,11 +1480,23 @@ bool Shader::validateInternal(StrongRef<ShaderStage> stages[], std::string &err,
|
||||
{
|
||||
const glslang::TQualifier &qualifiers = type->getQualifier();
|
||||
|
||||
if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && ((info.stages & (~EShLangComputeMask)) != 0) && !options.features[FEATURE_WRITABLE_BUFFERS])
|
||||
if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && ((info.stages & (~EShLangComputeMask)) != 0) && !options.features[FEATURE_WRITE])
|
||||
{
|
||||
err = "Shader validation error:\nStorage Buffer block '" + info.name + "' must be marked as readonly in vertex and pixel shaders unless explicitly enabled.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && ((info.stages & (~EShLangFragmentMask)) != 0) && !capabilities.features[Graphics::FEATURE_PIXEL_WRITE])
|
||||
{
|
||||
err = "Shader validation error:\nPlatform does not have writable Storage Buffer blocks capabilities in pixel shaders.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!qualifiers.isReadOnly() || qualifiers.isWriteOnly()) && ((info.stages & (~EShLangVertexMask)) != 0) && !capabilities.features[Graphics::FEATURE_VERTEX_WRITE])
|
||||
{
|
||||
err = "Shader validation error:\nPlatform does not have writable Storage Buffer blocks capabilities in vertex shaders.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (qualifiers.layoutPacking != glslang::ElpStd430)
|
||||
{
|
||||
|
||||
@@ -2250,8 +2250,24 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
|
||||
else
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = false;
|
||||
|
||||
// Apple 3 devices support read/write to buffers in functions, while Apple 4 supports read/write to images.
|
||||
// So let's err on the safe side and check support for Apple 4.
|
||||
if (families.apple[4])
|
||||
{
|
||||
capabilities.features[FEATURE_VERTEX_WRITE] = true;
|
||||
capabilities.features[FEATURE_PIXEL_WRITE] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
capabilities.features[FEATURE_VERTEX_WRITE] = false;
|
||||
capabilities.features[FEATURE_PIXEL_WRITE] = false;
|
||||
}
|
||||
|
||||
// Not supported until Metal 3
|
||||
capabilities.features[FEATURE_IMAGE_ATOMICS] = false;
|
||||
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
static_assert(FEATURE_MAX_ENUM == 16, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
|
||||
capabilities.limits[LIMIT_POINT_SIZE] = 511;
|
||||
|
||||
@@ -1632,7 +1632,10 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = gl.isBufferUsageSupported(BUFFERUSAGE_TEXEL);
|
||||
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = gl.isCopyTextureToBufferSupported();
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = capabilities.features[FEATURE_GLSL4];
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
capabilities.features[FEATURE_VERTEX_WRITE] = true;
|
||||
capabilities.features[FEATURE_PIXEL_WRITE] = true;
|
||||
capabilities.features[FEATURE_IMAGE_ATOMICS] = true;
|
||||
static_assert(FEATURE_MAX_ENUM == 16, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
|
||||
capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
|
||||
|
||||
@@ -821,6 +821,8 @@ bool Graphics::setMode(void *context, const BackbufferSettings &settings)
|
||||
|
||||
void Graphics::initCapabilities()
|
||||
{
|
||||
VkPhysicalDeviceFeatures features;
|
||||
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
|
||||
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ZERO] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ONE] = true;
|
||||
@@ -834,7 +836,10 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = true;
|
||||
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
capabilities.features[FEATURE_VERTEX_WRITE] = features.vertexPipelineStoresAndAtomics;
|
||||
capabilities.features[FEATURE_PIXEL_WRITE] = features.fragmentStoresAndAtomics;
|
||||
capabilities.features[FEATURE_IMAGE_ATOMICS] = true;
|
||||
static_assert(FEATURE_MAX_ENUM == 16, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||
|
||||
Reference in New Issue
Block a user