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 }
28 
~TransformFeedback11()29 TransformFeedback11::~TransformFeedback11()
30 {
31 }
32 
begin(GLenum primitiveMode)33 void TransformFeedback11::begin(GLenum primitiveMode)
34 {
35     // Reset all the cached offsets to the binding offsets
36     mIsDirty = true;
37     for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++)
38     {
39         const auto &binding = mState.getIndexedBuffer(bindingIdx);
40         if (binding.get() != nullptr)
41         {
42             mBufferOffsets[bindingIdx] = static_cast<UINT>(binding.getOffset());
43         }
44         else
45         {
46             mBufferOffsets[bindingIdx] = 0;
47         }
48     }
49 }
50 
end()51 void TransformFeedback11::end()
52 {
53     if (mRenderer->getWorkarounds().flushAfterEndingTransformFeedback)
54     {
55         mRenderer->getDeviceContext()->Flush();
56     }
57 }
58 
pause()59 void TransformFeedback11::pause()
60 {
61 }
62 
resume()63 void TransformFeedback11::resume()
64 {
65 }
66 
bindGenericBuffer(const gl::BindingPointer<gl::Buffer> & binding)67 void TransformFeedback11::bindGenericBuffer(const gl::BindingPointer<gl::Buffer> &binding)
68 {
69 }
70 
bindIndexedBuffer(size_t index,const gl::OffsetBindingPointer<gl::Buffer> & binding)71 void TransformFeedback11::bindIndexedBuffer(size_t index,
72                                             const gl::OffsetBindingPointer<gl::Buffer> &binding)
73 {
74     mIsDirty              = true;
75     mBufferOffsets[index] = static_cast<UINT>(binding.getOffset());
76 }
77 
onApply()78 void TransformFeedback11::onApply()
79 {
80     mIsDirty = false;
81 
82     // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to
83     // append
84     std::fill(mBufferOffsets.begin(), mBufferOffsets.end(), -1);
85 }
86 
isDirty() const87 bool TransformFeedback11::isDirty() const
88 {
89     return mIsDirty;
90 }
91 
getNumSOBuffers() const92 UINT TransformFeedback11::getNumSOBuffers() const
93 {
94     return static_cast<UINT>(mBuffers.size());
95 }
96 
getSOBuffers(const gl::Context * context)97 gl::ErrorOrResult<const std::vector<ID3D11Buffer *> *> TransformFeedback11::getSOBuffers(
98     const gl::Context *context)
99 {
100     for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++)
101     {
102         const auto &binding = mState.getIndexedBuffer(bindingIdx);
103         if (binding.get() != nullptr)
104         {
105             Buffer11 *storage = GetImplAs<Buffer11>(binding.get());
106             ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK),
107                              mBuffers[bindingIdx]);
108         }
109     }
110 
111     return &mBuffers;
112 }
113 
getSOBufferOffsets() const114 const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const
115 {
116     return mBufferOffsets;
117 }
118 
getSerial() const119 Serial TransformFeedback11::getSerial() const
120 {
121     return mSerial;
122 }
123 
124 }  // namespace rx
125