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 ...@@ -1332,7 +1332,7 @@ namespace egl
#endif #endif
} }
bool ClientBuffer::targetRequiresSync() const bool ClientBuffer::requiresSync() const
{ {
#if defined(__APPLE__) #if defined(__APPLE__)
return true; return true;
...@@ -1431,9 +1431,9 @@ namespace egl ...@@ -1431,9 +1431,9 @@ namespace egl
sw::Surface::unlockExternal(); sw::Surface::unlockExternal();
} }
bool targetRequiresSync() const override bool requiresSync() const override
{ {
return clientBuffer.targetRequiresSync(); return clientBuffer.requiresSync();
} }
void release() override void release() override
......
...@@ -79,7 +79,7 @@ public: ...@@ -79,7 +79,7 @@ public:
void release(); void release();
void* lock(int x, int y, int z); void* lock(int x, int y, int z);
void unlock(); void unlock();
bool targetRequiresSync() const; bool requiresSync() const;
private: private:
int width; int width;
......
...@@ -3180,6 +3180,7 @@ void Context::applyTextures(sw::SamplerType samplerType) ...@@ -3180,6 +3180,7 @@ void Context::applyTextures(sw::SamplerType samplerType)
device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter)); device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST); device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
device->setSyncRequired(samplerType, samplerIndex, texture->requiresSync());
applyTexture(samplerType, samplerIndex, texture); applyTexture(samplerType, samplerIndex, texture);
} }
......
...@@ -528,6 +528,19 @@ int Texture2D::getTopLevel() const ...@@ -528,6 +528,19 @@ int Texture2D::getTopLevel() const
return level - 1; 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) 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]) if(image[level])
...@@ -1019,6 +1032,22 @@ int TextureCubeMap::getTopLevel() const ...@@ -1019,6 +1032,22 @@ int TextureCubeMap::getTopLevel() const
return level - 1; 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) void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{ {
int face = CubeFaceIndex(target); int face = CubeFaceIndex(target);
...@@ -1531,6 +1560,19 @@ int Texture3D::getTopLevel() const ...@@ -1531,6 +1560,19 @@ int Texture3D::getTopLevel() const
return level - 1; 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) 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]) if(image[level])
......
...@@ -97,6 +97,7 @@ public: ...@@ -97,6 +97,7 @@ public:
virtual GLsizei getDepth(GLenum target, GLint level) const; virtual GLsizei getDepth(GLenum target, GLint level) const;
virtual GLint getFormat(GLenum target, GLint level) const = 0; virtual GLint getFormat(GLenum target, GLint level) const = 0;
virtual int getTopLevel() const = 0; virtual int getTopLevel() const = 0;
virtual bool requiresSync() const = 0;
virtual bool isSamplerComplete() const = 0; virtual bool isSamplerComplete() const = 0;
virtual bool isCompressed(GLenum target, GLint level) const = 0; virtual bool isCompressed(GLenum target, GLint level) const = 0;
...@@ -159,6 +160,7 @@ public: ...@@ -159,6 +160,7 @@ public:
GLsizei getHeight(GLenum target, GLint level) const override; GLsizei getHeight(GLenum target, GLint level) const override;
GLint getFormat(GLenum target, GLint level) const override; GLint getFormat(GLenum target, GLint level) const override;
int getTopLevel() 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 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); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
...@@ -226,6 +228,7 @@ public: ...@@ -226,6 +228,7 @@ public:
GLsizei getHeight(GLenum target, GLint level) const override; GLsizei getHeight(GLenum target, GLint level) const override;
GLint getFormat(GLenum target, GLint level) const override; GLint getFormat(GLenum target, GLint level) const override;
int getTopLevel() 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 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); void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
...@@ -287,6 +290,7 @@ public: ...@@ -287,6 +290,7 @@ public:
GLsizei getDepth(GLenum target, GLint level) const override; GLsizei getDepth(GLenum target, GLint level) const override;
GLint getFormat(GLenum target, GLint level) const override; GLint getFormat(GLenum target, GLint level) const override;
int getTopLevel() 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 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); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
......
...@@ -537,6 +537,15 @@ namespace sw ...@@ -537,6 +537,15 @@ namespace sw
else ASSERT(false); 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) void PixelProcessor::setWriteSRGB(bool sRGB)
{ {
context->setWriteSRGB(sRGB); context->setWriteSRGB(sRGB);
......
...@@ -242,6 +242,7 @@ namespace sw ...@@ -242,6 +242,7 @@ namespace sw
void setMaxLevel(unsigned int sampler, int maxLevel); void setMaxLevel(unsigned int sampler, int maxLevel);
void setMinLod(unsigned int sampler, float minLod); void setMinLod(unsigned int sampler, float minLod);
void setMaxLod(unsigned int sampler, float maxLod); void setMaxLod(unsigned int sampler, float maxLod);
void setSyncRequired(unsigned int sampler, bool isSincRequired);
void setWriteSRGB(bool sRGB); void setWriteSRGB(bool sRGB);
void setDepthBufferEnable(bool depthBufferEnable); void setDepthBufferEnable(bool depthBufferEnable);
......
...@@ -224,7 +224,7 @@ namespace sw ...@@ -224,7 +224,7 @@ namespace sw
int ss = context->getSuperSampleCount(); int ss = context->getSuperSampleCount();
int ms = context->getMultiSampleCount(); int ms = context->getMultiSampleCount();
bool targetRequiresSync = false; bool requiresSync = false;
for(int q = 0; q < ss; q++) for(int q = 0; q < ss; q++)
{ {
...@@ -368,6 +368,8 @@ namespace sw ...@@ -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 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(); data->mipmap[sampler] = context->sampler[sampler].getTextureData();
requiresSync |= context->sampler[sampler].requiresSync();
} }
} }
...@@ -426,6 +428,8 @@ namespace sw ...@@ -426,6 +428,8 @@ namespace sw
draw->texture[TEXTURE_IMAGE_UNITS + sampler]->lock(PUBLIC, PRIVATE); draw->texture[TEXTURE_IMAGE_UNITS + sampler]->lock(PUBLIC, PRIVATE);
data->mipmap[TEXTURE_IMAGE_UNITS + sampler] = context->sampler[TEXTURE_IMAGE_UNITS + sampler].getTextureData(); 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 ...@@ -608,7 +612,7 @@ namespace sw
if(draw->renderTarget[index]) if(draw->renderTarget[index])
{ {
unsigned int layer = context->renderTargetLayer[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] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
data->colorBuffer[index] += q * ms * context->renderTarget[index]->getSliceB(true); data->colorBuffer[index] += q * ms * context->renderTarget[index]->getSliceB(true);
data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB(); data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB();
...@@ -622,7 +626,7 @@ namespace sw ...@@ -622,7 +626,7 @@ namespace sw
if(draw->depthBuffer) if(draw->depthBuffer)
{ {
unsigned int layer = context->depthBufferLayer; 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 = (float*)context->depthBuffer->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
data->depthBuffer += q * ms * context->depthBuffer->getSliceB(true); data->depthBuffer += q * ms * context->depthBuffer->getSliceB(true);
data->depthPitchB = context->depthBuffer->getInternalPitchB(); data->depthPitchB = context->depthBuffer->getInternalPitchB();
...@@ -632,7 +636,7 @@ namespace sw ...@@ -632,7 +636,7 @@ namespace sw
if(draw->stencilBuffer) if(draw->stencilBuffer)
{ {
unsigned int layer = context->stencilBufferLayer; 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 = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, layer, MANAGED);
data->stencilBuffer += q * ms * context->stencilBuffer->getSliceB(true); data->stencilBuffer += q * ms * context->stencilBuffer->getSliceB(true);
data->stencilPitchB = context->stencilBuffer->getStencilPitchB(); data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
...@@ -681,7 +685,7 @@ namespace sw ...@@ -681,7 +685,7 @@ namespace sw
} }
// TODO(sugoi): This is a temporary brute-force workaround to ensure IOSurface synchronization. // TODO(sugoi): This is a temporary brute-force workaround to ensure IOSurface synchronization.
if(targetRequiresSync) if(requiresSync)
{ {
synchronize(); synchronize();
} }
...@@ -2469,6 +2473,18 @@ namespace sw ...@@ -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) void Renderer::setPointSpriteEnable(bool pointSpriteEnable)
{ {
context->setPointSpriteEnable(pointSpriteEnable); context->setPointSpriteEnable(pointSpriteEnable);
......
...@@ -304,6 +304,7 @@ namespace sw ...@@ -304,6 +304,7 @@ namespace sw
void setMaxLevel(SamplerType type, int sampler, int maxLevel); void setMaxLevel(SamplerType type, int sampler, int maxLevel);
void setMinLod(SamplerType type, int sampler, float minLod); void setMinLod(SamplerType type, int sampler, float minLod);
void setMaxLod(SamplerType type, int sampler, float maxLod); void setMaxLod(SamplerType type, int sampler, float maxLod);
void setSyncRequired(SamplerType type, int sampler, bool syncRequired);
void setPointSpriteEnable(bool pointSpriteEnable); void setPointSpriteEnable(bool pointSpriteEnable);
void setPointScaleEnable(bool pointScaleEnable); void setPointScaleEnable(bool pointScaleEnable);
......
...@@ -401,6 +401,16 @@ namespace sw ...@@ -401,6 +401,16 @@ namespace sw
return textureType == TEXTURE_3D || textureType == TEXTURE_2D_ARRAY; 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() const Texture &Sampler::getTextureData()
{ {
return texture; return texture;
......
...@@ -193,6 +193,7 @@ namespace sw ...@@ -193,6 +193,7 @@ namespace sw
void setMaxLevel(int maxLevel); void setMaxLevel(int maxLevel);
void setMinLod(float minLod); void setMinLod(float minLod);
void setMaxLod(float maxLod); void setMaxLod(float maxLod);
void setSyncRequired(bool isSincRequired);
static void setFilterQuality(FilterType maximumFilterQuality); static void setFilterQuality(FilterType maximumFilterQuality);
static void setMipmapQuality(MipmapType maximumFilterQuality); static void setMipmapQuality(MipmapType maximumFilterQuality);
...@@ -202,6 +203,7 @@ namespace sw ...@@ -202,6 +203,7 @@ namespace sw
bool hasUnsignedTexture() const; bool hasUnsignedTexture() const;
bool hasCubeTexture() const; bool hasCubeTexture() const;
bool hasVolumeTexture() const; bool hasVolumeTexture() const;
bool requiresSync() const;
const Texture &getTextureData(); const Texture &getTextureData();
...@@ -226,6 +228,7 @@ namespace sw ...@@ -226,6 +228,7 @@ namespace sw
bool sRGB; bool sRGB;
bool gather; bool gather;
bool highPrecisionFiltering; bool highPrecisionFiltering;
bool syncRequired;
int border; int border;
SwizzleType swizzleR; SwizzleType swizzleR;
......
...@@ -321,7 +321,7 @@ namespace sw ...@@ -321,7 +321,7 @@ namespace sw
inline int getStencilSliceB() const; inline int getStencilSliceB() const;
void sync(); // Wait for lock(s) to be released. 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 bool isUnlocked() const; // Only reliable after sync().
inline int getSamples() const; inline int getSamples() const;
......
...@@ -692,6 +692,15 @@ namespace sw ...@@ -692,6 +692,15 @@ namespace sw
else ASSERT(false); 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) void VertexProcessor::setPointSize(float pointSize)
{ {
point.pointSize = replicate(pointSize); point.pointSize = replicate(pointSize);
......
...@@ -268,6 +268,7 @@ namespace sw ...@@ -268,6 +268,7 @@ namespace sw
void setMaxLevel(unsigned int sampler, int maxLevel); void setMaxLevel(unsigned int sampler, int maxLevel);
void setMinLod(unsigned int sampler, float minLod); void setMinLod(unsigned int sampler, float minLod);
void setMaxLod(unsigned int sampler, float maxLod); void setMaxLod(unsigned int sampler, float maxLod);
void setSyncRequired(unsigned int sampler, bool isSincRequired);
void setPointSize(float pointSize); void setPointSize(float pointSize);
void setPointSizeMin(float pointSizeMin); 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