1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers.
8
9 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
10
11 #include "libANGLE/Buffer.h"
12 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
13 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
14
15 namespace rx
16 {
17
TransformFeedback11(const gl::TransformFeedbackState & state,Renderer11 * renderer)18 TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state,
19 Renderer11 *renderer)
20 : TransformFeedbackImpl(state),
21 mRenderer(renderer),
22 mIsDirty(true),
23 mBuffers(state.getIndexedBuffers().size(), nullptr),
24 mBufferOffsets(state.getIndexedBuffers().size(), 0),
25 mSerial(mRenderer->generateSerial())
26 {}
27
~TransformFeedback11()28 TransformFeedback11::~TransformFeedback11() {}
29
begin(const gl::Context * context,gl::PrimitiveMode primitiveMode)30 angle::Result TransformFeedback11::begin(const gl::Context *context,
31 gl::PrimitiveMode primitiveMode)
32 {
33 // Reset all the cached offsets to the binding offsets
34 mIsDirty = true;
35 for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++)
36 {
37 const auto &binding = mState.getIndexedBuffer(bindingIdx);
38 if (binding.get() != nullptr)
39 {
40 mBufferOffsets[bindingIdx] = static_cast<UINT>(binding.getOffset());
41 }
42 else
43 {
44 mBufferOffsets[bindingIdx] = 0;
45 }
46 }
47 mRenderer->getStateManager()->invalidateTransformFeedback();
48 return angle::Result::Continue;
49 }
50
end(const gl::Context * context)51 angle::Result TransformFeedback11::end(const gl::Context *context)
52 {
53 mRenderer->getStateManager()->invalidateTransformFeedback();
54 if (mRenderer->getFeatures().flushAfterEndingTransformFeedback.enabled)
55 {
56 mRenderer->getDeviceContext()->Flush();
57 }
58 return angle::Result::Continue;
59 }
60
pause(const gl::Context * context)61 angle::Result TransformFeedback11::pause(const gl::Context *context)
62 {
63 mRenderer->getStateManager()->invalidateTransformFeedback();
64 return angle::Result::Continue;
65 }
66
resume(const gl::Context * context)67 angle::Result TransformFeedback11::resume(const gl::Context *context)
68 {
69 mRenderer->getStateManager()->invalidateTransformFeedback();
70 return angle::Result::Continue;
71 }
72
bindIndexedBuffer(const gl::Context * context,size_t index,const gl::OffsetBindingPointer<gl::Buffer> & binding)73 angle::Result TransformFeedback11::bindIndexedBuffer(
74 const gl::Context *context,
75 size_t index,
76 const gl::OffsetBindingPointer<gl::Buffer> &binding)
77 {
78 mIsDirty = true;
79 mBufferOffsets[index] = static_cast<UINT>(binding.getOffset());
80 mRenderer->getStateManager()->invalidateTransformFeedback();
81 return angle::Result::Continue;
82 }
83
onApply()84 void TransformFeedback11::onApply()
85 {
86 mIsDirty = false;
87
88 // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to
89 // append
90 std::fill(mBufferOffsets.begin(), mBufferOffsets.end(), -1);
91 }
92
isDirty() const93 bool TransformFeedback11::isDirty() const
94 {
95 return mIsDirty;
96 }
97
getNumSOBuffers() const98 UINT TransformFeedback11::getNumSOBuffers() const
99 {
100 return static_cast<UINT>(mBuffers.size());
101 }
102
getSOBuffers(const gl::Context * context,const std::vector<ID3D11Buffer * > ** buffersOut)103 angle::Result TransformFeedback11::getSOBuffers(const gl::Context *context,
104 const std::vector<ID3D11Buffer *> **buffersOut)
105 {
106 for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++)
107 {
108 const auto &binding = mState.getIndexedBuffer(bindingIdx);
109 if (binding.get() != nullptr)
110 {
111 Buffer11 *storage = GetImplAs<Buffer11>(binding.get());
112 ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
113 &mBuffers[bindingIdx]));
114 }
115 }
116
117 *buffersOut = &mBuffers;
118 return angle::Result::Continue;
119 }
120
getSOBufferOffsets() const121 const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const
122 {
123 return mBufferOffsets;
124 }
125
getSerial() const126 UniqueSerial TransformFeedback11::getSerial() const
127 {
128 return mSerial;
129 }
130
131 } // namespace rx
132