Commit 88482c3c by Alexis Hetu Committed by Alexis Hétu

Fix IOSurface synchronization issues

It appears that not only render targets, but also samplers that use IOSurfaces require SwiftShader to perform synchronized draws, otherwise it seems like using a shared IOSurface's CPU memory is unsafe and can cause crashes in Layout Tests. Bug chromium:846693 Change-Id: I0ce24700d34c657ac2447ceb2f6f837bfa3a9a58 Reviewed-on: https://swiftshader-review.googlesource.com/19288Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent dd063024
......@@ -1332,7 +1332,7 @@ namespace egl
#endif
}
bool ClientBuffer::targetRequiresSync() const
bool ClientBuffer::requiresSync() const
{
#if defined(__APPLE__)
return true;
......@@ -1431,9 +1431,9 @@ namespace egl
sw::Surface::unlockExternal();
}
bool targetRequiresSync() const override
bool requiresSync() const override
{
return clientBuffer.targetRequiresSync();
return clientBuffer.requiresSync();
}
void release() override
......
......@@ -79,7 +79,7 @@ public:
void release();
void* lock(int x, int y, int z);
void unlock();
bool targetRequiresSync() const;
bool requiresSync() const;
private:
int width;
......
......@@ -3180,6 +3180,7 @@ void Context::applyTextures(sw::SamplerType samplerType)
device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
device->setSyncRequired(samplerType, samplerIndex, texture->requiresSync());
applyTexture(samplerType, samplerIndex, texture);
}
......
......@@ -528,6 +528,19 @@ int Texture2D::getTopLevel() const
return level - 1;
}
bool Texture2D::requiresSync() const
{
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
if(image[level] && image[level]->requiresSync())
{
return true;
}
}
return false;
}
void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
if(image[level])
......@@ -1019,6 +1032,22 @@ int TextureCubeMap::getTopLevel() const
return level - 1;
}
bool TextureCubeMap::requiresSync() const
{
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
for(int face = 0; face < 6; face++)
{
if(image[face][level] && image[face][level]->requiresSync())
{
return true;
}
}
}
return false;
}
void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{
int face = CubeFaceIndex(target);
......@@ -1531,6 +1560,19 @@ int Texture3D::getTopLevel() const
return level - 1;
}
bool Texture3D::requiresSync() const
{
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
if(image[level] && image[level]->requiresSync())
{
return true;
}
}
return false;
}
void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
if(image[level])
......
......@@ -97,6 +97,7 @@ public:
virtual GLsizei getDepth(GLenum target, GLint level) const;
virtual GLint getFormat(GLenum target, GLint level) const = 0;
virtual int getTopLevel() const = 0;
virtual bool requiresSync() const = 0;
virtual bool isSamplerComplete() const = 0;
virtual bool isCompressed(GLenum target, GLint level) const = 0;
......@@ -159,6 +160,7 @@ public:
GLsizei getHeight(GLenum target, GLint level) const override;
GLint getFormat(GLenum target, GLint level) const override;
int getTopLevel() const override;
bool requiresSync() const override;
void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
......@@ -226,6 +228,7 @@ public:
GLsizei getHeight(GLenum target, GLint level) const override;
GLint getFormat(GLenum target, GLint level) const override;
int getTopLevel() const override;
bool requiresSync() const override;
void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
......@@ -287,6 +290,7 @@ public:
GLsizei getDepth(GLenum target, GLint level) const override;
GLint getFormat(GLenum target, GLint level) const override;
int getTopLevel() const override;
bool requiresSync() const override;
void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
......
......@@ -537,6 +537,15 @@ namespace sw
else ASSERT(false);
}
void PixelProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
{
if(sampler < TEXTURE_IMAGE_UNITS)
{
context->sampler[sampler].setSyncRequired(isSincRequired);
}
else ASSERT(false);
}
void PixelProcessor::setWriteSRGB(bool sRGB)
{
context->setWriteSRGB(sRGB);
......
......@@ -242,6 +242,7 @@ namespace sw
void setMaxLevel(unsigned int sampler, int maxLevel);
void setMinLod(unsigned int sampler, float minLod);
void setMaxLod(unsigned int sampler, float maxLod);
void setSyncRequired(unsigned int sampler, bool isSincRequired);
void setWriteSRGB(bool sRGB);
void setDepthBufferEnable(bool depthBufferEnable);
......
......@@ -224,7 +224,7 @@ namespace sw
int ss = context->getSuperSampleCount();
int ms = context->getMultiSampleCount();
bool targetRequiresSync = false;
bool requiresSync = false;
for(int q = 0; q < ss; q++)
{
......@@ -368,6 +368,8 @@ namespace sw
draw->texture[sampler]->lock(PUBLIC, isReadWriteTexture(sampler) ? MANAGED : PRIVATE); // If the texure is both read and written, use the same read/write lock as render targets
data->mipmap[sampler] = context->sampler[sampler].getTextureData();
requiresSync |= context->sampler[sampler].requiresSync();
}
}
......@@ -426,6 +428,8 @@ namespace sw
draw->texture[TEXTURE_IMAGE_UNITS + sampler]->lock(PUBLIC, PRIVATE);
data->mipmap[TEXTURE_IMAGE_UNITS + sampler] = context->sampler[TEXTURE_IMAGE_UNITS + sampler].getTextureData();
requiresSync |= context->sampler[TEXTURE_IMAGE_UNITS + sampler].requiresSync();
}
}
}
......@@ -608,7 +612,7 @@ namespace sw
if(draw->renderTarget[index])
{
unsigned int layer = context->renderTargetLayer[index];
targetRequiresSync |= context->renderTarget[index]->targetRequiresSync();
requiresSync |= context->renderTarget[index]->requiresSync();
data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
data->colorBuffer[index] += q * ms * context->renderTarget[index]->getSliceB(true);
data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB();
......@@ -622,7 +626,7 @@ namespace sw
if(draw->depthBuffer)
{
unsigned int layer = context->depthBufferLayer;
targetRequiresSync |= context->depthBuffer->targetRequiresSync();
requiresSync |= context->depthBuffer->requiresSync();
data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
data->depthBuffer += q * ms * context->depthBuffer->getSliceB(true);
data->depthPitchB = context->depthBuffer->getInternalPitchB();
......@@ -632,7 +636,7 @@ namespace sw
if(draw->stencilBuffer)
{
unsigned int layer = context->stencilBufferLayer;
targetRequiresSync |= context->stencilBuffer->targetRequiresSync();
requiresSync |= context->stencilBuffer->requiresSync();
data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, layer, MANAGED);
data->stencilBuffer += q * ms * context->stencilBuffer->getSliceB(true);
data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
......@@ -681,7 +685,7 @@ namespace sw
}
// TODO(sugoi): This is a temporary brute-force workaround to ensure IOSurface synchronization.
if(targetRequiresSync)
if(requiresSync)
{
synchronize();
}
......@@ -2469,6 +2473,18 @@ namespace sw
}
}
void Renderer::setSyncRequired(SamplerType type, int sampler, bool syncRequired)
{
if(type == SAMPLER_PIXEL)
{
PixelProcessor::setSyncRequired(sampler, syncRequired);
}
else
{
VertexProcessor::setSyncRequired(sampler, syncRequired);
}
}
void Renderer::setPointSpriteEnable(bool pointSpriteEnable)
{
context->setPointSpriteEnable(pointSpriteEnable);
......
......@@ -304,6 +304,7 @@ namespace sw
void setMaxLevel(SamplerType type, int sampler, int maxLevel);
void setMinLod(SamplerType type, int sampler, float minLod);
void setMaxLod(SamplerType type, int sampler, float maxLod);
void setSyncRequired(SamplerType type, int sampler, bool syncRequired);
void setPointSpriteEnable(bool pointSpriteEnable);
void setPointScaleEnable(bool pointScaleEnable);
......
......@@ -401,6 +401,16 @@ namespace sw
return textureType == TEXTURE_3D || textureType == TEXTURE_2D_ARRAY;
}
void Sampler::setSyncRequired(bool isSyncRequired)
{
syncRequired = isSyncRequired;
}
bool Sampler::requiresSync() const
{
return syncRequired;
}
const Texture &Sampler::getTextureData()
{
return texture;
......
......@@ -193,6 +193,7 @@ namespace sw
void setMaxLevel(int maxLevel);
void setMinLod(float minLod);
void setMaxLod(float maxLod);
void setSyncRequired(bool isSincRequired);
static void setFilterQuality(FilterType maximumFilterQuality);
static void setMipmapQuality(MipmapType maximumFilterQuality);
......@@ -202,6 +203,7 @@ namespace sw
bool hasUnsignedTexture() const;
bool hasCubeTexture() const;
bool hasVolumeTexture() const;
bool requiresSync() const;
const Texture &getTextureData();
......@@ -226,6 +228,7 @@ namespace sw
bool sRGB;
bool gather;
bool highPrecisionFiltering;
bool syncRequired;
int border;
SwizzleType swizzleR;
......
......@@ -321,7 +321,7 @@ namespace sw
inline int getStencilSliceB() const;
void sync(); // Wait for lock(s) to be released.
virtual bool targetRequiresSync() const { return false; }
virtual bool requiresSync() const { return false; }
inline bool isUnlocked() const; // Only reliable after sync().
inline int getSamples() const;
......
......@@ -692,6 +692,15 @@ namespace sw
else ASSERT(false);
}
void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
{
if(sampler < TEXTURE_IMAGE_UNITS)
{
context->sampler[sampler].setSyncRequired(isSincRequired);
}
else ASSERT(false);
}
void VertexProcessor::setPointSize(float pointSize)
{
point.pointSize = replicate(pointSize);
......
......@@ -268,6 +268,7 @@ namespace sw
void setMaxLevel(unsigned int sampler, int maxLevel);
void setMinLod(unsigned int sampler, float minLod);
void setMaxLod(unsigned int sampler, float maxLod);
void setSyncRequired(unsigned int sampler, bool isSincRequired);
void setPointSize(float pointSize);
void setPointSizeMin(float pointSizeMin);
......
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