Commit 2b55f876 by Shrek Shao Committed by Commit Bot

Reland "Workaround for Mac Intel drawArraysInstanced with first > 0"

This is a reland of 027bc47c Original change's description: > Workaround for Mac Intel drawArraysInstanced with first > 0 > > Workaround by forcefully set instanced arrays (divisor > 0) > as streaming attributes and apply extra offset at front. Recover > those attribute bindings when first == 0 and other draw calls > (drawElementsInstanced) > > Bug: chromium:1144207, chromium:1144247, chromium:1144373 > Change-Id: Ie7836cc71b45a290513f34f90d49bd15b14ddba8 > Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2661095 > Commit-Queue: Shrek Shao <shrekshao@google.com> > Reviewed-by: Geoff Lang <geofflang@chromium.org> Bug: chromium:1144207 Bug: chromium:1144247 Bug: chromium:1144373 Bug: angleproject:5271 Change-Id: Id0b818b25a605376c98c2366c1f2029e2490c6cb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2704799 Commit-Queue: Shrek Shao <shrekshao@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent da4aa8b8
...@@ -522,6 +522,13 @@ struct FeaturesGL : FeatureSetBase ...@@ -522,6 +522,13 @@ struct FeaturesGL : FeatureSetBase
Feature initFragmentOutputVariables = { Feature initFragmentOutputVariables = {
"init_fragment_output_variables", FeatureCategory::OpenGLWorkarounds, "init_fragment_output_variables", FeatureCategory::OpenGLWorkarounds,
"No init gl_FragColor causes context lost", &members, "http://crbug.com/1171371"}; "No init gl_FragColor causes context lost", &members, "http://crbug.com/1171371"};
// On macOS with Intel GPUs, instanced array with divisor > 0 is buggy when first > 0 in
// drawArraysInstanced. Shift the attributes with extra offset to workaround.
Feature shiftInstancedArrayDataWithExtraOffset = {
"shift_instanced_array_data_with_offset", FeatureCategory::OpenGLWorkarounds,
"glDrawArraysInstanced is buggy on certain new Mac Intel GPUs", &members,
"http://crbug.com/1144207"};
}; };
inline FeaturesGL::FeaturesGL() = default; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -210,7 +210,9 @@ ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *cont ...@@ -210,7 +210,9 @@ ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *cont
GLsizei count, GLsizei count,
GLsizei instanceCount) GLsizei instanceCount)
{ {
if (context->getStateCache().hasAnyActiveClientAttrib()) const angle::FeaturesGL &features = getFeaturesGL();
if (context->getStateCache().hasAnyActiveClientAttrib() ||
(features.shiftInstancedArrayDataWithExtraOffset.enabled && first > 0))
{ {
const gl::State &glState = context->getState(); const gl::State &glState = context->getState();
const gl::ProgramExecutable *executable = getState().getProgramExecutable(); const gl::ProgramExecutable *executable = getState().getProgramExecutable();
...@@ -224,8 +226,16 @@ ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *cont ...@@ -224,8 +226,16 @@ ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *cont
vaoGL->validateState(context); vaoGL->validateState(context);
#endif // ANGLE_STATE_VALIDATION_ENABLED #endif // ANGLE_STATE_VALIDATION_ENABLED
} }
else if (features.shiftInstancedArrayDataWithExtraOffset.enabled && first == 0)
{
// There could be previous draw call that has modified the attributes
// Instead of forcefully streaming attributes, we just rebind the original ones
const gl::State &glState = context->getState();
const gl::VertexArray *vao = glState.getVertexArray();
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
vaoGL->recoverForcedStreamingAttributesForDrawArraysInstanced(context);
}
const angle::FeaturesGL &features = getFeaturesGL();
if (features.setPrimitiveRestartFixedIndexForDrawArrays.enabled) if (features.setPrimitiveRestartFixedIndexForDrawArrays.enabled)
{ {
StateManagerGL *stateManager = getStateManager(); StateManagerGL *stateManager = getStateManager();
...@@ -248,6 +258,15 @@ ANGLE_INLINE angle::Result ContextGL::setDrawElementsState(const gl::Context *co ...@@ -248,6 +258,15 @@ ANGLE_INLINE angle::Result ContextGL::setDrawElementsState(const gl::Context *co
const gl::VertexArray *vao = glState.getVertexArray(); const gl::VertexArray *vao = glState.getVertexArray();
const gl::StateCache &stateCache = context->getStateCache(); const gl::StateCache &stateCache = context->getStateCache();
const angle::FeaturesGL &features = getFeaturesGL();
if (features.shiftInstancedArrayDataWithExtraOffset.enabled)
{
// There might be instanced arrays that are forced streaming for drawArraysInstanced
// They cannot be ELEMENT_ARRAY_BUFFER
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
vaoGL->recoverForcedStreamingAttributesForDrawArraysInstanced(context);
}
if (stateCache.hasAnyActiveClientAttrib() || vao->getElementArrayBuffer() == nullptr) if (stateCache.hasAnyActiveClientAttrib() || vao->getElementArrayBuffer() == nullptr)
{ {
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao); const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
...@@ -260,7 +279,6 @@ ANGLE_INLINE angle::Result ContextGL::setDrawElementsState(const gl::Context *co ...@@ -260,7 +279,6 @@ ANGLE_INLINE angle::Result ContextGL::setDrawElementsState(const gl::Context *co
*outIndices = indices; *outIndices = indices;
} }
const angle::FeaturesGL &features = getFeaturesGL();
if (glState.isPrimitiveRestartEnabled() && features.emulatePrimitiveRestartFixedIndex.enabled) if (glState.isPrimitiveRestartEnabled() && features.emulatePrimitiveRestartFixedIndex.enabled)
{ {
StateManagerGL *stateManager = getStateManager(); StateManagerGL *stateManager = getStateManager();
......
...@@ -457,4 +457,9 @@ bool ScopedWorkerContextGL::operator()() const ...@@ -457,4 +457,9 @@ bool ScopedWorkerContextGL::operator()() const
return mValid; return mValid;
} }
void RendererGL::handleGPUSwitch()
{
nativegl_gl::ReInitializeFeaturesAtGPUSwitch(mFunctions.get(), &mFeatures);
}
} // namespace rx } // namespace rx
...@@ -135,6 +135,8 @@ class RendererGL : angle::NonCopyable ...@@ -135,6 +135,8 @@ class RendererGL : angle::NonCopyable
void setNeedsFlushBeforeDeleteTextures(); void setNeedsFlushBeforeDeleteTextures();
void flushIfNecessaryBeforeDeleteTextures(); void flushIfNecessaryBeforeDeleteTextures();
void handleGPUSwitch();
protected: protected:
virtual WorkerContext *createWorkerContext(std::string *infoLog) = 0; virtual WorkerContext *createWorkerContext(std::string *infoLog) = 0;
......
...@@ -57,6 +57,8 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -57,6 +57,8 @@ class VertexArrayGL : public VertexArrayImpl
void validateState(const gl::Context *context) const; void validateState(const gl::Context *context) const;
void recoverForcedStreamingAttributesForDrawArraysInstanced(const gl::Context *context) const;
private: private:
angle::Result syncDrawState(const gl::Context *context, angle::Result syncDrawState(const gl::Context *context,
const gl::AttributesMask &activeAttributesMask, const gl::AttributesMask &activeAttributesMask,
...@@ -90,7 +92,8 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -90,7 +92,8 @@ class VertexArrayGL : public VertexArrayImpl
angle::Result streamAttributes(const gl::Context *context, angle::Result streamAttributes(const gl::Context *context,
const gl::AttributesMask &attribsToStream, const gl::AttributesMask &attribsToStream,
GLsizei instanceCount, GLsizei instanceCount,
const gl::IndexRange &indexRange) const; const gl::IndexRange &indexRange,
bool applyExtraOffsetWorkaroundForInstancedAttributes) const;
void syncDirtyAttrib(const gl::Context *context, void syncDirtyAttrib(const gl::Context *context,
size_t attribIndex, size_t attribIndex,
const gl::VertexArray::DirtyAttribBits &dirtyAttribBits); const gl::VertexArray::DirtyAttribBits &dirtyAttribBits);
...@@ -116,6 +119,10 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -116,6 +119,10 @@ class VertexArrayGL : public VertexArrayImpl
GLsizei stride, GLsizei stride,
GLintptr offset) const; GLintptr offset) const;
void recoverForcedStreamingAttributesForDrawArraysInstanced(
const gl::Context *context,
gl::AttributesMask *attributeMask) const;
GLuint mVertexArrayID; GLuint mVertexArrayID;
int mAppliedNumViews; int mAppliedNumViews;
...@@ -133,6 +140,11 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -133,6 +140,11 @@ class VertexArrayGL : public VertexArrayImpl
mutable size_t mStreamingArrayBufferSize; mutable size_t mStreamingArrayBufferSize;
mutable GLuint mStreamingArrayBuffer; mutable GLuint mStreamingArrayBuffer;
// Used for Mac Intel instanced draw workaround
mutable gl::AttributesMask mForcedStreamingAttributesForDrawArraysInstancedMask;
mutable gl::AttributesMask mInstancedAttributesMask;
mutable std::array<GLint, gl::MAX_VERTEX_ATTRIBS> mForcedStreamingAttributesFirstOffsets;
}; };
ANGLE_INLINE angle::Result VertexArrayGL::syncDrawElementsState( ANGLE_INLINE angle::Result VertexArrayGL::syncDrawElementsState(
......
...@@ -658,6 +658,8 @@ egl::Error DisplayCGL::handleGPUSwitch() ...@@ -658,6 +658,8 @@ egl::Error DisplayCGL::handleGPUSwitch()
CGLSetCurrentContext(mContext); CGLSetCurrentContext(mContext);
onStateChange(angle::SubjectMessage::SubjectChanged); onStateChange(angle::SubjectMessage::SubjectChanged);
mCurrentGPUID = gpuID; mCurrentGPUID = gpuID;
mRenderer->handleGPUSwitch();
} }
} }
......
...@@ -1647,23 +1647,33 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -1647,23 +1647,33 @@ void GenerateCaps(const FunctionsGL *functions,
extensions->yuvTargetEXT = functions->hasGLESExtension("GL_EXT_YUV_target"); extensions->yuvTargetEXT = functions->hasGLESExtension("GL_EXT_YUV_target");
} }
void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features) bool GetSystemInfoVendorIDAndDeviceID(const FunctionsGL *functions,
angle::SystemInfo *outSystemInfo,
angle::VendorID *outVendor,
angle::DeviceID *outDevice)
{ {
angle::VendorID vendor; bool isGetSystemInfoSuccess = angle::GetSystemInfo(outSystemInfo);
angle::DeviceID device; if (isGetSystemInfoSuccess && !outSystemInfo->gpus.empty())
angle::SystemInfo systemInfo;
bool isGetSystemInfoSuccess = angle::GetSystemInfo(&systemInfo);
if (isGetSystemInfoSuccess && !systemInfo.gpus.empty())
{ {
vendor = systemInfo.gpus[systemInfo.activeGPUIndex].vendorId; *outVendor = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].vendorId;
device = systemInfo.gpus[systemInfo.activeGPUIndex].deviceId; *outDevice = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].deviceId;
} }
else else
{ {
vendor = GetVendorID(functions); *outVendor = GetVendorID(functions);
device = GetDeviceID(functions); *outDevice = GetDeviceID(functions);
} }
return isGetSystemInfoSuccess;
}
void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
{
angle::VendorID vendor;
angle::DeviceID device;
angle::SystemInfo systemInfo;
bool isGetSystemInfoSuccess =
GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);
bool isAMD = IsAMD(vendor); bool isAMD = IsAMD(vendor);
bool isIntel = IsIntel(vendor); bool isIntel = IsIntel(vendor);
...@@ -1931,6 +1941,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -1931,6 +1941,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// If output variable gl_FragColor is written by fragment shader, it may cause context lost with // If output variable gl_FragColor is written by fragment shader, it may cause context lost with
// Adreno 42x and 3xx. // Adreno 42x and 3xx.
ANGLE_FEATURE_CONDITION(features, initFragmentOutputVariables, IsAdreno42xOr3xx(functions)); ANGLE_FEATURE_CONDITION(features, initFragmentOutputVariables, IsAdreno42xOr3xx(functions));
// http://crbug.com/1144207
// The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
// now.
ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithExtraOffset,
IsApple() && IsIntel(vendor) && !IsHaswell(device));
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
...@@ -1943,6 +1959,22 @@ void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFea ...@@ -1943,6 +1959,22 @@ void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFea
ANGLE_FEATURE_CONDITION(features, syncFramebufferBindingsOnTexImage, false); ANGLE_FEATURE_CONDITION(features, syncFramebufferBindingsOnTexImage, false);
} }
void ReInitializeFeaturesAtGPUSwitch(const FunctionsGL *functions, angle::FeaturesGL *features)
{
angle::VendorID vendor;
angle::DeviceID device;
angle::SystemInfo systemInfo;
GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);
// http://crbug.com/1144207
// The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
// now.
// We need to reinitialize this feature when switching between buggy and non-buggy GPUs.
ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithExtraOffset,
IsApple() && IsIntel(vendor) && !IsHaswell(device));
}
} // namespace nativegl_gl } // namespace nativegl_gl
namespace nativegl namespace nativegl
......
...@@ -106,6 +106,7 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -106,6 +106,7 @@ void GenerateCaps(const FunctionsGL *functions,
void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features); void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features);
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features); void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features);
void ReInitializeFeaturesAtGPUSwitch(const FunctionsGL *functions, angle::FeaturesGL *features);
} // namespace nativegl_gl } // namespace nativegl_gl
namespace nativegl namespace nativegl
......
...@@ -122,10 +122,6 @@ class InstancingTest : public ANGLETest ...@@ -122,10 +122,6 @@ class InstancingTest : public ANGLETest
// Unknown problem. FL9_3 is not officially supported anyway. // Unknown problem. FL9_3 is not officially supported anyway.
ANGLE_SKIP_TEST_IF(IsD3D11_FL93() && geometry == Quad && draw == NonIndexed); ANGLE_SKIP_TEST_IF(IsD3D11_FL93() && geometry == Quad && draw == NonIndexed);
// http://anglebug.com/5271
ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL() &&
draw == NonIndexed && offset != 0);
// The window is divided into kMaxDrawn slices of size kDrawSize. // The window is divided into kMaxDrawn slices of size kDrawSize.
// The slice drawn into is determined by the instance datum. // The slice drawn into is determined by the instance datum.
// The instance data array selects all the slices in order. // The instance data array selects all the slices in order.
......
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