Hash :
73bd218e
Author :
Date :
2016-07-15T13:01:24
Support virtualized contexts and transform feedback in Renderer11. Track buffer offets in the transform feedback object and dirty them when a buffer is bound. This fixes problems when a buffer is rebound at the same offset and maintains tracking between context switches. BUG=angleproject:1447 BUG=angleproject:1298 Change-Id: I2f890e3ad5edacab47f624a95a502615c86cc0c8 Reviewed-on: https://chromium-review.googlesource.com/360910 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
//
// Copyright 2015 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.
//
// TransformFeedbackGL.cpp: Implements the class methods for TransformFeedbackGL.
#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
#include "common/debug.h"
#include "libANGLE/ContextState.h"
#include "libANGLE/renderer/gl/BufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
namespace rx
{
TransformFeedbackGL::TransformFeedbackGL(const gl::TransformFeedbackState &state,
const FunctionsGL *functions,
StateManagerGL *stateManager)
: TransformFeedbackImpl(state),
mFunctions(functions),
mStateManager(stateManager),
mTransformFeedbackID(0),
mIsActive(false),
mIsPaused(false)
{
mFunctions->genTransformFeedbacks(1, &mTransformFeedbackID);
}
TransformFeedbackGL::~TransformFeedbackGL()
{
mStateManager->deleteTransformFeedback(mTransformFeedbackID);
mTransformFeedbackID = 0;
}
void TransformFeedbackGL::begin(GLenum primitiveMode)
{
// Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback.
}
void TransformFeedbackGL::end()
{
syncActiveState(false, GL_NONE);
}
void TransformFeedbackGL::pause()
{
syncPausedState(true);
}
void TransformFeedbackGL::resume()
{
// Do not resume directly, StateManagerGL will handle beginning and resuming transform feedback.
}
void TransformFeedbackGL::bindGenericBuffer(const BindingPointer<gl::Buffer> &binding)
{
}
void TransformFeedbackGL::bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding)
{
// Directly bind buffer (not through the StateManager methods) because the buffer bindings are
// tracked per transform feedback object
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (binding.get() != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get());
if (binding.getSize() != 0)
{
mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID(), binding.getOffset(),
binding.getSize());
}
else
{
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID());
}
}
else
{
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0);
}
}
GLuint TransformFeedbackGL::getTransformFeedbackID() const
{
return mTransformFeedbackID;
}
void TransformFeedbackGL::syncActiveState(bool active, GLenum primitiveMode) const
{
if (mIsActive != active)
{
mIsActive = active;
mIsPaused = false;
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (mIsActive)
{
mFunctions->beginTransformFeedback(primitiveMode);
}
else
{
mFunctions->endTransformFeedback();
}
}
}
void TransformFeedbackGL::syncPausedState(bool paused) const
{
if (mIsActive && mIsPaused != paused)
{
mIsPaused = paused;
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (mIsPaused)
{
mFunctions->pauseTransformFeedback();
}
else
{
mFunctions->resumeTransformFeedback();
}
}
}
}