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 height = source->getHeight(); 378 unsigned int pitch = source->getInternalPitchB(); 379 380 for(unsigned int y = 0; y < height; y++) 381 { 382 memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 383 384 sourceBuffer += pitch; 385 destBuffer += pitch; 386 } 387 388 source->unlockInternal(); 389 dest->unlockInternal(); 390 } 391 392 if(source->hasStencil()) 393 { 394 sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, 0, 0, PUBLIC); 395 sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, 0, 0, PUBLIC); 396 397 unsigned int height = source->getHeight(); 398 unsigned int pitch = source->getStencilPitchB(); 399 400 for(unsigned int y = 0; y < height; y++) 401 { 402 memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 403 404 sourceBuffer += pitch; 405 destBuffer += pitch; 406 } 407 408 source->unlockStencil(); 409 dest->unlockStencil(); 410 } 411 } 412 else if(!scaling && equalFormats) 413 { 414 unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC); 415 unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC); 416 unsigned int sourcePitch = source->getInternalPitchB(); 417 unsigned int destPitch = dest->getInternalPitchB(); 418 419 unsigned int width = dRect.x1 - dRect.x0; 420 unsigned int height = dRect.y1 - dRect.y0; 421 unsigned int bytes = width * egl::Image::bytes(source->getInternalFormat()); 422 423 for(unsigned int y = 0; y < height; y++) 424 { 425 memcpy(destBytes, sourceBytes, bytes); 426 427 if(alpha0xFF) 428 { 429 for(unsigned int x = 0; x < width; x++) 430 { 431 destBytes[4 * x + 3] = 0xFF; 432 } 433 } 434 435 sourceBytes += sourcePitch; 436 destBytes += destPitch; 437 } 438 439 source->unlockInternal(); 440 dest->unlockInternal(); 441 } 442 else 443 { 444 sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice); 445 blit(source, sRectF, dest, dRect, scaling && filter); 446 } 447 448 return true; 449 } 450 bindResources()451 bool Device::bindResources() 452 { 453 if(!bindViewport()) 454 { 455 return false; // Zero-area target region 456 } 457 458 return true; 459 } 460 bindViewport()461 bool Device::bindViewport() 462 { 463 if(viewport.width <= 0 || viewport.height <= 0) 464 { 465 return false; 466 } 467 468 if(scissorEnable) 469 { 470 if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1) 471 { 472 return false; 473 } 474 475 sw::Rect scissor; 476 scissor.x0 = scissorRect.x0; 477 scissor.x1 = scissorRect.x1; 478 scissor.y0 = scissorRect.y0; 479 scissor.y1 = scissorRect.y1; 480 481 setScissor(scissor); 482 } 483 else 484 { 485 sw::Rect scissor; 486 scissor.x0 = viewport.x0; 487 scissor.x1 = viewport.x0 + viewport.width; 488 scissor.y0 = viewport.y0; 489 scissor.y1 = viewport.y0 + viewport.height; 490 491 if(renderTarget) 492 { 493 scissor.x0 = max(scissor.x0, 0); 494 scissor.x1 = min(scissor.x1, renderTarget->getWidth()); 495 scissor.y0 = max(scissor.y0, 0); 496 scissor.y1 = min(scissor.y1, renderTarget->getHeight()); 497 } 498 499 if(depthBuffer) 500 { 501 scissor.x0 = max(scissor.x0, 0); 502 scissor.x1 = min(scissor.x1, depthBuffer->getWidth()); 503 scissor.y0 = max(scissor.y0, 0); 504 scissor.y1 = min(scissor.y1, depthBuffer->getHeight()); 505 } 506 507 if(stencilBuffer) 508 { 509 scissor.x0 = max(scissor.x0, 0); 510 scissor.x1 = min(scissor.x1, stencilBuffer->getWidth()); 511 scissor.y0 = max(scissor.y0, 0); 512 scissor.y1 = min(scissor.y1, stencilBuffer->getHeight()); 513 } 514 515 setScissor(scissor); 516 } 517 518 sw::Viewport view; 519 view.x0 = (float)viewport.x0; 520 view.y0 = (float)viewport.y0; 521 view.width = (float)viewport.width; 522 view.height = (float)viewport.height; 523 view.minZ = viewport.minZ; 524 view.maxZ = viewport.maxZ; 525 526 Renderer::setViewport(view); 527 528 return true; 529 } 530 validRectangle(const sw::Rect * rect,sw::Surface * surface)531 bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface) 532 { 533 if(!rect) 534 { 535 return true; 536 } 537 538 if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0) 539 { 540 return false; 541 } 542 543 if(rect->x0 < 0 || rect->y0 < 0) 544 { 545 return false; 546 } 547 548 if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight()) 549 { 550 return false; 551 } 552 553 return true; 554 } 555 finish()556 void Device::finish() 557 { 558 synchronize(); 559 } 560 } 561