Commit 5a2553a7 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Emulate subgroup ops in seamful cubemap emulation

Where subgroup ops are not available, they are emulated as such: Code with subgroup ops: float lH = subgroupQuadSwapHorizontal(layer); float lV = subgroupQuadSwapVertical(layer); float lD = subgroupQuadSwapDiagonal(layer); bool isHelperH = subgroupQuadSwapHorizontal(gl_HelperInvocation); bool isHelperV = subgroupQuadSwapVertical(gl_HelperInvocation); if (gl_HelperInvocation) { layer = !isHelperH ? lH : !isHelperV ? lV : lD; } Emulated code: float nonHelperLayer = gl_HelperInvocation ? 0.0 : layer; float lH = abs(dFdxFine(nonHelperLayer)); float lV = abs(dFdyFine(nonHelperLayer)); float lD = abs(dFdxFine(lV)); float isHelperDiffH = abs(dFdxFine(float(gl_HelperInvocation))); bool isNonHelperH = isHelperDiffH > 0.5; float isHelperDiffV = abs(dFdyFine(float(gl_HelperInvocation))); bool isNonHelperV = isHelperDiffV > 0.5; if (gl_HelperInvocation) { layer = isNonHelperH ? lH : isNonHelperV ? lV : lD; } Both paths are supported as on nvidia devices the emulated code misbehaves. This change therefore effectively only enables seamful cube map emulation on Android where subgroup operations are not supported. Bug: angleproject:3243 Bug: angleproject:3732 Change-Id: I9664d9760756758748183eb121c626f176789f3a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1742222Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 20141940
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 211 #define ANGLE_SH_VERSION 212
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -288,9 +288,14 @@ const ShCompileOptions SH_FORCE_ATOMIC_VALUE_RESOLUTION = UINT64_C(1) << 42; ...@@ -288,9 +288,14 @@ const ShCompileOptions SH_FORCE_ATOMIC_VALUE_RESOLUTION = UINT64_C(1) << 42;
const ShCompileOptions SH_EMULATE_GL_BASE_VERTEX_BASE_INSTANCE = UINT64_C(1) << 43; const ShCompileOptions SH_EMULATE_GL_BASE_VERTEX_BASE_INSTANCE = UINT64_C(1) << 43;
// Emulate seamful cube map sampling for OpenGL ES2.0. Currently only applies to the Vulkan // Emulate seamful cube map sampling for OpenGL ES2.0. Currently only applies to the Vulkan
// backend, as subgroup operations are used. Once that dependency is broken, could be used with // backend, as is done after samplers are moved out of structs. Can likely be made to work on
// the other backends as well. // the other backends as well.
//
// There are two variations of this. One using subgroup operations where available, and another
// that emulates those operations using dFdxFine and dFdyFine. The latter is more universally
// available, but is buggy on Nvidia.
const ShCompileOptions SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING = UINT64_C(1) << 44; const ShCompileOptions SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING = UINT64_C(1) << 44;
const ShCompileOptions SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING_WITH_SUBGROUP_OP = UINT64_C(1) << 45;
// Defines alternate strategies for implementing array index clamping. // Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy enum ShArrayIndexClampingStrategy
......
...@@ -645,7 +645,7 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -645,7 +645,7 @@ void TranslatorVulkan::translate(TIntermBlock *root,
sink << "#version 450 core\n"; sink << "#version 450 core\n";
if (compileOptions & SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING) if (compileOptions & SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING_WITH_SUBGROUP_OP)
{ {
sink << "#extension GL_KHR_shader_subgroup_quad : require\n"; sink << "#extension GL_KHR_shader_subgroup_quad : require\n";
} }
...@@ -688,10 +688,12 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -688,10 +688,12 @@ void TranslatorVulkan::translate(TIntermBlock *root,
// Rewrite samplerCubes as sampler2DArrays. This must be done after rewriting struct samplers // Rewrite samplerCubes as sampler2DArrays. This must be done after rewriting struct samplers
// as it doesn't expect that. // as it doesn't expect that.
if (compileOptions & SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING) if (compileOptions & (SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING |
SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING_WITH_SUBGROUP_OP))
{ {
RewriteCubeMapSamplersAs2DArray(root, &getSymbolTable(), RewriteCubeMapSamplersAs2DArray(
getShaderType() == GL_FRAGMENT_SHADER); root, &getSymbolTable(), getShaderType() == GL_FRAGMENT_SHADER,
compileOptions & SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING_WITH_SUBGROUP_OP);
} }
if (defaultUniformCount > 0) if (defaultUniformCount > 0)
......
...@@ -19,7 +19,8 @@ class TSymbolTable; ...@@ -19,7 +19,8 @@ class TSymbolTable;
void RewriteCubeMapSamplersAs2DArray(TIntermBlock *root, void RewriteCubeMapSamplersAs2DArray(TIntermBlock *root,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
bool isFragmentShader); bool isFragmentShader,
bool useSubgroupOps);
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_ #endif // COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
...@@ -238,6 +238,8 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -238,6 +238,8 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mClearColorMask(kAllColorChannelsMask), mClearColorMask(kAllColorChannelsMask),
mFlipYForCurrentSurface(false), mFlipYForCurrentSurface(false),
mIsAnyHostVisibleBufferWritten(false), mIsAnyHostVisibleBufferWritten(false),
mEmulateSeamfulCubeMapSampling(false),
mEmulateSeamfulCubeMapSamplingWithSubgroupOps(false),
mLastCompletedQueueSerial(renderer->nextSerial()), mLastCompletedQueueSerial(renderer->nextSerial()),
mCurrentQueueSerial(renderer->nextSerial()), mCurrentQueueSerial(renderer->nextSerial()),
mPoolAllocator(kDefaultPoolAllocatorPageSize, 1), mPoolAllocator(kDefaultPoolAllocatorPageSize, 1),
...@@ -441,7 +443,8 @@ angle::Result ContextVk::initialize() ...@@ -441,7 +443,8 @@ angle::Result ContextVk::initialize()
ANGLE_TRY(synchronizeCpuGpuTime()); ANGLE_TRY(synchronizeCpuGpuTime());
} }
mEmulateSeamfulCubeMapSampling = shouldEmulateSeamfulCubeMapSampling(); mEmulateSeamfulCubeMapSampling =
shouldEmulateSeamfulCubeMapSampling(&mEmulateSeamfulCubeMapSamplingWithSubgroupOps);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2896,9 +2899,10 @@ vk::DescriptorSetLayoutDesc ContextVk::getDriverUniformsDescriptorSetDesc( ...@@ -2896,9 +2899,10 @@ vk::DescriptorSetLayoutDesc ContextVk::getDriverUniformsDescriptorSetDesc(
return desc; return desc;
} }
bool ContextVk::shouldEmulateSeamfulCubeMapSampling() const bool ContextVk::shouldEmulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const
{ {
if (mState.getClientMajorVersion() != 2) // Only allow seamful cube map sampling in non-webgl ES2.
if (mState.getClientMajorVersion() != 2 || mState.isWebGL())
{ {
return false; return false;
} }
...@@ -2908,17 +2912,15 @@ bool ContextVk::shouldEmulateSeamfulCubeMapSampling() const ...@@ -2908,17 +2912,15 @@ bool ContextVk::shouldEmulateSeamfulCubeMapSampling() const
return false; return false;
} }
// Use subgroup ops where available.
constexpr VkSubgroupFeatureFlags kSeamfulCubeMapSubgroupOperations = constexpr VkSubgroupFeatureFlags kSeamfulCubeMapSubgroupOperations =
VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT |
VK_SUBGROUP_FEATURE_QUAD_BIT; VK_SUBGROUP_FEATURE_QUAD_BIT;
const VkSubgroupFeatureFlags deviceSupportedOperations = const VkSubgroupFeatureFlags deviceSupportedOperations =
mRenderer->getPhysicalDeviceSubgroupProperties().supportedOperations; mRenderer->getPhysicalDeviceSubgroupProperties().supportedOperations;
bool hasSeamfulCubeMapSubgroupOperations = *useSubgroupOpsOut = (deviceSupportedOperations & kSeamfulCubeMapSubgroupOperations) ==
(deviceSupportedOperations & kSeamfulCubeMapSubgroupOperations) == kSeamfulCubeMapSubgroupOperations;
kSeamfulCubeMapSubgroupOperations;
// Only enable seamful cube map emulation if the necessary subgroup operations are supported. return true;
// Without them, we cannot remove derivative-related artifacts caused by helper invocations.
return hasSeamfulCubeMapSubgroupOperations;
} }
} // namespace rx } // namespace rx
...@@ -313,7 +313,11 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -313,7 +313,11 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
void updateScissor(const gl::State &glState); void updateScissor(const gl::State &glState);
bool emulateSeamfulCubeMapSampling() const { return mEmulateSeamfulCubeMapSampling; } bool emulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const
{
*useSubgroupOpsOut = mEmulateSeamfulCubeMapSamplingWithSubgroupOps;
return mEmulateSeamfulCubeMapSampling;
}
private: private:
// Dirty bits. // Dirty bits.
...@@ -472,7 +476,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -472,7 +476,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
void waitForSwapchainImageIfNecessary(); void waitForSwapchainImageIfNecessary();
bool shouldEmulateSeamfulCubeMapSampling() const; bool shouldEmulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const;
vk::PipelineHelper *mCurrentGraphicsPipeline; vk::PipelineHelper *mCurrentGraphicsPipeline;
vk::PipelineAndSerial *mCurrentComputePipeline; vk::PipelineAndSerial *mCurrentComputePipeline;
...@@ -535,8 +539,10 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -535,8 +539,10 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
// at the end of the command buffer to make that write available to the host. // at the end of the command buffer to make that write available to the host.
bool mIsAnyHostVisibleBufferWritten; bool mIsAnyHostVisibleBufferWritten;
// Whether this context should do seamful cube map sampling emulation. // Whether this context should do seamful cube map sampling emulation, and whether subgroup
// operations should be used.
bool mEmulateSeamfulCubeMapSampling; bool mEmulateSeamfulCubeMapSampling;
bool mEmulateSeamfulCubeMapSamplingWithSubgroupOps;
struct DriverUniformsDescriptorSet struct DriverUniformsDescriptorSet
{ {
......
...@@ -936,7 +936,7 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState, ...@@ -936,7 +936,7 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState,
angle::Result GlslangWrapper::GetShaderCode(vk::Context *context, angle::Result GlslangWrapper::GetShaderCode(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableLineRasterEmulation, bool enableLineRasterEmulation,
bool enableSeamfulCubeMapEmulation, bool enableSubgroupOps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut) gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{ {
...@@ -956,20 +956,18 @@ angle::Result GlslangWrapper::GetShaderCode(vk::Context *context, ...@@ -956,20 +956,18 @@ angle::Result GlslangWrapper::GetShaderCode(vk::Context *context,
kVersionDefine, kLineRasterDefine), kVersionDefine, kLineRasterDefine),
VK_ERROR_INVALID_SHADER_NV); VK_ERROR_INVALID_SHADER_NV);
return GetShaderCodeImpl(context, glCaps, enableSeamfulCubeMapEmulation, patchedSources, return GetShaderCodeImpl(context, glCaps, enableSubgroupOps, patchedSources, shaderCodeOut);
shaderCodeOut);
} }
else else
{ {
return GetShaderCodeImpl(context, glCaps, enableSeamfulCubeMapEmulation, shaderSources, return GetShaderCodeImpl(context, glCaps, enableSubgroupOps, shaderSources, shaderCodeOut);
shaderCodeOut);
} }
} }
// static // static
angle::Result GlslangWrapper::GetShaderCodeImpl(vk::Context *context, angle::Result GlslangWrapper::GetShaderCodeImpl(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableSeamfulCubeMapEmulation, bool enableSubgroupOps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut) gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{ {
...@@ -1005,9 +1003,9 @@ angle::Result GlslangWrapper::GetShaderCodeImpl(vk::Context *context, ...@@ -1005,9 +1003,9 @@ angle::Result GlslangWrapper::GetShaderCodeImpl(vk::Context *context,
glslang::TShader *shader = shaders[shaderType]; glslang::TShader *shader = shaders[shaderType];
shader->setStringsWithLengths(&shaderString, &shaderLength, 1); shader->setStringsWithLengths(&shaderString, &shaderLength, 1);
shader->setEntryPoint("main"); shader->setEntryPoint("main");
if (enableSeamfulCubeMapEmulation) if (enableSubgroupOps)
{ {
// Enable SPIR-V 1.3 if this workaround is used, as it uses subgroup operations. // Enable SPIR-V 1.3 if to be able to use subgroup operations.
shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
} }
......
...@@ -29,14 +29,14 @@ class GlslangWrapper ...@@ -29,14 +29,14 @@ class GlslangWrapper
static angle::Result GetShaderCode(vk::Context *context, static angle::Result GetShaderCode(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableLineRasterEmulation, bool enableLineRasterEmulation,
bool enableSeamfulCubeMapEmulation, bool enableSubgroupOps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut); gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
private: private:
static angle::Result GetShaderCodeImpl(vk::Context *context, static angle::Result GetShaderCodeImpl(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableSeamfulCubeMapEmulation, bool enableSubgroupOps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut); gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
}; };
......
...@@ -304,10 +304,16 @@ angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk, ...@@ -304,10 +304,16 @@ angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk,
{ {
ASSERT(!valid()); ASSERT(!valid());
bool useSubgroupOpsWithSeamfulCubeMapEmulation = false;
bool emulateSeamfulCubeMapSampling =
contextVk->emulateSeamfulCubeMapSampling(&useSubgroupOpsWithSeamfulCubeMapEmulation);
bool useSubgroupOps =
emulateSeamfulCubeMapSampling && useSubgroupOpsWithSeamfulCubeMapEmulation;
gl::ShaderMap<std::vector<uint32_t>> shaderCodes; gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
ANGLE_TRY(GlslangWrapper::GetShaderCode( ANGLE_TRY(GlslangWrapper::GetShaderCode(contextVk, contextVk->getCaps(),
contextVk, contextVk->getCaps(), enableLineRasterEmulation, enableLineRasterEmulation, useSubgroupOps,
contextVk->emulateSeamfulCubeMapSampling(), shaderSources, &shaderCodes)); shaderSources, &shaderCodes));
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
...@@ -1437,7 +1443,8 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk) ...@@ -1437,7 +1443,8 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
const gl::ActiveTextureArray<vk::TextureUnit> &activeTextures = contextVk->getActiveTextures(); const gl::ActiveTextureArray<vk::TextureUnit> &activeTextures = contextVk->getActiveTextures();
bool emulateSeamfulCubeMapSampling = contextVk->emulateSeamfulCubeMapSampling(); bool useSubgroupOps = false;
bool emulateSeamfulCubeMapSampling = contextVk->emulateSeamfulCubeMapSampling(&useSubgroupOps);
for (uint32_t textureIndex = 0; textureIndex < mState.getSamplerBindings().size(); for (uint32_t textureIndex = 0; textureIndex < mState.getSamplerBindings().size();
++textureIndex) ++textureIndex)
......
...@@ -1279,6 +1279,7 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames) ...@@ -1279,6 +1279,7 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
if (IsWindows() && IsAMD(mPhysicalDeviceProperties.vendorID)) if (IsWindows() && IsAMD(mPhysicalDeviceProperties.vendorID))
{ {
// Disabled on AMD/windows due to buggy behavior.
mFeatures.disallowSeamfulCubeMapEmulation.enabled = true; mFeatures.disallowSeamfulCubeMapEmulation.enabled = true;
} }
......
...@@ -40,9 +40,17 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte ...@@ -40,9 +40,17 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
compileOptions |= SH_CLAMP_POINT_SIZE; compileOptions |= SH_CLAMP_POINT_SIZE;
} }
if (contextVk->emulateSeamfulCubeMapSampling()) bool useSubgroupOps = false;
if (contextVk->emulateSeamfulCubeMapSampling(&useSubgroupOps))
{ {
compileOptions |= SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING; if (useSubgroupOps)
{
compileOptions |= SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING_WITH_SUBGROUP_OP;
}
else
{
compileOptions |= SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING;
}
} }
return compileImpl(context, compilerInstance, mData.getSource(), compileOptions | options); return compileImpl(context, compilerInstance, mData.getSource(), compileOptions | options);
......
...@@ -329,25 +329,6 @@ ...@@ -329,25 +329,6 @@
3306 VULKAN ANDROID : dEQP-GLES2.functional.polygon_offset.fixed16_factor_1_slope = FAIL 3306 VULKAN ANDROID : dEQP-GLES2.functional.polygon_offset.fixed16_factor_1_slope = FAIL
3307 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.projected.nearest_linear = FAIL 3307 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.projected.nearest_linear = FAIL
// Seamful cubemap sampling failures on Android (due to missing support subgroupQuad* operations).
3243 VULKAN ANDROID : dEQP-GLES2.functional.shaders.texture_functions.vertex.texturecubelod = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_nearest = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_linear = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_nearest = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_linear = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.filtering.linear_mipmap_linear_nearest_clamp = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.filtering.linear_mipmap_linear_nearest_mirror = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.filtering.linear_mipmap_linear_linear_clamp = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.filtering.linear_mipmap_linear_linear_mirror = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.wrap.clamp_clamp = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.wrap.clamp_repeat = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.wrap.clamp_mirror = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.wrap.mirror_clamp = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.wrap.mirror_repeat = FAIL
3243 VULKAN ANDROID : dEQP-GLES2.functional.texture.vertex.cube.wrap.mirror_mirror = FAIL
// These tests also fail on AMD windows driver as it is not allowed to use emulation due to errors. // These tests also fail on AMD windows driver as it is not allowed to use emulation due to errors.
3243 VULKAN WIN AMD : dEQP-GLES2.functional.shaders.texture_functions.vertex.texturecubelod = FAIL 3243 VULKAN WIN AMD : dEQP-GLES2.functional.shaders.texture_functions.vertex.texturecubelod = FAIL
3243 VULKAN WIN AMD : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL 3243 VULKAN WIN AMD : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
......
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