1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "RenderAPI/BsRenderAPI.h" |
4 | |
5 | #include "CoreThread/BsCoreThread.h" |
6 | #include "RenderAPI/BsViewport.h" |
7 | #include "RenderAPI/BsRenderTarget.h" |
8 | #include "RenderAPI/BsRenderWindow.h" |
9 | #include "Mesh/BsMesh.h" |
10 | #include "RenderAPI/BsGpuParams.h" |
11 | #include "RenderAPI/BsDepthStencilState.h" |
12 | #include "RenderAPI/BsRasterizerState.h" |
13 | #include "RenderAPI/BsGpuBuffer.h" |
14 | #include "RenderAPI/BsGpuPipelineState.h" |
15 | |
16 | using namespace std::placeholders; |
17 | |
18 | namespace bs |
19 | { |
20 | void RenderAPI::setGpuParams(const SPtr<GpuParams>& gpuParams) |
21 | { |
22 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setGpuParams, ct::RenderAPI::instancePtr(), gpuParams->getCore(), |
23 | nullptr)); |
24 | } |
25 | |
26 | void RenderAPI::setGraphicsPipeline(const SPtr<GraphicsPipelineState>& pipelineState) |
27 | { |
28 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setGraphicsPipeline, ct::RenderAPI::instancePtr(), |
29 | pipelineState->getCore(), nullptr)); |
30 | } |
31 | |
32 | void RenderAPI::setComputePipeline(const SPtr<ComputePipelineState>& pipelineState) |
33 | { |
34 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setComputePipeline, ct::RenderAPI::instancePtr(), |
35 | pipelineState->getCore(), nullptr)); |
36 | } |
37 | |
38 | void RenderAPI::setVertexBuffers(UINT32 index, const Vector<SPtr<VertexBuffer>>& buffers) |
39 | { |
40 | Vector<SPtr<ct::VertexBuffer>> coreBuffers(buffers.size()); |
41 | for (UINT32 i = 0; i < (UINT32)buffers.size(); i++) |
42 | coreBuffers[i] = buffers[i] != nullptr ? buffers[i]->getCore() : nullptr; |
43 | |
44 | std::function<void(ct::RenderAPI*, UINT32, const Vector<SPtr<ct::VertexBuffer>>&)> resizeFunc = |
45 | [](ct::RenderAPI* rs, UINT32 idx, const Vector<SPtr<ct::VertexBuffer>>& _buffers) |
46 | { |
47 | rs->setVertexBuffers(idx, (SPtr<ct::VertexBuffer>*)_buffers.data(), (UINT32)_buffers.size()); |
48 | }; |
49 | |
50 | gCoreThread().queueCommand(std::bind(resizeFunc, ct::RenderAPI::instancePtr(), index, coreBuffers)); |
51 | } |
52 | |
53 | void RenderAPI::setIndexBuffer(const SPtr<IndexBuffer>& buffer) |
54 | { |
55 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setIndexBuffer, ct::RenderAPI::instancePtr(), buffer->getCore(), |
56 | nullptr)); |
57 | } |
58 | |
59 | void RenderAPI::setVertexDeclaration(const SPtr<VertexDeclaration>& vertexDeclaration) |
60 | { |
61 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setVertexDeclaration, ct::RenderAPI::instancePtr(), |
62 | vertexDeclaration->getCore(), nullptr)); |
63 | } |
64 | |
65 | void RenderAPI::setViewport(const Rect2& vp) |
66 | { |
67 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setViewport, ct::RenderAPI::instancePtr(), vp, nullptr)); |
68 | } |
69 | |
70 | void RenderAPI::setStencilRef(UINT32 value) |
71 | { |
72 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setStencilRef, ct::RenderAPI::instancePtr(), value, nullptr)); |
73 | } |
74 | |
75 | void RenderAPI::setDrawOperation(DrawOperationType op) |
76 | { |
77 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setDrawOperation, ct::RenderAPI::instancePtr(), op, |
78 | nullptr)); |
79 | } |
80 | |
81 | void RenderAPI::setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom) |
82 | { |
83 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setScissorRect, ct::RenderAPI::instancePtr(), left, top, right, bottom, |
84 | nullptr)); |
85 | } |
86 | |
87 | void RenderAPI::setRenderTarget(const SPtr<RenderTarget>& target, UINT32 readOnlyFlags, |
88 | RenderSurfaceMask loadMask) |
89 | { |
90 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::setRenderTarget, |
91 | ct::RenderAPI::instancePtr(), target->getCore(), readOnlyFlags, loadMask, nullptr)); |
92 | } |
93 | |
94 | void RenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, |
95 | UINT16 stencil, UINT8 targetMask) |
96 | { |
97 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::clearRenderTarget, ct::RenderAPI::instancePtr(), buffers, color, |
98 | depth, stencil, targetMask, nullptr)); |
99 | } |
100 | |
101 | void RenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil, |
102 | UINT8 targetMask) |
103 | { |
104 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::clearViewport, ct::RenderAPI::instancePtr(), buffers, color, depth, |
105 | stencil, targetMask, nullptr)); |
106 | } |
107 | |
108 | void RenderAPI::swapBuffers(const SPtr<RenderTarget>& target) |
109 | { |
110 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::swapBuffers, ct::RenderAPI::instancePtr(), target->getCore(), 1)); |
111 | } |
112 | |
113 | void RenderAPI::draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount) |
114 | { |
115 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::draw, ct::RenderAPI::instancePtr(), vertexOffset, |
116 | vertexCount, instanceCount, nullptr)); |
117 | } |
118 | |
119 | void RenderAPI::drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, |
120 | UINT32 vertexCount, UINT32 instanceCount) |
121 | { |
122 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::drawIndexed, ct::RenderAPI::instancePtr(), startIndex, indexCount, |
123 | vertexOffset, vertexCount, instanceCount, nullptr)); |
124 | } |
125 | |
126 | void RenderAPI::dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY, UINT32 numGroupsZ) |
127 | { |
128 | gCoreThread().queueCommand(std::bind(&ct::RenderAPI::dispatchCompute, ct::RenderAPI::instancePtr(), numGroupsX, |
129 | numGroupsY, numGroupsZ, nullptr)); |
130 | } |
131 | |
132 | const VideoModeInfo& RenderAPI::getVideoModeInfo() |
133 | { |
134 | return ct::RenderAPI::instance().getVideoModeInfo(); |
135 | } |
136 | |
137 | void RenderAPI::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest) |
138 | { |
139 | ct::RenderAPI::instance().convertProjectionMatrix(matrix, dest); |
140 | } |
141 | |
142 | namespace ct |
143 | { |
144 | RenderAPI::RenderAPI() |
145 | : mCurrentCapabilities(nullptr), mNumDevices(0) |
146 | { |
147 | } |
148 | |
149 | RenderAPI::~RenderAPI() |
150 | { |
151 | // Base classes need to call virtual destroy_internal method instead of a destructor |
152 | |
153 | bs_deleteN(mCurrentCapabilities, mNumDevices); |
154 | mCurrentCapabilities = nullptr; |
155 | } |
156 | |
157 | SPtr<bs::RenderWindow> RenderAPI::initialize(const RENDER_WINDOW_DESC& primaryWindowDesc) |
158 | { |
159 | gCoreThread().queueCommand(std::bind((void(RenderAPI::*)())&RenderAPI::initialize, this), |
160 | CTQF_InternalQueue | CTQF_BlockUntilComplete); |
161 | |
162 | RENDER_WINDOW_DESC windowDesc = primaryWindowDesc; |
163 | SPtr<bs::RenderWindow> renderWindow = bs::RenderWindow::create(windowDesc, nullptr); |
164 | |
165 | // Make sure render window initialization is submitted to the internal queue |
166 | gCoreThread().submitAll(); |
167 | |
168 | gCoreThread().queueCommand(std::bind(&RenderAPI::initializeWithWindow, this, renderWindow->getCore()), |
169 | CTQF_InternalQueue | CTQF_BlockUntilComplete); |
170 | |
171 | return renderWindow; |
172 | } |
173 | |
174 | void RenderAPI::initialize() |
175 | { |
176 | // Do nothing |
177 | } |
178 | |
179 | void RenderAPI::initializeWithWindow(const SPtr<RenderWindow>& primaryWindow) |
180 | { |
181 | THROW_IF_NOT_CORE_THREAD; |
182 | } |
183 | |
184 | void RenderAPI::destroy() |
185 | { |
186 | gCoreThread().queueCommand(std::bind(&RenderAPI::destroyCore, this)); |
187 | gCoreThread().submitAll(true); |
188 | } |
189 | |
190 | void RenderAPI::destroyCore() |
191 | { |
192 | mActiveRenderTarget = nullptr; |
193 | } |
194 | |
195 | const RenderAPICapabilities& RenderAPI::getCapabilities(UINT32 deviceIdx) const |
196 | { |
197 | if(deviceIdx >= mNumDevices) |
198 | { |
199 | LOGWRN("Invalid device index provided: " + toString(deviceIdx) + ". Valid range is: [0, " + toString(mNumDevices) + ")." ); |
200 | return mCurrentCapabilities[0]; |
201 | } |
202 | |
203 | return mCurrentCapabilities[deviceIdx]; |
204 | } |
205 | |
206 | UINT32 RenderAPI::vertexCountToPrimCount(DrawOperationType type, UINT32 elementCount) |
207 | { |
208 | UINT32 primCount = 0; |
209 | switch (type) |
210 | { |
211 | case DOT_POINT_LIST: |
212 | primCount = elementCount; |
213 | break; |
214 | |
215 | case DOT_LINE_LIST: |
216 | primCount = elementCount / 2; |
217 | break; |
218 | |
219 | case DOT_LINE_STRIP: |
220 | primCount = elementCount - 1; |
221 | break; |
222 | |
223 | case DOT_TRIANGLE_LIST: |
224 | primCount = elementCount / 3; |
225 | break; |
226 | |
227 | case DOT_TRIANGLE_STRIP: |
228 | primCount = elementCount - 2; |
229 | break; |
230 | |
231 | case DOT_TRIANGLE_FAN: |
232 | primCount = elementCount - 2; |
233 | break; |
234 | } |
235 | |
236 | return primCount; |
237 | } |
238 | } |
239 | } |