blob: d52338f3889b522811d7c517d5cf363c84f8bbd1 [file] [log] [blame]
//
// 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->getWorkarounds().flushAfterEndingTransformFeedback)
{
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::bindGenericBuffer(const gl::Context *context,
const gl::BindingPointer<gl::Buffer> &binding)
{
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