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 @@
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Sampler.h"
#include "libGLESv2/validationES.h"
#include "libGLESv2/TransformFeedback.h"
#include "libEGL/Surface.h"
......@@ -192,6 +193,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
bindPixelPackBuffer(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;
mCurrentProgramBinary.set(NULL);
......@@ -252,6 +260,12 @@ Context::~Context()
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 sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
......@@ -274,6 +288,8 @@ Context::~Context()
mState.arrayBuffer.set(NULL);
mState.renderbuffer.set(NULL);
mState.transformFeedback.set(NULL);
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
mTexture3DZero.set(NULL);
......@@ -881,6 +897,15 @@ GLuint Context::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
GLuint Context::createFramebuffer()
{
......@@ -983,6 +1008,18 @@ void Context::deleteSampler(GLuint 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)
{
FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
......@@ -1072,6 +1109,19 @@ Sampler *Context::getSampler(GLuint handle) const
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()
{
return getFramebuffer(mState.readFramebuffer);
......@@ -1089,6 +1139,11 @@ VertexArray *Context::getCurrentVertexArray() const
return vao;
}
TransformFeedback *Context::getCurrentTransformFeedback() const
{
return mState.transformFeedback.get();
}
bool Context::isSampler(GLuint samplerName) const
{
return mResourceManager->isSampler(samplerName);
......@@ -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)
{
// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
......@@ -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)
{
// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
......
......@@ -67,6 +67,7 @@ class Buffer;
class VertexAttribute;
class VertexArray;
class Sampler;
class TransformFeedback;
// Helper structure to store all raw state
struct State
......@@ -117,6 +118,7 @@ struct State
BindingPointer<Buffer> genericUniformBuffer;
OffsetBindingPointer<Buffer> uniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
BindingPointer<TransformFeedback> transformFeedback;
BindingPointer<Buffer> genericTransformFeedbackBuffer;
OffsetBindingPointer<Buffer> transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
......@@ -253,6 +255,7 @@ class Context
GLuint createTexture();
GLuint createRenderbuffer();
GLuint createSampler();
GLuint createTransformFeedback();
GLsync createFenceSync(GLenum condition);
void deleteBuffer(GLuint buffer);
......@@ -261,6 +264,7 @@ class Context
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
void deleteSampler(GLuint sampler);
void deleteTransformFeedback(GLuint transformFeedback);
void deleteFenceSync(GLsync fenceSync);
// Framebuffers are owned by the Context, so these methods do not pass through
......@@ -301,6 +305,7 @@ class Context
void useProgram(GLuint program);
void linkProgram(GLuint program);
void setProgramBinary(GLuint program, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
void beginQuery(GLenum target, GLuint query);
void endQuery(GLenum target);
......@@ -330,6 +335,7 @@ class Context
VertexArray *getVertexArray(GLuint handle) const;
Sampler *getSampler(GLuint handle) const;
Query *getQuery(GLuint handle, bool create, GLenum type);
TransformFeedback *getTransformFeedback(GLuint handle) const;
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
......@@ -354,6 +360,7 @@ class Context
Framebuffer *getReadFramebuffer();
Framebuffer *getDrawFramebuffer();
VertexArray *getCurrentVertexArray() const;
TransformFeedback *getCurrentTransformFeedback() const;
bool isSampler(GLuint samplerName) const;
......@@ -463,6 +470,7 @@ class Context
void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer);
void detachVertexArray(GLuint vertexArray);
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
void generateSwizzles(ProgramBinary *programBinary);
......@@ -506,6 +514,11 @@ class Context
VertexArrayMap mVertexArrayMap;
HandleAllocator mVertexArrayHandleAllocator;
BindingPointer<TransformFeedback> mTransformFeedbackZero;
typedef std::unordered_map<GLuint, TransformFeedback*> TransformFeedbackMap;
TransformFeedbackMap mTransformFeedbackMap;
HandleAllocator mTransformFeedbackAllocator;
std::vector<std::string> mExtensionStringList;
const char *mCombinedExtensionsString;
const char *mRendererString;
......
......@@ -22,6 +22,7 @@
#include "libGLESv2/Query.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/TransformFeedback.h"
#include "libGLESv2/validationES.h"
#include "libGLESv2/validationES2.h"
......@@ -7355,8 +7356,32 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
return gl::error(GL_INVALID_OPERATION);
}
// glBeginTransformFeedback
UNIMPLEMENTED();
switch (primitiveMode)
{
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&)
......@@ -7380,8 +7405,15 @@ void __stdcall glEndTransformFeedback(void)
return gl::error(GL_INVALID_OPERATION);
}
// glEndTransformFeedback
UNIMPLEMENTED();
gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
ASSERT(transformFeedback != NULL);
if (!transformFeedback->isStarted())
{
return gl::error(GL_INVALID_OPERATION);
}
transformFeedback->stop();
}
}
catch(std::bad_alloc&)
......@@ -9500,8 +9532,30 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
return gl::error(GL_INVALID_OPERATION);
}
// glBindTransformFeedback
UNIMPLEMENTED();
switch (target)
{
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&)
......@@ -9525,8 +9579,10 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
return gl::error(GL_INVALID_OPERATION);
}
// glDeleteTransformFeedbacks
UNIMPLEMENTED();
for (int i = 0; i < n; i++)
{
context->deleteTransformFeedback(ids[i]);
}
}
}
catch(std::bad_alloc&)
......@@ -9550,8 +9606,10 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids)
return gl::error(GL_INVALID_OPERATION);
}
// glGenTransformFeedbacks
UNIMPLEMENTED();
for (int i = 0; i < n; i++)
{
ids[i] = context->createTransformFeedback();
}
}
}
catch(std::bad_alloc&)
......@@ -9575,8 +9633,7 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id)
return gl::error(GL_INVALID_OPERATION, GL_FALSE);
}
// glIsTransformFeedback
UNIMPLEMENTED();
return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
}
}
catch(std::bad_alloc&)
......@@ -9602,8 +9659,16 @@ void __stdcall glPauseTransformFeedback(void)
return gl::error(GL_INVALID_OPERATION);
}
// glPauseTransformFeedback
UNIMPLEMENTED();
gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
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&)
......@@ -9627,8 +9692,16 @@ void __stdcall glResumeTransformFeedback(void)
return gl::error(GL_INVALID_OPERATION);
}
// glResumeTransformFeedback
UNIMPLEMENTED();
gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
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&)
......
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