1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "Device.hpp"
16 
17 #include "common/Image.hpp"
18 #include "Texture.h"
19 
20 #include "Renderer/Renderer.hpp"
21 #include "Renderer/Clipper.hpp"
22 #include "Shader/PixelShader.hpp"
23 #include "Shader/VertexShader.hpp"
24 #include "Main/Config.hpp"
25 #include "Main/FrameBuffer.hpp"
26 #include "Common/Math.hpp"
27 #include "Common/Configurator.hpp"
28 #include "Common/Memory.hpp"
29 #include "Common/Timer.hpp"
30 #include "../common/debug.h"
31 
32 namespace es1
33 {
34 	using namespace sw;
35 
Device(Context * context)36 	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
37 	{
38 		renderTarget = nullptr;
39 		depthBuffer = nullptr;
40 		stencilBuffer = nullptr;
41 
42 		setDepthBufferEnable(true);
43 		setFillMode(FILL_SOLID);
44 		setShadingMode(SHADING_GOURAUD);
45 		setDepthWriteEnable(true);
46 		setAlphaTestEnable(false);
47 		setSourceBlendFactor(BLEND_ONE);
48 		setDestBlendFactor(BLEND_ZERO);
49 		setCullMode(CULL_COUNTERCLOCKWISE, true);
50 		setDepthCompare(DEPTH_LESSEQUAL);
51 		setAlphaReference(0.0f);
52 		setAlphaCompare(ALPHA_ALWAYS);
53 		setAlphaBlendEnable(false);
54 		setFogEnable(false);
55 		setSpecularEnable(true);
56 		setLocalViewer(false);
57 		setFogColor(0);
58 		setPixelFogMode(FOG_NONE);
59 		setFogStart(0.0f);
60 		setFogEnd(1.0f);
61 		setFogDensity(1.0f);
62 		setRangeFogEnable(false);
63 		setStencilEnable(false);
64 		setStencilFailOperation(OPERATION_KEEP);
65 		setStencilZFailOperation(OPERATION_KEEP);
66 		setStencilPassOperation(OPERATION_KEEP);
67 		setStencilCompare(STENCIL_ALWAYS);
68 		setStencilReference(0);
69 		setStencilMask(0xFFFFFFFF);
70 		setStencilWriteMask(0xFFFFFFFF);
71 		setVertexFogMode(FOG_NONE);
72 		setClipFlags(0);
73 		setPointSize(1.0f);
74 		setPointSizeMin(0.125f);
75         setPointSizeMax(8192.0f);
76 		setColorWriteMask(0, 0x0000000F);
77 		setBlendOperation(BLENDOP_ADD);
78 		scissorEnable = false;
79 		setSlopeDepthBias(0.0f);
80 		setTwoSidedStencil(false);
81 		setStencilFailOperationCCW(OPERATION_KEEP);
82 		setStencilZFailOperationCCW(OPERATION_KEEP);
83 		setStencilPassOperationCCW(OPERATION_KEEP);
84 		setStencilCompareCCW(STENCIL_ALWAYS);
85 		setColorWriteMask(1, 0x0000000F);
86 		setColorWriteMask(2, 0x0000000F);
87 		setColorWriteMask(3, 0x0000000F);
88 		setBlendConstant(0xFFFFFFFF);
89 		setWriteSRGB(false);
90 		setDepthBias(0.0f);
91 		setSeparateAlphaBlendEnable(false);
92 		setSourceBlendFactorAlpha(BLEND_ONE);
93 		setDestBlendFactorAlpha(BLEND_ZERO);
94 		setBlendOperationAlpha(BLENDOP_ADD);
95 		setPointSpriteEnable(true);
96 
97 		for(int i = 0; i < 16; i++)
98 		{
99 			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
100 			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
101 			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
102 			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);
103 			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);
104 			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);
105 			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);
106 		}
107 
108 		for(int i = 0; i < 4; i++)
109 		{
110 			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
111 			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
112 			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
113 			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);
114 			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);
115 			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);
116 			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);
117 		}
118 
119 		for(int i = 0; i < 6; i++)
120 		{
121 			float plane[4] = {0, 0, 0, 0};
122 
123 			setClipPlane(i, plane);
124 		}
125 	}
126 
~Device()127 	Device::~Device()
128 	{
129 		if(renderTarget)
130 		{
131 			renderTarget->release();
132 			renderTarget = nullptr;
133 		}
134 
135 		if(depthBuffer)
136 		{
137 			depthBuffer->release();
138 			depthBuffer = nullptr;
139 		}
140 
141 		if(stencilBuffer)
142 		{
143 			stencilBuffer->release();
144 			stencilBuffer = nullptr;
145 		}
146 
147 		delete context;
148 	}
149 
150 	// This object has to be mem aligned
operator new(size_t size)151 	void* Device::operator new(size_t size)
152 	{
153 		ASSERT(size == sizeof(Device)); // This operator can't be called from a derived class
154 		return sw::allocate(sizeof(Device), 16);
155 	}
156 
operator delete(void * mem)157 	void Device::operator delete(void * mem)
158 	{
159 		sw::deallocate(mem);
160 	}
161 
clearColor(float red,float green,float blue,float alpha,unsigned int rgbaMask)162 	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
163 	{
164 		if(!renderTarget || !rgbaMask)
165 		{
166 			return;
167 		}
168 
169 		float rgba[4];
170 		rgba[0] = red;
171 		rgba[1] = green;
172 		rgba[2] = blue;
173 		rgba[3] = alpha;
174 
175 		sw::Rect clearRect = renderTarget->getRect();
176 
177 		if(scissorEnable)
178 		{
179 			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
180 		}
181 
182 		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);
183 	}
184 
clearDepth(float z)185 	void Device::clearDepth(float z)
186 	{
187 		if(!depthBuffer)
188 		{
189 			return;
190 		}
191 
192 		z = clamp01(z);
193 		sw::Rect clearRect = depthBuffer->getRect();
194 
195 		if(scissorEnable)
196 		{
197 			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
198 		}
199 
200 		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
201 	}
202 
clearStencil(unsigned int stencil,unsigned int mask)203 	void Device::clearStencil(unsigned int stencil, unsigned int mask)
204 	{
205 		if(!stencilBuffer)
206 		{
207 			return;
208 		}
209 
210 		sw::Rect clearRect = stencilBuffer->getRect();
211 
212 		if(scissorEnable)
213 		{
214 			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
215 		}
216 
217 		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
218 	}
219 
drawIndexedPrimitive(sw::DrawType type,unsigned int indexOffset,unsigned int primitiveCount)220 	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)
221 	{
222 		if(!bindResources() || !primitiveCount)
223 		{
224 			return;
225 		}
226 
227 		draw(type, indexOffset, primitiveCount);
228 	}
229 
drawPrimitive(sw::DrawType type,unsigned int primitiveCount)230 	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)
231 	{
232 		if(!bindResources() || !primitiveCount)
233 		{
234 			return;
235 		}
236 
237 		setIndexBuffer(nullptr);
238 
239 		draw(type, 0, primitiveCount);
240 	}
241 
setScissorEnable(bool enable)242 	void Device::setScissorEnable(bool enable)
243 	{
244 		scissorEnable = enable;
245 	}
246 
setRenderTarget(int index,egl::Image * renderTarget)247 	void Device::setRenderTarget(int index, egl::Image *renderTarget)
248 	{
249 		if(renderTarget)
250 		{
251 			renderTarget->addRef();
252 		}
253 
254 		if(this->renderTarget)
255 		{
256 			this->renderTarget->release();
257 		}
258 
259 		this->renderTarget = renderTarget;
260 
261 		Renderer::setRenderTarget(index, renderTarget);
262 	}
263 
setDepthBuffer(egl::Image * depthBuffer)264 	void Device::setDepthBuffer(egl::Image *depthBuffer)
265 	{
266 		if(this->depthBuffer == depthBuffer)
267 		{
268 			return;
269 		}
270 
271 		if(depthBuffer)
272 		{
273 			depthBuffer->addRef();
274 		}
275 
276 		if(this->depthBuffer)
277 		{
278 			this->depthBuffer->release();
279 		}
280 
281 		this->depthBuffer = depthBuffer;
282 
283 		Renderer::setDepthBuffer(depthBuffer);
284 	}
285 
setStencilBuffer(egl::Image * stencilBuffer)286 	void Device::setStencilBuffer(egl::Image *stencilBuffer)
287 	{
288 		if(this->stencilBuffer == stencilBuffer)
289 		{
290 			return;
291 		}
292 
293 		if(stencilBuffer)
294 		{
295 			stencilBuffer->addRef();
296 		}
297 
298 		if(this->stencilBuffer)
299 		{
300 			this->stencilBuffer->release();
301 		}
302 
303 		this->stencilBuffer = stencilBuffer;
304 
305 		Renderer::setStencilBuffer(stencilBuffer);
306 	}
307 
setScissorRect(const sw::Rect & rect)308 	void Device::setScissorRect(const sw::Rect &rect)
309 	{
310 		scissorRect = rect;
311 	}
312 
setViewport(const Viewport & viewport)313 	void Device::setViewport(const Viewport &viewport)
314 	{
315 		this->viewport = viewport;
316 	}
317 
stretchRect(sw::Surface * source,const sw::SliceRect * sourceRect,sw::Surface * dest,const sw::SliceRect * destRect,bool filter)318 	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)
319 	{
320 		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))
321 		{
322 			ERR("Invalid parameters");
323 			return false;
324 		}
325 
326 		int sWidth = source->getWidth();
327 		int sHeight = source->getHeight();
328 		int dWidth = dest->getWidth();
329 		int dHeight = dest->getHeight();
330 
331 		SliceRect sRect;
332 		SliceRect dRect;
333 
334 		if(sourceRect)
335 		{
336 			sRect = *sourceRect;
337 		}
338 		else
339 		{
340 			sRect.y0 = 0;
341 			sRect.x0 = 0;
342 			sRect.y1 = sHeight;
343 			sRect.x1 = sWidth;
344 		}
345 
346 		if(destRect)
347 		{
348 			dRect = *destRect;
349 		}
350 		else
351 		{
352 			dRect.y0 = 0;
353 			dRect.x0 = 0;
354 			dRect.y1 = dHeight;
355 			dRect.x1 = dWidth;
356 		}
357 
358 		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
359 		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
360 		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat());
361 		bool alpha0xFF = false;
362 
363 		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
364 		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
365 		{
366 			equalFormats = true;
367 			alpha0xFF = true;
368 		}
369 
370 		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
371 		{
372 			if(source->hasDepth())
373 			{
374 				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);
375 				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);
376 
377 				unsigned int width = source->getWidth();
378 				unsigned int height = source->getHeight();
379 				unsigned int pitch = source->getInternalPitchB();
380 
381 				for(unsigned int y = 0; y < height; y++)
382 				{
383 					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
384 
385 					sourceBuffer += pitch;
386 					destBuffer += pitch;
387 				}
388 
389 				source->unlockInternal();
390 				dest->unlockInternal();
391 			}
392 
393 			if(source->hasStencil())
394 			{
395 				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, 0, 0, PUBLIC);
396 				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, 0, 0, PUBLIC);
397 
398 				unsigned int width = source->getWidth();
399 				unsigned int height = source->getHeight();
400 				unsigned int pitch = source->getStencilPitchB();
401 
402 				for(unsigned int y = 0; y < height; y++)
403 				{
404 					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
405 
406 					sourceBuffer += pitch;
407 					destBuffer += pitch;
408 				}
409 
410 				source->unlockStencil();
411 				dest->unlockStencil();
412 			}
413 		}
414 		else if(!scaling && equalFormats)
415 		{
416 			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);
417 			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);
418 			unsigned int sourcePitch = source->getInternalPitchB();
419 			unsigned int destPitch = dest->getInternalPitchB();
420 
421 			unsigned int width = dRect.x1 - dRect.x0;
422 			unsigned int height = dRect.y1 - dRect.y0;
423 			unsigned int bytes = width * egl::Image::bytes(source->getInternalFormat());
424 
425 			for(unsigned int y = 0; y < height; y++)
426 			{
427 				memcpy(destBytes, sourceBytes, bytes);
428 
429 				if(alpha0xFF)
430 				{
431 					for(unsigned int x = 0; x < width; x++)
432 					{
433 						destBytes[4 * x + 3] = 0xFF;
434 					}
435 				}
436 
437 				sourceBytes += sourcePitch;
438 				destBytes += destPitch;
439 			}
440 
441 			source->unlockInternal();
442 			dest->unlockInternal();
443 		}
444 		else
445 		{
446 			sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
447 			blit(source, sRectF, dest, dRect, scaling && filter);
448 		}
449 
450 		return true;
451 	}
452 
bindResources()453 	bool Device::bindResources()
454 	{
455 		if(!bindViewport())
456 		{
457 			return false;   // Zero-area target region
458 		}
459 
460 		return true;
461 	}
462 
bindViewport()463 	bool Device::bindViewport()
464 	{
465 		if(viewport.width <= 0 || viewport.height <= 0)
466 		{
467 			return false;
468 		}
469 
470 		if(scissorEnable)
471 		{
472 			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)
473 			{
474 				return false;
475 			}
476 
477 			sw::Rect scissor;
478 			scissor.x0 = scissorRect.x0;
479 			scissor.x1 = scissorRect.x1;
480 			scissor.y0 = scissorRect.y0;
481 			scissor.y1 = scissorRect.y1;
482 
483 			setScissor(scissor);
484 		}
485 		else
486 		{
487 			sw::Rect scissor;
488 			scissor.x0 = viewport.x0;
489 			scissor.x1 = viewport.x0 + viewport.width;
490 			scissor.y0 = viewport.y0;
491 			scissor.y1 = viewport.y0 + viewport.height;
492 
493 			if(renderTarget)
494 			{
495 				scissor.x0 = max(scissor.x0, 0);
496 				scissor.x1 = min(scissor.x1, renderTarget->getWidth());
497 				scissor.y0 = max(scissor.y0, 0);
498 				scissor.y1 = min(scissor.y1, renderTarget->getHeight());
499 			}
500 
501 			if(depthBuffer)
502 			{
503 				scissor.x0 = max(scissor.x0, 0);
504 				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());
505 				scissor.y0 = max(scissor.y0, 0);
506 				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());
507 			}
508 
509 			if(stencilBuffer)
510 			{
511 				scissor.x0 = max(scissor.x0, 0);
512 				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());
513 				scissor.y0 = max(scissor.y0, 0);
514 				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());
515 			}
516 
517 			setScissor(scissor);
518 		}
519 
520 		sw::Viewport view;
521 		view.x0 = (float)viewport.x0;
522 		view.y0 = (float)viewport.y0;
523 		view.width = (float)viewport.width;
524 		view.height = (float)viewport.height;
525 		view.minZ = viewport.minZ;
526 		view.maxZ = viewport.maxZ;
527 
528 		Renderer::setViewport(view);
529 
530 		return true;
531 	}
532 
validRectangle(const sw::Rect * rect,sw::Surface * surface)533 	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)
534 	{
535 		if(!rect)
536 		{
537 			return true;
538 		}
539 
540 		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
541 		{
542 			return false;
543 		}
544 
545 		if(rect->x0 < 0 || rect->y0 < 0)
546 		{
547 			return false;
548 		}
549 
550 		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
551 		{
552 			return false;
553 		}
554 
555 		return true;
556 	}
557 
finish()558 	void Device::finish()
559 	{
560 		synchronize();
561 	}
562 }
563