Commit 5d0458fa by Mohan Maiya Committed by Commit Bot

Vulkan: Add OES_shader_multisample_interpolation support

Support OES_shader_multisample_interpolation extension if maxInterpolationOffset >= 0.5 Bug: angleproject:3589 Tests: dEQP-GLES31.functional.shaders.multisample_interpolation.* dEQP-GLES31.functional.state_query.multisample_interpolation.* Change-Id: I42997f10be82e3be8b63c56833cbbf791bf4be9b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2477905 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 5c4c37dc
...@@ -28,6 +28,7 @@ enum InterpolationType ...@@ -28,6 +28,7 @@ enum InterpolationType
{ {
INTERPOLATION_SMOOTH, INTERPOLATION_SMOOTH,
INTERPOLATION_CENTROID, INTERPOLATION_CENTROID,
INTERPOLATION_SAMPLE,
INTERPOLATION_FLAT, INTERPOLATION_FLAT,
INTERPOLATION_NOPERSPECTIVE INTERPOLATION_NOPERSPECTIVE
}; };
......
...@@ -981,10 +981,12 @@ enum TQualifier ...@@ -981,10 +981,12 @@ enum TQualifier
EvqFlatOut, EvqFlatOut,
EvqNoPerspectiveOut, EvqNoPerspectiveOut,
EvqCentroidOut, // Implies smooth EvqCentroidOut, // Implies smooth
EvqSampleOut,
EvqSmoothIn, EvqSmoothIn,
EvqFlatIn, EvqFlatIn,
EvqNoPerspectiveIn, EvqNoPerspectiveIn,
EvqCentroidIn, // Implies smooth EvqCentroidIn, // Implies smooth
EvqSampleIn,
// GLSL ES 3.1 compute shader special variables // GLSL ES 3.1 compute shader special variables
EvqShared, EvqShared,
...@@ -1042,6 +1044,7 @@ inline bool IsShaderIn(TQualifier qualifier) ...@@ -1042,6 +1044,7 @@ inline bool IsShaderIn(TQualifier qualifier)
case EvqFlatIn: case EvqFlatIn:
case EvqNoPerspectiveIn: case EvqNoPerspectiveIn:
case EvqCentroidIn: case EvqCentroidIn:
case EvqSampleIn:
return true; return true;
default: default:
return false; return false;
...@@ -1060,6 +1063,7 @@ inline bool IsShaderOut(TQualifier qualifier) ...@@ -1060,6 +1063,7 @@ inline bool IsShaderOut(TQualifier qualifier)
case EvqFlatOut: case EvqFlatOut:
case EvqNoPerspectiveOut: case EvqNoPerspectiveOut:
case EvqCentroidOut: case EvqCentroidOut:
case EvqSampleOut:
return true; return true;
default: default:
return false; return false;
...@@ -1333,6 +1337,9 @@ inline const char *getQualifierString(TQualifier q) ...@@ -1333,6 +1337,9 @@ inline const char *getQualifierString(TQualifier q)
case EvqPerVertexIn: return "gl_in"; case EvqPerVertexIn: return "gl_in";
case EvqPrecise: return "precise"; case EvqPrecise: return "precise";
case EvqClipDistance: return "ClipDistance"; case EvqClipDistance: return "ClipDistance";
case EvqSample: return "sample";
case EvqSampleIn: return "sample in";
case EvqSampleOut: return "sample out";
default: UNREACHABLE(); return "unknown qualifier"; default: UNREACHABLE(); return "unknown qualifier";
} }
// clang-format on // clang-format on
......
...@@ -732,6 +732,7 @@ ShaderVariable CollectVariablesTraverser::recordVarying(const TIntermSymbol &var ...@@ -732,6 +732,7 @@ ShaderVariable CollectVariablesTraverser::recordVarying(const TIntermSymbol &var
case EvqNoPerspectiveOut: case EvqNoPerspectiveOut:
case EvqCentroidOut: case EvqCentroidOut:
case EvqGeometryOut: case EvqGeometryOut:
case EvqSampleOut:
if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant()) if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant())
{ {
varying.isInvariant = true; varying.isInvariant = true;
......
...@@ -1090,6 +1090,7 @@ void TCompiler::setResourceString() ...@@ -1090,6 +1090,7 @@ void TCompiler::setResourceString()
<< ":OES_texture_cube_map_array:" << mResources.OES_texture_cube_map_array << ":OES_texture_cube_map_array:" << mResources.OES_texture_cube_map_array
<< ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array << ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array
<< ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers << ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers
<< ":OES_shader_multisample_interpolation:" << mResources.OES_shader_multisample_interpolation
<< ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset << ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset
<< ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset << ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset
<< ":MaxImageUnits:" << mResources.MaxImageUnits << ":MaxImageUnits:" << mResources.MaxImageUnits
......
...@@ -129,6 +129,10 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi ...@@ -129,6 +129,10 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi
{ {
extBehavior[TExtension::EXT_shadow_samplers] = EBhUndefined; extBehavior[TExtension::EXT_shadow_samplers] = EBhUndefined;
} }
if (resources.OES_shader_multisample_interpolation)
{
extBehavior[TExtension::OES_shader_multisample_interpolation] = EBhUndefined;
}
} }
void ResetExtensionBehavior(const ShBuiltInResources &resources, void ResetExtensionBehavior(const ShBuiltInResources &resources,
......
...@@ -128,6 +128,26 @@ bool IsBufferOrSharedVariable(TIntermTyped *var) ...@@ -128,6 +128,26 @@ bool IsBufferOrSharedVariable(TIntermTyped *var)
return false; return false;
} }
TIntermTyped *FindLValueBase(TIntermTyped *node)
{
do
{
const TIntermBinary *binary = node->getAsBinaryNode();
if (binary == nullptr)
{
return node;
}
TOperator op = binary->getOp();
if (op != EOpIndexDirect && op != EOpIndexIndirect)
{
return static_cast<TIntermTyped *>(nullptr);
}
node = binary->getLeft();
} while (true);
}
} // namespace } // namespace
// This tracks each binding point's current default offset for inheritance of subsequent // This tracks each binding point's current default offset for inheritance of subsequent
...@@ -534,6 +554,7 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn ...@@ -534,6 +554,7 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
case EvqNoPerspectiveIn: case EvqNoPerspectiveIn:
case EvqSmoothIn: case EvqSmoothIn:
case EvqCentroidIn: case EvqCentroidIn:
case EvqSampleIn:
message = "can't modify an input"; message = "can't modify an input";
break; break;
case EvqUniform: case EvqUniform:
...@@ -5983,6 +6004,41 @@ void TParseContext::checkSingleTextureOffset(const TSourceLoc &line, ...@@ -5983,6 +6004,41 @@ void TParseContext::checkSingleTextureOffset(const TSourceLoc &line,
} }
} }
void TParseContext::checkInterpolationFS(TIntermAggregate *functionCall)
{
const TFunction *func = functionCall->getFunction();
if (!BuiltInGroup::isInterpolationFS(func))
{
return;
}
TIntermTyped *arg0 = nullptr;
if (functionCall->getAsAggregate())
{
const TIntermSequence *argp = functionCall->getSequence();
if (argp->size() > 0)
arg0 = (*argp)[0]->getAsTyped();
}
else
{
assert(functionCall->getAsUnaryNode());
arg0 = functionCall->getAsUnaryNode()->getOperand();
}
// Make sure the first argument is an interpolant, or an array element of an interpolant
if (!IsVaryingIn(arg0->getType().getQualifier()))
{
// It might still be an array element.
const TIntermTyped *base = FindLValueBase(arg0);
if (base == nullptr || (!IsVaryingIn(base->getType().getQualifier())))
error(arg0->getLine(),
"first argument must be an interpolant, or interpolant-array element",
func->name());
}
}
void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall) void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
{ {
const TFunction *func = functionCall->getFunction(); const TFunction *func = functionCall->getFunction();
...@@ -6248,6 +6304,7 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCa ...@@ -6248,6 +6304,7 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCa
callNode->setLine(loc); callNode->setLine(loc);
checkTextureOffset(callNode); checkTextureOffset(callNode);
checkTextureGather(callNode); checkTextureGather(callNode);
checkInterpolationFS(callNode);
checkImageMemoryAccessForBuiltinFunctions(callNode); checkImageMemoryAccessForBuiltinFunctions(callNode);
functionCallRValueLValueErrorCheck(fnCandidate, callNode); functionCallRValueLValueErrorCheck(fnCandidate, callNode);
return callNode; return callNode;
......
...@@ -441,6 +441,7 @@ class TParseContext : angle::NonCopyable ...@@ -441,6 +441,7 @@ class TParseContext : angle::NonCopyable
void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition, void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
const TIntermAggregate *functionCall); const TIntermAggregate *functionCall);
void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall); void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
void checkInterpolationFS(TIntermAggregate *functionCall);
// fnCall is only storing the built-in op, and function name or constructor type. arguments // fnCall is only storing the built-in op, and function name or constructor type. arguments
// has the arguments. // has the arguments.
......
...@@ -440,6 +440,23 @@ bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storag ...@@ -440,6 +440,23 @@ bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storag
} }
break; break;
} }
case EvqSample:
{
switch (storageQualifier)
{
case EvqVertexOut:
case EvqGeometryOut:
*joinedQualifier = EvqSampleOut;
break;
case EvqFragmentIn:
case EvqGeometryIn:
*joinedQualifier = EvqSampleIn;
break;
default:
return false;
}
break;
}
default: default:
return false; return false;
} }
......
...@@ -1063,6 +1063,8 @@ const char *InterpolationString(TQualifier qualifier) ...@@ -1063,6 +1063,8 @@ const char *InterpolationString(TQualifier qualifier)
return "nointerpolation"; return "nointerpolation";
case EvqCentroidOut: case EvqCentroidOut:
return "centroid"; return "centroid";
case EvqSampleIn:
return "sample";
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -1083,6 +1085,8 @@ const char *QualifierString(TQualifier qualifier) ...@@ -1083,6 +1085,8 @@ const char *QualifierString(TQualifier qualifier)
return "inout"; return "inout";
case EvqConstReadOnly: case EvqConstReadOnly:
return "const"; return "const";
case EvqSampleOut:
return "sample";
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -35,6 +35,7 @@ bool IsInterpolationIn(TQualifier qualifier) ...@@ -35,6 +35,7 @@ bool IsInterpolationIn(TQualifier qualifier)
case EvqFlatIn: case EvqFlatIn:
case EvqNoPerspectiveIn: case EvqNoPerspectiveIn:
case EvqCentroidIn: case EvqCentroidIn:
case EvqSampleIn:
return true; return true;
default: default:
return false; return false;
...@@ -538,6 +539,7 @@ bool IsVaryingOut(TQualifier qualifier) ...@@ -538,6 +539,7 @@ bool IsVaryingOut(TQualifier qualifier)
case EvqCentroidOut: case EvqCentroidOut:
case EvqVertexOut: case EvqVertexOut:
case EvqGeometryOut: case EvqGeometryOut:
case EvqSampleOut:
return true; return true;
default: default:
...@@ -558,6 +560,7 @@ bool IsVaryingIn(TQualifier qualifier) ...@@ -558,6 +560,7 @@ bool IsVaryingIn(TQualifier qualifier)
case EvqCentroidIn: case EvqCentroidIn:
case EvqFragmentIn: case EvqFragmentIn:
case EvqGeometryIn: case EvqGeometryIn:
case EvqSampleIn:
return true; return true;
default: default:
...@@ -604,6 +607,9 @@ InterpolationType GetInterpolationType(TQualifier qualifier) ...@@ -604,6 +607,9 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
case EvqCentroidOut: case EvqCentroidOut:
return INTERPOLATION_CENTROID; return INTERPOLATION_CENTROID;
case EvqSampleIn:
case EvqSampleOut:
return INTERPOLATION_SAMPLE;
default: default:
UNREACHABLE(); UNREACHABLE();
#if !UNREACHABLE_IS_NORETURN #if !UNREACHABLE_IS_NORETURN
......
...@@ -1036,6 +1036,7 @@ const ExtensionInfoMap &GetExtensionInfoMap() ...@@ -1036,6 +1036,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_EXT_buffer_storage"] = enableableExtension(&Extensions::bufferStorageEXT); map["GL_EXT_buffer_storage"] = enableableExtension(&Extensions::bufferStorageEXT);
map["GL_OES_texture_stencil8"] = enableableExtension(&Extensions::stencilIndex8); map["GL_OES_texture_stencil8"] = enableableExtension(&Extensions::stencilIndex8);
map["GL_OES_sample_shading"] = enableableExtension(&Extensions::sampleShadingOES); map["GL_OES_sample_shading"] = enableableExtension(&Extensions::sampleShadingOES);
map["GL_OES_shader_multisample_interpolation"] = enableableExtension(&Extensions::multisampleInterpolationOES);
map["GL_NV_robustness_video_memory_purge"] = esOnlyExtension(&Extensions::robustnessVideoMemoryPurgeNV); map["GL_NV_robustness_video_memory_purge"] = esOnlyExtension(&Extensions::robustnessVideoMemoryPurgeNV);
map["GL_ANGLE_get_tex_level_parameter"] = enableableExtension(&Extensions::getTexLevelParameterANGLE); map["GL_ANGLE_get_tex_level_parameter"] = enableableExtension(&Extensions::getTexLevelParameterANGLE);
// GLES1 extensions // GLES1 extensions
......
...@@ -654,6 +654,9 @@ struct Extensions ...@@ -654,6 +654,9 @@ struct Extensions
// GL_OES_sample_shading // GL_OES_sample_shading
bool sampleShadingOES = false; bool sampleShadingOES = false;
// OES_shader_multisample_interpolation
bool multisampleInterpolationOES = false;
// GL_NV_robustness_video_memory_purge // GL_NV_robustness_video_memory_purge
bool robustnessVideoMemoryPurgeNV = false; bool robustnessVideoMemoryPurgeNV = false;
...@@ -746,6 +749,10 @@ struct Caps ...@@ -746,6 +749,10 @@ struct Caps
// be GLint instead of GLuint and call LimitToInt() to ensure // be GLint instead of GLuint and call LimitToInt() to ensure
// they will not overflow. // they will not overflow.
GLfloat minInterpolationOffset = 0;
GLfloat maxInterpolationOffset = 0;
GLint subPixelInterpolationOffsetBits = 0;
// ES 3.1 (April 29, 2015) 20.39: implementation dependent values // ES 3.1 (April 29, 2015) 20.39: implementation dependent values
GLint64 maxElementIndex = 0; GLint64 maxElementIndex = 0;
GLint max3DTextureSize = 0; GLint max3DTextureSize = 0;
......
...@@ -110,7 +110,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp ...@@ -110,7 +110,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp
mResources.ANGLE_multi_draw = extensions.multiDraw; mResources.ANGLE_multi_draw = extensions.multiDraw;
mResources.ANGLE_base_vertex_base_instance = extensions.baseVertexBaseInstance; mResources.ANGLE_base_vertex_base_instance = extensions.baseVertexBaseInstance;
mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE; mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE;
// OES_shader_multisample_interpolation
mResources.OES_shader_multisample_interpolation = extensions.multisampleInterpolationOES;
// TODO: use shader precision caps to determine if high precision is supported? // TODO: use shader precision caps to determine if high precision is supported?
mResources.FragmentPrecisionHigh = 1; mResources.FragmentPrecisionHigh = 1;
mResources.EXT_frag_depth = extensions.fragDepth; mResources.EXT_frag_depth = extensions.fragDepth;
......
...@@ -1419,6 +1419,12 @@ void Context::getFloatvImpl(GLenum pname, GLfloat *params) const ...@@ -1419,6 +1419,12 @@ void Context::getFloatvImpl(GLenum pname, GLfloat *params) const
case GL_MAX_TEXTURE_LOD_BIAS: case GL_MAX_TEXTURE_LOD_BIAS:
*params = mState.mCaps.maxLODBias; *params = mState.mCaps.maxLODBias;
break; break;
case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET:
*params = mState.mCaps.minInterpolationOffset;
break;
case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET:
*params = mState.mCaps.maxInterpolationOffset;
break;
default: default:
mState.getFloatv(pname, params); mState.getFloatv(pname, params);
break; break;
...@@ -1850,7 +1856,10 @@ void Context::getIntegervImpl(GLenum pname, GLint *params) const ...@@ -1850,7 +1856,10 @@ void Context::getIntegervImpl(GLenum pname, GLint *params) const
case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT: case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT:
*params = mState.mExtensions.maxDualSourceDrawBuffers; *params = mState.mExtensions.maxDualSourceDrawBuffers;
break; break;
// OES_shader_multisample_interpolation
case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
*params = mState.mCaps.subPixelInterpolationOffsetBits;
break;
default: default:
ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params)); ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params));
break; break;
......
...@@ -3567,6 +3567,7 @@ bool GetQueryParameterInfo(const State &glState, ...@@ -3567,6 +3567,7 @@ bool GetQueryParameterInfo(const State &glState,
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
case GL_UNPACK_IMAGE_HEIGHT: case GL_UNPACK_IMAGE_HEIGHT:
case GL_UNPACK_SKIP_IMAGES: case GL_UNPACK_SKIP_IMAGES:
case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
{ {
*type = GL_INT; *type = GL_INT;
*numParams = 1; *numParams = 1;
...@@ -3595,6 +3596,8 @@ bool GetQueryParameterInfo(const State &glState, ...@@ -3595,6 +3596,8 @@ bool GetQueryParameterInfo(const State &glState,
} }
case GL_MAX_TEXTURE_LOD_BIAS: case GL_MAX_TEXTURE_LOD_BIAS:
case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES:
case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES:
{ {
*type = GL_FLOAT; *type = GL_FLOAT;
*numParams = 1; *numParams = 1;
......
...@@ -435,6 +435,9 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, ...@@ -435,6 +435,9 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking,
case sh::INTERPOLATION_CENTROID: case sh::INTERPOLATION_CENTROID:
hlslStream << " centroid "; hlslStream << " centroid ";
break; break;
case sh::INTERPOLATION_SAMPLE:
hlslStream << " sample ";
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -272,7 +272,29 @@ void RendererVk::ensureCapsInitialized() const ...@@ -272,7 +272,29 @@ void RendererVk::ensureCapsInitialized() const
// VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE and the // VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE and the
// minSampleShading member is ignored. This also specifies whether shader modules can declare // minSampleShading member is ignored. This also specifies whether shader modules can declare
// the SampleRateShading capability // the SampleRateShading capability
mNativeExtensions.sampleShadingOES = (mPhysicalDeviceFeatures.sampleRateShading == VK_TRUE); bool supportSampleRateShading = (mPhysicalDeviceFeatures.sampleRateShading == VK_TRUE);
mNativeExtensions.sampleShadingOES = supportSampleRateShading;
mNativeCaps.minInterpolationOffset = limitsVk.minInterpolationOffset;
mNativeCaps.maxInterpolationOffset = limitsVk.maxInterpolationOffset;
mNativeCaps.subPixelInterpolationOffsetBits = limitsVk.subPixelInterpolationOffsetBits;
// From the Vulkan spec:
//
// > The values minInterpolationOffset and maxInterpolationOffset describe the closed interval
// > of supported interpolation offsets : [ minInterpolationOffset, maxInterpolationOffset ].
// > The ULP is determined by subPixelInterpolationOffsetBits. If
// > subPixelInterpolationOffsetBits is 4, this provides increments of(1 / 2^4) = 0.0625, and
// > thus the range of supported interpolation offsets would be[-0.5, 0.4375]
//
// OES_shader_multisample_interpolation requires a maximum value of -0.5 for
// MIN_FRAGMENT_INTERPOLATION_OFFSET_OES and minimum 0.5 for
// MAX_FRAGMENT_INTERPOLATION_OFFSET_OES. Vulkan has an identical limit for
// minInterpolationOffset, but it's limit for maxInterpolationOffset is 0.5-(1/ULP).
// OES_shader_multisample_interpolation is therefore only supported if
// maxInterpolationOffset is at least 0.5.
mNativeExtensions.multisampleInterpolationOES =
supportSampleRateShading && (mNativeCaps.maxInterpolationOffset >= 0.5);
// https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html // https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html
mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1; mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
......
...@@ -187,6 +187,12 @@ ...@@ -187,6 +187,12 @@
// Cannot create 2D (array) view of 3D texture. // Cannot create 2D (array) view of 3D texture.
3886 VULKAN : dEQP-GLES31.functional.image_load_store.3d.*layer = FAIL 3886 VULKAN : dEQP-GLES31.functional.image_load_store.3d.*layer = FAIL
// Conflict between "interpolateAtOffset()" and the viewport transformation for a default framebuffer
3589 VULKAN : dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_offset.no_qualifiers.default_framebuffer = FAIL
3589 VULKAN : dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_offset.centroid_qualifier.default_framebuffer = FAIL
3589 VULKAN : dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_offset.sample_qualifier.default_framebuffer = FAIL
3589 VULKAN : dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_offset.array_element.default_framebuffer = FAIL
//// ////
//// Android (i.e. Pixel*) Vulkan expectations //// Android (i.e. Pixel*) Vulkan expectations
//// ////
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment