Commit e5a43390 by Alexis Hetu Committed by Alexis Hétu

New FenceSync object API implementation

- Added new FenceSync object and related API functions implementations - Added FenceSync to ResourceManager - Moved Sampler to ResourceManager Change-Id: Ia3d42b749811a4e1ed087b41f0c871beb8fdb8d4 Reviewed-on: https://swiftshader-review.googlesource.com/2931Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent e61d74a0
...@@ -223,11 +223,6 @@ Context::~Context() ...@@ -223,11 +223,6 @@ Context::~Context()
deleteTransformFeedback(mTransformFeedbackMap.begin()->first); deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
} }
while(!mSamplerMap.empty())
{
deleteSampler(mSamplerMap.begin()->first);
}
for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
{ {
for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
...@@ -951,6 +946,13 @@ GLuint Context::createVertexArray() ...@@ -951,6 +946,13 @@ GLuint Context::createVertexArray()
return handle; return handle;
} }
GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
{
GLuint handle = mResourceManager->createFenceSync(condition, flags);
return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
}
// Returns an unused transform feedback name // Returns an unused transform feedback name
GLuint Context::createTransformFeedback() GLuint Context::createTransformFeedback()
{ {
...@@ -964,11 +966,7 @@ GLuint Context::createTransformFeedback() ...@@ -964,11 +966,7 @@ GLuint Context::createTransformFeedback()
// Returns an unused sampler name // Returns an unused sampler name
GLuint Context::createSampler() GLuint Context::createSampler()
{ {
GLuint handle = mSamplerNameSpace.allocate(); return mResourceManager->createSampler();
mSamplerMap[handle] = NULL;
return handle;
} }
void Context::deleteBuffer(GLuint buffer) void Context::deleteBuffer(GLuint buffer)
...@@ -1078,6 +1076,15 @@ void Context::deleteVertexArray(GLuint vertexArray) ...@@ -1078,6 +1076,15 @@ void Context::deleteVertexArray(GLuint vertexArray)
} }
} }
void Context::deleteFenceSync(GLsync fenceSync)
{
// The spec specifies the underlying Fence object is not deleted until all current
// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
// and since our API is currently designed for being called from a single thread, we can delete
// the fence immediately.
mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
}
void Context::deleteTransformFeedback(GLuint transformFeedback) void Context::deleteTransformFeedback(GLuint transformFeedback)
{ {
TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback);
...@@ -1092,19 +1099,12 @@ void Context::deleteTransformFeedback(GLuint transformFeedback) ...@@ -1092,19 +1099,12 @@ void Context::deleteTransformFeedback(GLuint transformFeedback)
void Context::deleteSampler(GLuint sampler) void Context::deleteSampler(GLuint sampler)
{ {
SamplerMap::iterator samplerObject = mSamplerMap.find(sampler); if(mResourceManager->getSampler(sampler))
if(samplerObject != mSamplerMap.end())
{ {
mSamplerNameSpace.release(samplerObject->first); detachSampler(sampler);
if(samplerObject->second)
{
samplerObject->second->release();
} }
mSamplerMap.erase(samplerObject); mResourceManager->deleteSampler(sampler);
}
} }
Buffer *Context::getBuffer(GLuint handle) const Buffer *Context::getBuffer(GLuint handle) const
...@@ -1457,6 +1457,11 @@ Fence *Context::getFence(unsigned int handle) const ...@@ -1457,6 +1457,11 @@ Fence *Context::getFence(unsigned int handle) const
} }
} }
FenceSync *Context::getFenceSync(GLsync handle) const
{
return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
}
Query *Context::getQuery(unsigned int handle) const Query *Context::getQuery(unsigned int handle) const
{ {
QueryMap::const_iterator query = mQueryMap.find(handle); QueryMap::const_iterator query = mQueryMap.find(handle);
...@@ -1528,9 +1533,7 @@ TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const ...@@ -1528,9 +1533,7 @@ TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
Sampler *Context::getSampler(GLuint sampler) const Sampler *Context::getSampler(GLuint sampler) const
{ {
SamplerMap::const_iterator samplerObject = mSamplerMap.find(sampler); return mResourceManager->getSampler(sampler);
return (samplerObject == mSamplerMap.end()) ? NULL : samplerObject->second;
} }
Buffer *Context::getArrayBuffer() const Buffer *Context::getArrayBuffer() const
...@@ -3822,6 +3825,22 @@ void Context::detachRenderbuffer(GLuint renderbuffer) ...@@ -3822,6 +3825,22 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
} }
} }
void Context::detachSampler(GLuint sampler)
{
// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
// If a sampler object that is currently bound to one or more texture units is
// deleted, it is as though BindSampler is called once for each texture unit to
// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
{
gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
if(samplerBinding.name() == sampler)
{
samplerBinding = NULL;
}
}
}
bool Context::cullSkipsDraw(GLenum drawMode) bool Context::cullSkipsDraw(GLenum drawMode)
{ {
return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
......
...@@ -64,6 +64,7 @@ class DepthStencilbuffer; ...@@ -64,6 +64,7 @@ class DepthStencilbuffer;
class VertexDataManager; class VertexDataManager;
class IndexDataManager; class IndexDataManager;
class Fence; class Fence;
class FenceSync;
class Query; class Query;
class Sampler; class Sampler;
class VertexArray; class VertexArray;
...@@ -478,12 +479,16 @@ public: ...@@ -478,12 +479,16 @@ public:
GLuint createProgram(); GLuint createProgram();
GLuint createTexture(); GLuint createTexture();
GLuint createRenderbuffer(); GLuint createRenderbuffer();
GLuint createSampler();
GLsync createFenceSync(GLenum condition, GLbitfield flags);
void deleteBuffer(GLuint buffer); void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader); void deleteShader(GLuint shader);
void deleteProgram(GLuint program); void deleteProgram(GLuint program);
void deleteTexture(GLuint texture); void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer); void deleteRenderbuffer(GLuint renderbuffer);
void deleteSampler(GLuint sampler);
void deleteFenceSync(GLsync fenceSync);
// Framebuffers are owned by the Context, so these methods do not pass through // Framebuffers are owned by the Context, so these methods do not pass through
GLuint createFramebuffer(); GLuint createFramebuffer();
...@@ -505,10 +510,6 @@ public: ...@@ -505,10 +510,6 @@ public:
GLuint createTransformFeedback(); GLuint createTransformFeedback();
void deleteTransformFeedback(GLuint transformFeedback); void deleteTransformFeedback(GLuint transformFeedback);
// Samplers are owned by the Context
GLuint createSampler();
void deleteSampler(GLuint sampler);
void bindArrayBuffer(GLuint buffer); void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer); void bindElementArrayBuffer(GLuint buffer);
void bindCopyReadBuffer(GLuint buffer); void bindCopyReadBuffer(GLuint buffer);
...@@ -543,6 +544,7 @@ public: ...@@ -543,6 +544,7 @@ public:
Buffer *getBuffer(GLuint handle) const; Buffer *getBuffer(GLuint handle) const;
Fence *getFence(GLuint handle) const; Fence *getFence(GLuint handle) const;
FenceSync *getFenceSync(GLsync handle) const;
Shader *getShader(GLuint handle) const; Shader *getShader(GLuint handle) const;
Program *getProgram(GLuint handle) const; Program *getProgram(GLuint handle) const;
virtual Texture *getTexture(GLuint handle) const; virtual Texture *getTexture(GLuint handle) const;
...@@ -635,6 +637,7 @@ private: ...@@ -635,6 +637,7 @@ private:
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer); void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer); void detachRenderbuffer(GLuint renderbuffer);
void detachSampler(GLuint sampler);
bool cullSkipsDraw(GLenum drawMode); bool cullSkipsDraw(GLenum drawMode);
bool isTriangleMode(GLenum drawMode); bool isTriangleMode(GLenum drawMode);
...@@ -672,10 +675,6 @@ private: ...@@ -672,10 +675,6 @@ private:
TransformFeedbackMap mTransformFeedbackMap; TransformFeedbackMap mTransformFeedbackMap;
gl::NameSpace mTransformFeedbackNameSpace; gl::NameSpace mTransformFeedbackNameSpace;
typedef std::map<GLint, Sampler*> SamplerMap;
SamplerMap mSamplerMap;
gl::NameSpace mSamplerNameSpace;
VertexDataManager *mVertexDataManager; VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager; IndexDataManager *mIndexDataManager;
......
...@@ -112,4 +112,21 @@ void Fence::getFenceiv(GLenum pname, GLint *params) ...@@ -112,4 +112,21 @@ void Fence::getFenceiv(GLenum pname, GLint *params)
} }
} }
FenceSync::FenceSync(GLuint name, GLenum condition, GLbitfield flags) : NamedObject(name), mCondition(condition), mFlags(flags)
{
}
FenceSync::~FenceSync()
{
}
GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
{
return GL_TRUE;
}
void FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
{
}
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#ifndef LIBGLESV2_FENCE_H_ #ifndef LIBGLESV2_FENCE_H_
#define LIBGLESV2_FENCE_H_ #define LIBGLESV2_FENCE_H_
#include "common/Object.hpp"
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
namespace es2 namespace es2
...@@ -37,6 +38,23 @@ class Fence ...@@ -37,6 +38,23 @@ class Fence
GLboolean mStatus; GLboolean mStatus;
}; };
class FenceSync : public gl::NamedObject
{
public:
FenceSync(GLuint name, GLenum condition, GLbitfield flags);
virtual ~FenceSync();
GLenum clientWait(GLbitfield flags, GLuint64 timeout);
void serverWait(GLbitfield flags, GLuint64 timeout);
GLenum getCondition() const { return mCondition; }
GLbitfield getFlags() const { return mFlags; }
private:
GLenum mCondition;
GLbitfield mFlags;
};
} }
#endif // LIBGLESV2_FENCE_H_ #endif // LIBGLESV2_FENCE_H_
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
#include "ResourceManager.h" #include "ResourceManager.h"
#include "Buffer.h" #include "Buffer.h"
#include "Fence.h"
#include "Program.h" #include "Program.h"
#include "Renderbuffer.h" #include "Renderbuffer.h"
#include "Sampler.h"
#include "Shader.h" #include "Shader.h"
#include "Texture.h" #include "Texture.h"
...@@ -53,6 +55,16 @@ ResourceManager::~ResourceManager() ...@@ -53,6 +55,16 @@ ResourceManager::~ResourceManager()
{ {
deleteTexture(mTextureMap.begin()->first); deleteTexture(mTextureMap.begin()->first);
} }
while(!mSamplerMap.empty())
{
deleteSampler(mSamplerMap.begin()->first);
}
while(!mFenceSyncMap.empty())
{
deleteFenceSync(mFenceSyncMap.begin()->first);
}
} }
void ResourceManager::addRef() void ResourceManager::addRef()
...@@ -126,6 +138,26 @@ GLuint ResourceManager::createRenderbuffer() ...@@ -126,6 +138,26 @@ GLuint ResourceManager::createRenderbuffer()
return handle; return handle;
} }
// Returns an unused sampler name
GLuint ResourceManager::createSampler()
{
GLuint handle = mSamplerHandleAllocator.allocate();
mSamplerMap[handle] = NULL;
return handle;
}
// Returns the next unused fence name, and allocates the fence
GLuint ResourceManager::createFenceSync(GLenum condition, GLbitfield flags)
{
GLuint handle = mFenceSyncHandleAllocator.allocate();
mFenceSyncMap[handle] = new FenceSync(handle, condition, flags);
return handle;
}
void ResourceManager::deleteBuffer(GLuint buffer) void ResourceManager::deleteBuffer(GLuint buffer)
{ {
BufferMap::iterator bufferObject = mBufferMap.find(buffer); BufferMap::iterator bufferObject = mBufferMap.find(buffer);
...@@ -200,6 +232,30 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) ...@@ -200,6 +232,30 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
} }
} }
void ResourceManager::deleteSampler(GLuint sampler)
{
auto samplerObject = mSamplerMap.find(sampler);
if(samplerObject != mSamplerMap.end())
{
mSamplerHandleAllocator.release(samplerObject->first);
if(samplerObject->second) samplerObject->second->release();
mSamplerMap.erase(samplerObject);
}
}
void ResourceManager::deleteFenceSync(GLuint fenceSync)
{
auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
if(fenceObjectIt != mFenceSyncMap.end())
{
mFenceSyncHandleAllocator.release(fenceObjectIt->first);
if(fenceObjectIt->second) fenceObjectIt->second->release();
mFenceSyncMap.erase(fenceObjectIt);
}
}
Buffer *ResourceManager::getBuffer(unsigned int handle) Buffer *ResourceManager::getBuffer(unsigned int handle)
{ {
BufferMap::iterator buffer = mBufferMap.find(handle); BufferMap::iterator buffer = mBufferMap.find(handle);
...@@ -278,6 +334,34 @@ Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) ...@@ -278,6 +334,34 @@ Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
} }
} }
Sampler *ResourceManager::getSampler(unsigned int handle)
{
auto sampler = mSamplerMap.find(handle);
if(sampler == mSamplerMap.end())
{
return NULL;
}
else
{
return sampler->second;
}
}
FenceSync *ResourceManager::getFenceSync(unsigned int handle)
{
auto fenceObjectIt = mFenceSyncMap.find(handle);
if(fenceObjectIt == mFenceSyncMap.end())
{
return NULL;
}
else
{
return fenceObjectIt->second;
}
}
void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
{ {
mRenderbufferMap[handle] = buffer; mRenderbufferMap[handle] = buffer;
...@@ -330,4 +414,20 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) ...@@ -330,4 +414,20 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
} }
} }
void ResourceManager::checkSamplerAllocation(GLuint sampler)
{
if(sampler != 0 && !getSampler(sampler))
{
Sampler *samplerObject = new Sampler(sampler);
mSamplerMap[sampler] = samplerObject;
samplerObject->addRef();
// Samplers cannot be created via Bind
}
}
bool ResourceManager::isSampler(GLuint sampler)
{
return mSamplerMap.find(sampler) != mSamplerMap.end();
}
} }
...@@ -28,6 +28,8 @@ class Shader; ...@@ -28,6 +28,8 @@ class Shader;
class Program; class Program;
class Texture; class Texture;
class Renderbuffer; class Renderbuffer;
class Sampler;
class FenceSync;
enum TextureType enum TextureType
{ {
...@@ -55,23 +57,32 @@ class ResourceManager ...@@ -55,23 +57,32 @@ class ResourceManager
GLuint createProgram(); GLuint createProgram();
GLuint createTexture(); GLuint createTexture();
GLuint createRenderbuffer(); GLuint createRenderbuffer();
GLuint createSampler();
GLuint createFenceSync(GLenum condition, GLbitfield flags);
void deleteBuffer(GLuint buffer); void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader); void deleteShader(GLuint shader);
void deleteProgram(GLuint program); void deleteProgram(GLuint program);
void deleteTexture(GLuint texture); void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer); void deleteRenderbuffer(GLuint renderbuffer);
void deleteSampler(GLuint sampler);
void deleteFenceSync(GLuint fenceSync);
Buffer *getBuffer(GLuint handle); Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle); Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle); Program *getProgram(GLuint handle);
Texture *getTexture(GLuint handle); Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle); Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
FenceSync *getFenceSync(GLuint handle);
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
void checkBufferAllocation(unsigned int buffer); void checkBufferAllocation(unsigned int buffer);
void checkTextureAllocation(GLuint texture, TextureType type); void checkTextureAllocation(GLuint texture, TextureType type);
void checkSamplerAllocation(GLuint sampler);
bool isSampler(GLuint sampler);
private: private:
std::size_t mRefCount; std::size_t mRefCount;
...@@ -94,6 +105,14 @@ class ResourceManager ...@@ -94,6 +105,14 @@ class ResourceManager
typedef std::map<GLint, Renderbuffer*> RenderbufferMap; typedef std::map<GLint, Renderbuffer*> RenderbufferMap;
RenderbufferMap mRenderbufferMap; RenderbufferMap mRenderbufferMap;
gl::NameSpace mRenderbufferNameSpace; gl::NameSpace mRenderbufferNameSpace;
typedef std::map<GLint, Sampler*> SamplerMap;
SamplerMap mSamplerMap;
gl::NameSpace mSamplerHandleAllocator;
typedef std::map<GLint, FenceSync*> FenceMap;
FenceMap mFenceSyncMap;
gl::NameSpace mFenceSyncHandleAllocator;
}; };
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "main.h" #include "main.h"
#include "Buffer.h" #include "Buffer.h"
#include "Fence.h"
#include "Framebuffer.h" #include "Framebuffer.h"
#include "Program.h" #include "Program.h"
#include "Query.h" #include "Query.h"
...@@ -2969,7 +2970,13 @@ GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags) ...@@ -2969,7 +2970,13 @@ GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
return error(GL_INVALID_VALUE, nullptr); return error(GL_INVALID_VALUE, nullptr);
} }
UNIMPLEMENTED(); es2::Context *context = es2::getContext();
if(context)
{
return context->createFenceSync(condition, flags);
}
return nullptr; return nullptr;
} }
...@@ -2977,7 +2984,18 @@ GL_APICALL GLboolean GL_APIENTRY glIsSync(GLsync sync) ...@@ -2977,7 +2984,18 @@ GL_APICALL GLboolean GL_APIENTRY glIsSync(GLsync sync)
{ {
TRACE("(GLsync sync = %p)", sync); TRACE("(GLsync sync = %p)", sync);
UNIMPLEMENTED(); es2::Context *context = es2::getContext();
if(context)
{
es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
if(fenceSyncObject)
{
return GL_TRUE;
}
}
return GL_FALSE; return GL_FALSE;
} }
...@@ -2985,7 +3003,12 @@ GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync) ...@@ -2985,7 +3003,12 @@ GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync)
{ {
TRACE("(GLsync sync = %p)", sync); TRACE("(GLsync sync = %p)", sync);
UNIMPLEMENTED(); es2::Context *context = es2::getContext();
if(context)
{
context->deleteFenceSync(sync);
}
} }
GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
...@@ -2997,7 +3020,22 @@ GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GL ...@@ -2997,7 +3020,22 @@ GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GL
error(GL_INVALID_VALUE); error(GL_INVALID_VALUE);
} }
UNIMPLEMENTED(); es2::Context *context = es2::getContext();
if(context)
{
es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
if(fenceSyncObject)
{
return fenceSyncObject->clientWait(flags, timeout);
}
else
{
return error(GL_INVALID_VALUE, GL_FALSE);
}
}
return GL_FALSE; return GL_FALSE;
} }
...@@ -3015,7 +3053,21 @@ GL_APICALL void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 t ...@@ -3015,7 +3053,21 @@ GL_APICALL void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 t
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
UNIMPLEMENTED(); es2::Context *context = es2::getContext();
if(context)
{
es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
if(fenceSyncObject)
{
fenceSyncObject->serverWait(flags, timeout);
}
else
{
return error(GL_INVALID_VALUE);
}
}
} }
GL_APICALL void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data) GL_APICALL void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data)
......
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