Commit eeba6e1e by Geoff Lang

Added methods for applying the current transform feedback buffers.

BUG=angle:495 Change-Id: I2d9fbf9c245bc519b8c5a724ca3912aaa7a23d97 Reviewed-on: https://chromium-review.googlesource.com/185034Tested-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent ca442ba4
#include "precompiled.h"
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -141,6 +141,12 @@ GLint64 Buffer::mapLength() const
return mMapLength;
}
void Buffer::markTransformFeedbackUsage()
{
mBufferStorage->markTransformFeedbackUsage();
invalidateStaticData();
}
rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer()
{
return mStaticVertexBuffer;
......
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -49,6 +49,8 @@ class Buffer : public RefCountObject
rx::BufferStorage *getStorage() const;
unsigned int size() const;
void markTransformFeedbackUsage();
rx::StaticVertexBufferInterface *getStaticVertexBuffer();
rx::StaticIndexBufferInterface *getStaticIndexBuffer();
void invalidateStaticData();
......
#include "precompiled.h"
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -2619,7 +2619,38 @@ bool Context::applyUniformBuffers()
return programBinary->applyUniformBuffers(boundBuffers);
}
bool Context::applyTransformFeedbackBuffers()
{
TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
transformFeedbackBuffers[i] = mState.transformFeedbackBuffers[i].get();
transformFeedbackOffsets[i] = mState.transformFeedbackBuffers[i].getOffset();
}
mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
return true;
}
else
{
return false;
}
}
void Context::markTransformFeedbackUsage()
{
for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
Buffer *buffer = mState.transformFeedbackBuffers[i].get();
if (buffer)
{
buffer->markTransformFeedbackUsage();
}
}
}
void Context::clear(GLbitfield mask)
{
......@@ -2945,6 +2976,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
return gl::error(err);
}
bool transformFeedbackActive = applyTransformFeedbackBuffers();
applyShaders(programBinary);
applyTextures(programBinary);
......@@ -2961,6 +2994,11 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
if (!skipDraw(mode))
{
mRenderer->drawArrays(mode, count, instances);
if (transformFeedbackActive)
{
markTransformFeedbackUsage();
}
}
}
......@@ -3008,6 +3046,11 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
return gl::error(err);
}
bool transformFeedbackActive = applyTransformFeedbackBuffers();
// Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
// layer.
ASSERT(!transformFeedbackActive);
applyShaders(programBinary);
applyTextures(programBinary);
......
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -464,6 +464,8 @@ class Context
void applyTextures(ProgramBinary *programBinary);
void applyTextures(ProgramBinary *programBinary, SamplerType type);
bool applyUniformBuffers();
bool applyTransformFeedbackBuffers();
void markTransformFeedbackUsage();
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
......
......@@ -1670,6 +1670,16 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
if (context)
{
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
context->drawArrays(mode, first, count, 0);
}
}
......@@ -1696,6 +1706,16 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
if (context)
{
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
context->drawArrays(mode, first, count, primcount);
}
}
......@@ -1730,13 +1750,21 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
case GL_UNSIGNED_INT:
if (!context->supports32bitIndices())
{
return gl::error(GL_INVALID_ENUM);
return gl::error(GL_INVALID_ENUM);
}
break;
default:
return gl::error(GL_INVALID_ENUM);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
context->drawElements(mode, count, type, indices, 0);
}
}
......@@ -1772,13 +1800,21 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
case GL_UNSIGNED_INT:
if (!context->supports32bitIndices())
{
return gl::error(GL_INVALID_ENUM);
return gl::error(GL_INVALID_ENUM);
}
break;
default:
return gl::error(GL_INVALID_ENUM);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
context->drawElements(mode, count, type, indices, primcount);
}
}
......
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -26,6 +26,7 @@ class BufferStorage
virtual void copyData(BufferStorage* sourceStorage, unsigned int size,
unsigned int sourceOffset, unsigned int destOffset) = 0;
virtual void clear() = 0;
virtual void markTransformFeedbackUsage() = 0;
virtual unsigned int getSize() const = 0;
virtual bool supportsDirectBinding() const = 0;
unsigned int getSerial() const;
......
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -132,6 +132,7 @@ class Renderer
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances) = 0;
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0;
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0;
virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
......
#include "precompiled.h"
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -165,6 +165,12 @@ void BufferStorage11::clear()
mResolvedDataRevision = 0;
}
void BufferStorage11::markTransformFeedbackUsage()
{
DirectBufferStorage11 *transformFeedbackStorage = getStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
}
unsigned int BufferStorage11::getSize() const
{
return mSize;
......@@ -420,9 +426,9 @@ void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Render
bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
break;
case BUFFER_USAGE_VERTEX:
case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
bufferDesc->CPUAccessFlags = 0;
break;
......
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -19,11 +19,11 @@ class DirectBufferStorage11;
enum BufferUsage
{
BUFFER_USAGE_STAGING = 0,
BUFFER_USAGE_VERTEX = 1,
BUFFER_USAGE_INDEX = 2,
BUFFER_USAGE_PIXEL_UNPACK = 3,
BUFFER_USAGE_UNIFORM = 4,
BUFFER_USAGE_STAGING,
BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
BUFFER_USAGE_INDEX,
BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_UNIFORM,
};
typedef size_t DataRevision;
......@@ -41,6 +41,7 @@ class BufferStorage11 : public BufferStorage
virtual void copyData(BufferStorage* sourceStorage, unsigned int size,
unsigned int sourceOffset, unsigned int destOffset);
virtual void clear();
virtual void markTransformFeedbackUsage();
virtual unsigned int getSize() const;
virtual bool supportsDirectBinding() const;
......
......@@ -133,7 +133,8 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M
ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor;
ilKey.elementCount++;
vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX) : vertexBuffer->getBuffer();
vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
: vertexBuffer->getBuffer();
vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial();
vertexStrides[i] = attributes[i].stride;
vertexOffsets[i] = attributes[i].offset;
......
#include "precompiled.h"
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -1180,6 +1180,44 @@ GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementAr
return err;
}
void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
{
ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
bool requiresUpdate = false;
for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
if (transformFeedbackBuffers[i])
{
BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(transformFeedbackBuffers[i]->getStorage());
ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
d3dBuffers[i] = buffer;
d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1;
}
else
{
d3dBuffers[i] = NULL;
d3dOffsets[i] = 0;
}
if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i])
{
requiresUpdate = true;
}
}
if (requiresUpdate)
{
mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets);
for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
mAppliedTFBuffers[i] = d3dBuffers[i];
mAppliedTFOffsets[i] = offsets[i];
}
}
}
void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
{
if (mode == GL_LINE_LOOP)
......@@ -1683,6 +1721,13 @@ void Renderer11::markAllStateDirty()
mAppliedVertexShader = NULL;
mAppliedGeometryShader = NULL;
mAppliedPixelShader = NULL;
for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
mAppliedTFBuffers[i] = NULL;
mAppliedTFOffsets[i] = 0;
}
memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
......
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -81,6 +81,7 @@ class Renderer11 : public Renderer
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
......@@ -343,10 +344,16 @@ class Renderer11 : public Renderer
// Currently applied primitive topology
D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
// Currently applied index buffer
unsigned int mAppliedIBSerial;
unsigned int mAppliedStorageIBSerial;
unsigned int mAppliedIBOffset;
// Currently applied transform feedback buffers
ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
// Currently applied shaders
ID3D11VertexShader *mAppliedVertexShader;
ID3D11GeometryShader *mAppliedGeometryShader;
ID3D11PixelShader *mAppliedPixelShader;
......
#include "precompiled.h"
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -78,6 +78,11 @@ void BufferStorage9::clear()
mSize = 0;
}
void BufferStorage9::markTransformFeedbackUsage()
{
UNREACHABLE();
}
unsigned int BufferStorage9::getSize() const
{
return mSize;
......
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -27,6 +27,7 @@ class BufferStorage9 : public BufferStorage
virtual void copyData(BufferStorage* sourceStorage, unsigned int size,
unsigned int sourceOffset, unsigned int destOffset);
virtual void clear();
virtual void markTransformFeedbackUsage();
virtual unsigned int getSize() const;
virtual bool supportsDirectBinding() const;
......
#include "precompiled.h"
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -1447,6 +1447,11 @@ GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArr
return err;
}
void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
{
UNREACHABLE();
}
void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
{
startScene();
......
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -83,6 +83,8 @@ class Renderer9 : public Renderer
GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
......
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