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