// // 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(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 &binding) { mIsDirty = true; mBufferOffsets[index] = static_cast(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(mBuffers.size()); } angle::Result TransformFeedback11::getSOBuffers(const gl::Context *context, const std::vector **buffersOut) { for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) { const auto &binding = mState.getIndexedBuffer(bindingIdx); if (binding.get() != nullptr) { Buffer11 *storage = GetImplAs(binding.get()); ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, &mBuffers[bindingIdx])); } } *buffersOut = &mBuffers; return angle::Result::Continue; } const std::vector &TransformFeedback11::getSOBufferOffsets() const { return mBufferOffsets; } Serial TransformFeedback11::getSerial() const { return mSerial; } } // namespace rx