| // |
| // Copyright 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. |
| // |
| |
| // TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. |
| |
| #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" |
| |
| #include "libANGLE/Buffer.h" |
| #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" |
| #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" |
| |
| namespace rx |
| { |
| |
| TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state, |
| Renderer11 *renderer) |
| : TransformFeedbackImpl(state), |
| mRenderer(renderer), |
| mIsDirty(true), |
| mBuffers(state.getIndexedBuffers().size(), nullptr), |
| mBufferOffsets(state.getIndexedBuffers().size(), 0), |
| mSerial(mRenderer->generateSerial()) |
| {} |
| |
| TransformFeedback11::~TransformFeedback11() {} |
| |
| angle::Result TransformFeedback11::begin(const gl::Context *context, |
| gl::PrimitiveMode primitiveMode) |
| { |
| // Reset all the cached offsets to the binding offsets |
| mIsDirty = true; |
| for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) |
| { |
| const auto &binding = mState.getIndexedBuffer(bindingIdx); |
| if (binding.get() != nullptr) |
| { |
| mBufferOffsets[bindingIdx] = static_cast<UINT>(binding.getOffset()); |
| } |
| else |
| { |
| mBufferOffsets[bindingIdx] = 0; |
| } |
| } |
| mRenderer->getStateManager()->invalidateTransformFeedback(); |
| return angle::Result::Continue; |
| } |
| |
| angle::Result TransformFeedback11::end(const gl::Context *context) |
| { |
| mRenderer->getStateManager()->invalidateTransformFeedback(); |
| if (mRenderer->getFeatures().flushAfterEndingTransformFeedback.enabled) |
| { |
| mRenderer->getDeviceContext()->Flush(); |
| } |
| return angle::Result::Continue; |
| } |
| |
| angle::Result TransformFeedback11::pause(const gl::Context *context) |
| { |
| mRenderer->getStateManager()->invalidateTransformFeedback(); |
| return angle::Result::Continue; |
| } |
| |
| angle::Result TransformFeedback11::resume(const gl::Context *context) |
| { |
| mRenderer->getStateManager()->invalidateTransformFeedback(); |
| return angle::Result::Continue; |
| } |
| |
| angle::Result TransformFeedback11::bindIndexedBuffer( |
| const gl::Context *context, |
| size_t index, |
| const gl::OffsetBindingPointer<gl::Buffer> &binding) |
| { |
| mIsDirty = true; |
| mBufferOffsets[index] = static_cast<UINT>(binding.getOffset()); |
| mRenderer->getStateManager()->invalidateTransformFeedback(); |
| return angle::Result::Continue; |
| } |
| |
| void TransformFeedback11::onApply() |
| { |
| mIsDirty = false; |
| |
| // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to |
| // append |
| std::fill(mBufferOffsets.begin(), mBufferOffsets.end(), -1); |
| } |
| |
| bool TransformFeedback11::isDirty() const |
| { |
| return mIsDirty; |
| } |
| |
| UINT TransformFeedback11::getNumSOBuffers() const |
| { |
| return static_cast<UINT>(mBuffers.size()); |
| } |
| |
| angle::Result TransformFeedback11::getSOBuffers(const gl::Context *context, |
| const std::vector<ID3D11Buffer *> **buffersOut) |
| { |
| for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) |
| { |
| const auto &binding = mState.getIndexedBuffer(bindingIdx); |
| if (binding.get() != nullptr) |
| { |
| Buffer11 *storage = GetImplAs<Buffer11>(binding.get()); |
| ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, |
| &mBuffers[bindingIdx])); |
| } |
| } |
| |
| *buffersOut = &mBuffers; |
| return angle::Result::Continue; |
| } |
| |
| const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const |
| { |
| return mBufferOffsets; |
| } |
| |
| Serial TransformFeedback11::getSerial() const |
| { |
| return mSerial; |
| } |
| |
| } // namespace rx |