Commit c8058451 by Geoff Lang

Add functionality to create and destroy TransformFeedback objects.

BUG=angle:491 Change-Id: I3ee3c2aec1878ad656a8f522943a29fea6f7e215 Reviewed-on: https://chromium-review.googlesource.com/185033Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 92877af5
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "libGLESv2/VertexArray.h" #include "libGLESv2/VertexArray.h"
#include "libGLESv2/Sampler.h" #include "libGLESv2/Sampler.h"
#include "libGLESv2/validationES.h" #include "libGLESv2/validationES.h"
#include "libGLESv2/TransformFeedback.h"
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
...@@ -192,6 +193,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere ...@@ -192,6 +193,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
bindPixelPackBuffer(0); bindPixelPackBuffer(0);
bindPixelUnpackBuffer(0); bindPixelUnpackBuffer(0);
// [OpenGL ES 3.0.2] section 2.14.1 pg 85:
// In the initial state, a default transform feedback object is bound and treated as
// a transform feedback object with a name of zero. That object is bound any time
// BindTransformFeedback is called with id of zero
mTransformFeedbackZero.set(new TransformFeedback(0));
bindTransformFeedback(0);
mState.currentProgram = 0; mState.currentProgram = 0;
mCurrentProgramBinary.set(NULL); mCurrentProgramBinary.set(NULL);
...@@ -252,6 +260,12 @@ Context::~Context() ...@@ -252,6 +260,12 @@ Context::~Context()
deleteVertexArray(mVertexArrayMap.begin()->first); deleteVertexArray(mVertexArrayMap.begin()->first);
} }
mTransformFeedbackZero.set(NULL);
while (!mTransformFeedbackMap.empty())
{
deleteTransformFeedback(mTransformFeedbackMap.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 < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
...@@ -274,6 +288,8 @@ Context::~Context() ...@@ -274,6 +288,8 @@ Context::~Context()
mState.arrayBuffer.set(NULL); mState.arrayBuffer.set(NULL);
mState.renderbuffer.set(NULL); mState.renderbuffer.set(NULL);
mState.transformFeedback.set(NULL);
mTexture2DZero.set(NULL); mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL); mTextureCubeMapZero.set(NULL);
mTexture3DZero.set(NULL); mTexture3DZero.set(NULL);
...@@ -881,6 +897,15 @@ GLuint Context::createSampler() ...@@ -881,6 +897,15 @@ GLuint Context::createSampler()
return mResourceManager->createSampler(); return mResourceManager->createSampler();
} }
GLuint Context::createTransformFeedback()
{
GLuint handle = mTransformFeedbackAllocator.allocate();
TransformFeedback *transformFeedback = new TransformFeedback(handle);
transformFeedback->addRef();
mTransformFeedbackMap[handle] = transformFeedback;
return handle;
}
// Returns an unused framebuffer name // Returns an unused framebuffer name
GLuint Context::createFramebuffer() GLuint Context::createFramebuffer()
{ {
...@@ -983,6 +1008,18 @@ void Context::deleteSampler(GLuint sampler) ...@@ -983,6 +1008,18 @@ void Context::deleteSampler(GLuint sampler)
mResourceManager->deleteSampler(sampler); mResourceManager->deleteSampler(sampler);
} }
void Context::deleteTransformFeedback(GLuint transformFeedback)
{
TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
if (iter != mTransformFeedbackMap.end())
{
detachTransformFeedback(transformFeedback);
mTransformFeedbackAllocator.release(transformFeedback);
iter->second->release();
mTransformFeedbackMap.erase(iter);
}
}
void Context::deleteFramebuffer(GLuint framebuffer) void Context::deleteFramebuffer(GLuint framebuffer)
{ {
FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
...@@ -1072,6 +1109,19 @@ Sampler *Context::getSampler(GLuint handle) const ...@@ -1072,6 +1109,19 @@ Sampler *Context::getSampler(GLuint handle) const
return mResourceManager->getSampler(handle); return mResourceManager->getSampler(handle);
} }
TransformFeedback *Context::getTransformFeedback(GLuint handle) const
{
if (handle == 0)
{
return mTransformFeedbackZero.get();
}
else
{
TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle);
return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL;
}
}
Framebuffer *Context::getReadFramebuffer() Framebuffer *Context::getReadFramebuffer()
{ {
return getFramebuffer(mState.readFramebuffer); return getFramebuffer(mState.readFramebuffer);
...@@ -1089,6 +1139,11 @@ VertexArray *Context::getCurrentVertexArray() const ...@@ -1089,6 +1139,11 @@ VertexArray *Context::getCurrentVertexArray() const
return vao; return vao;
} }
TransformFeedback *Context::getCurrentTransformFeedback() const
{
return mState.transformFeedback.get();
}
bool Context::isSampler(GLuint samplerName) const bool Context::isSampler(GLuint samplerName) const
{ {
return mResourceManager->isSampler(samplerName); return mResourceManager->isSampler(samplerName);
...@@ -1292,6 +1347,12 @@ void Context::setProgramBinary(GLuint program, const void *binary, GLint length) ...@@ -1292,6 +1347,12 @@ void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
} }
void Context::bindTransformFeedback(GLuint transformFeedback)
{
TransformFeedback *transformFeedbackObject = getTransformFeedback(transformFeedback);
mState.transformFeedback.set(transformFeedbackObject);
}
void Context::beginQuery(GLenum target, GLuint query) void Context::beginQuery(GLenum target, GLuint query)
{ {
// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
...@@ -3413,6 +3474,14 @@ void Context::detachVertexArray(GLuint vertexArray) ...@@ -3413,6 +3474,14 @@ void Context::detachVertexArray(GLuint vertexArray)
} }
} }
void Context::detachTransformFeedback(GLuint transformFeedback)
{
if (mState.transformFeedback.id() == transformFeedback)
{
bindTransformFeedback(0);
}
}
void Context::detachSampler(GLuint sampler) void Context::detachSampler(GLuint sampler)
{ {
// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124: // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
......
...@@ -67,6 +67,7 @@ class Buffer; ...@@ -67,6 +67,7 @@ class Buffer;
class VertexAttribute; class VertexAttribute;
class VertexArray; class VertexArray;
class Sampler; class Sampler;
class TransformFeedback;
// Helper structure to store all raw state // Helper structure to store all raw state
struct State struct State
...@@ -117,6 +118,7 @@ struct State ...@@ -117,6 +118,7 @@ struct State
BindingPointer<Buffer> genericUniformBuffer; BindingPointer<Buffer> genericUniformBuffer;
OffsetBindingPointer<Buffer> uniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; OffsetBindingPointer<Buffer> uniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
BindingPointer<TransformFeedback> transformFeedback;
BindingPointer<Buffer> genericTransformFeedbackBuffer; BindingPointer<Buffer> genericTransformFeedbackBuffer;
OffsetBindingPointer<Buffer> transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; OffsetBindingPointer<Buffer> transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
...@@ -253,6 +255,7 @@ class Context ...@@ -253,6 +255,7 @@ class Context
GLuint createTexture(); GLuint createTexture();
GLuint createRenderbuffer(); GLuint createRenderbuffer();
GLuint createSampler(); GLuint createSampler();
GLuint createTransformFeedback();
GLsync createFenceSync(GLenum condition); GLsync createFenceSync(GLenum condition);
void deleteBuffer(GLuint buffer); void deleteBuffer(GLuint buffer);
...@@ -261,6 +264,7 @@ class Context ...@@ -261,6 +264,7 @@ class Context
void deleteTexture(GLuint texture); void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer); void deleteRenderbuffer(GLuint renderbuffer);
void deleteSampler(GLuint sampler); void deleteSampler(GLuint sampler);
void deleteTransformFeedback(GLuint transformFeedback);
void deleteFenceSync(GLsync fenceSync); 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
...@@ -301,6 +305,7 @@ class Context ...@@ -301,6 +305,7 @@ class Context
void useProgram(GLuint program); void useProgram(GLuint program);
void linkProgram(GLuint program); void linkProgram(GLuint program);
void setProgramBinary(GLuint program, const void *binary, GLint length); void setProgramBinary(GLuint program, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
void beginQuery(GLenum target, GLuint query); void beginQuery(GLenum target, GLuint query);
void endQuery(GLenum target); void endQuery(GLenum target);
...@@ -330,6 +335,7 @@ class Context ...@@ -330,6 +335,7 @@ class Context
VertexArray *getVertexArray(GLuint handle) const; VertexArray *getVertexArray(GLuint handle) const;
Sampler *getSampler(GLuint handle) const; Sampler *getSampler(GLuint handle) const;
Query *getQuery(GLuint handle, bool create, GLenum type); Query *getQuery(GLuint handle, bool create, GLenum type);
TransformFeedback *getTransformFeedback(GLuint handle) const;
Buffer *getArrayBuffer(); Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer(); Buffer *getElementArrayBuffer();
...@@ -354,6 +360,7 @@ class Context ...@@ -354,6 +360,7 @@ class Context
Framebuffer *getReadFramebuffer(); Framebuffer *getReadFramebuffer();
Framebuffer *getDrawFramebuffer(); Framebuffer *getDrawFramebuffer();
VertexArray *getCurrentVertexArray() const; VertexArray *getCurrentVertexArray() const;
TransformFeedback *getCurrentTransformFeedback() const;
bool isSampler(GLuint samplerName) const; bool isSampler(GLuint samplerName) const;
...@@ -463,6 +470,7 @@ class Context ...@@ -463,6 +470,7 @@ class Context
void detachFramebuffer(GLuint framebuffer); void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer); void detachRenderbuffer(GLuint renderbuffer);
void detachVertexArray(GLuint vertexArray); void detachVertexArray(GLuint vertexArray);
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler); void detachSampler(GLuint sampler);
void generateSwizzles(ProgramBinary *programBinary); void generateSwizzles(ProgramBinary *programBinary);
...@@ -506,6 +514,11 @@ class Context ...@@ -506,6 +514,11 @@ class Context
VertexArrayMap mVertexArrayMap; VertexArrayMap mVertexArrayMap;
HandleAllocator mVertexArrayHandleAllocator; HandleAllocator mVertexArrayHandleAllocator;
BindingPointer<TransformFeedback> mTransformFeedbackZero;
typedef std::unordered_map<GLuint, TransformFeedback*> TransformFeedbackMap;
TransformFeedbackMap mTransformFeedbackMap;
HandleAllocator mTransformFeedbackAllocator;
std::vector<std::string> mExtensionStringList; std::vector<std::string> mExtensionStringList;
const char *mCombinedExtensionsString; const char *mCombinedExtensionsString;
const char *mRendererString; const char *mRendererString;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "libGLESv2/Query.h" #include "libGLESv2/Query.h"
#include "libGLESv2/Context.h" #include "libGLESv2/Context.h"
#include "libGLESv2/VertexArray.h" #include "libGLESv2/VertexArray.h"
#include "libGLESv2/TransformFeedback.h"
#include "libGLESv2/validationES.h" #include "libGLESv2/validationES.h"
#include "libGLESv2/validationES2.h" #include "libGLESv2/validationES2.h"
...@@ -7355,8 +7356,32 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode) ...@@ -7355,8 +7356,32 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glBeginTransformFeedback switch (primitiveMode)
UNIMPLEMENTED(); {
case GL_TRIANGLES:
case GL_LINES:
case GL_POINTS:
break;
default:
return gl::error(GL_INVALID_ENUM);
}
gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
ASSERT(transformFeedback != NULL);
if (transformFeedback->isStarted())
{
return gl::error(GL_INVALID_OPERATION);
}
if (transformFeedback->isPaused())
{
transformFeedback->resume();
}
else
{
transformFeedback->start(primitiveMode);
}
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -7380,8 +7405,15 @@ void __stdcall glEndTransformFeedback(void) ...@@ -7380,8 +7405,15 @@ void __stdcall glEndTransformFeedback(void)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glEndTransformFeedback gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
UNIMPLEMENTED(); ASSERT(transformFeedback != NULL);
if (!transformFeedback->isStarted())
{
return gl::error(GL_INVALID_OPERATION);
}
transformFeedback->stop();
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -9500,8 +9532,30 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id) ...@@ -9500,8 +9532,30 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glBindTransformFeedback switch (target)
UNIMPLEMENTED(); {
case GL_TRANSFORM_FEEDBACK:
{
// Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1)
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
return gl::error(GL_INVALID_OPERATION);
}
// Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
if (context->getTransformFeedback(id) == NULL)
{
return gl::error(GL_INVALID_OPERATION);
}
context->bindTransformFeedback(id);
}
break;
default:
return gl::error(GL_INVALID_ENUM);
}
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -9525,8 +9579,10 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) ...@@ -9525,8 +9579,10 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glDeleteTransformFeedbacks for (int i = 0; i < n; i++)
UNIMPLEMENTED(); {
context->deleteTransformFeedback(ids[i]);
}
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -9550,8 +9606,10 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) ...@@ -9550,8 +9606,10 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glGenTransformFeedbacks for (int i = 0; i < n; i++)
UNIMPLEMENTED(); {
ids[i] = context->createTransformFeedback();
}
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -9575,8 +9633,7 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id) ...@@ -9575,8 +9633,7 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id)
return gl::error(GL_INVALID_OPERATION, GL_FALSE); return gl::error(GL_INVALID_OPERATION, GL_FALSE);
} }
// glIsTransformFeedback return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
UNIMPLEMENTED();
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -9602,8 +9659,16 @@ void __stdcall glPauseTransformFeedback(void) ...@@ -9602,8 +9659,16 @@ void __stdcall glPauseTransformFeedback(void)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glPauseTransformFeedback gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
UNIMPLEMENTED(); ASSERT(transformFeedback != NULL);
// Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
if (!transformFeedback->isStarted() || transformFeedback->isPaused())
{
return gl::error(GL_INVALID_OPERATION);
}
transformFeedback->pause();
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -9627,8 +9692,16 @@ void __stdcall glResumeTransformFeedback(void) ...@@ -9627,8 +9692,16 @@ void __stdcall glResumeTransformFeedback(void)
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glResumeTransformFeedback gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
UNIMPLEMENTED(); ASSERT(transformFeedback != NULL);
// Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
{
return gl::error(GL_INVALID_OPERATION);
}
transformFeedback->resume();
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
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