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 "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/Timer.hpp" 29 #include "../common/debug.h" 30 31 namespace gl 32 { 33 using namespace sw; 34 Device(Context * context)35 Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context) 36 { 37 depthStencil = 0; 38 renderTarget = 0; 39 40 setDepthBufferEnable(true); 41 setFillMode(FILL_SOLID); 42 setShadingMode(SHADING_GOURAUD); 43 setDepthWriteEnable(true); 44 setAlphaTestEnable(false); 45 setSourceBlendFactor(BLEND_ONE); 46 setDestBlendFactor(BLEND_ZERO); 47 setCullMode(CULL_COUNTERCLOCKWISE); 48 setDepthCompare(DEPTH_LESSEQUAL); 49 setAlphaReference(0.0f); 50 setAlphaCompare(ALPHA_ALWAYS); 51 setAlphaBlendEnable(false); 52 setFogEnable(false); 53 setSpecularEnable(false); 54 setFogColor(0); 55 setPixelFogMode(FOG_NONE); 56 setFogStart(0.0f); 57 setFogEnd(1.0f); 58 setFogDensity(1.0f); 59 setRangeFogEnable(false); 60 setStencilEnable(false); 61 setStencilFailOperation(OPERATION_KEEP); 62 setStencilZFailOperation(OPERATION_KEEP); 63 setStencilPassOperation(OPERATION_KEEP); 64 setStencilCompare(STENCIL_ALWAYS); 65 setStencilReference(0); 66 setStencilMask(0xFFFFFFFF); 67 setStencilWriteMask(0xFFFFFFFF); 68 setVertexFogMode(FOG_NONE); 69 setClipFlags(0); 70 setPointSize(1.0f); 71 setPointSizeMin(0.125f); 72 setPointSizeMax(8192.0f); 73 setColorWriteMask(0, 0x0000000F); 74 setBlendOperation(BLENDOP_ADD); 75 scissorEnable = false; 76 setSlopeDepthBias(0.0f); 77 setTwoSidedStencil(false); 78 setStencilFailOperationCCW(OPERATION_KEEP); 79 setStencilZFailOperationCCW(OPERATION_KEEP); 80 setStencilPassOperationCCW(OPERATION_KEEP); 81 setStencilCompareCCW(STENCIL_ALWAYS); 82 setColorWriteMask(1, 0x0000000F); 83 setColorWriteMask(2, 0x0000000F); 84 setColorWriteMask(3, 0x0000000F); 85 setBlendConstant(0xFFFFFFFF); 86 setWriteSRGB(false); 87 setDepthBias(0.0f); 88 setSeparateAlphaBlendEnable(false); 89 setSourceBlendFactorAlpha(BLEND_ONE); 90 setDestBlendFactorAlpha(BLEND_ZERO); 91 setBlendOperationAlpha(BLENDOP_ADD); 92 setPointSpriteEnable(true); 93 setColorLogicOpEnabled(false); 94 setLogicalOperation(LOGICALOP_COPY); 95 96 for(int i = 0; i < 16; i++) 97 { 98 setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP); 99 setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP); 100 setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP); 101 setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000); 102 setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT); 103 setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE); 104 setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f); 105 } 106 107 for(int i = 0; i < 4; i++) 108 { 109 setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP); 110 setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP); 111 setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP); 112 setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000); 113 setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT); 114 setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE); 115 setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f); 116 } 117 118 for(int i = 0; i < 6; i++) 119 { 120 float plane[4] = {0, 0, 0, 0}; 121 122 setClipPlane(i, plane); 123 } 124 125 pixelShader = 0; 126 vertexShader = 0; 127 128 pixelShaderDirty = true; 129 pixelShaderConstantsFDirty = 0; 130 vertexShaderDirty = true; 131 vertexShaderConstantsFDirty = 0; 132 133 for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++) 134 { 135 float zero[4] = {0, 0, 0, 0}; 136 137 setPixelShaderConstantF(i, zero, 1); 138 } 139 140 for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++) 141 { 142 float zero[4] = {0, 0, 0, 0}; 143 144 setVertexShaderConstantF(i, zero, 1); 145 } 146 147 setLightingEnable(false); 148 149 setGlobalAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f)); 150 setMaterialAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f)); 151 setMaterialDiffuse(sw::Color<float>(0.8f, 0.8f, 0.8f, 1.0f)); 152 setMaterialSpecular(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f)); 153 setMaterialEmission(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f)); 154 155 for(int i = 0; i < 8; i++) 156 { 157 setLightEnable(i, false); 158 setLightAttenuation(i, 1.0f, 0.0f, 0.0f); 159 } 160 161 setDiffuseMaterialSource(sw::MATERIAL_COLOR1); 162 setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 163 setAmbientMaterialSource(sw::MATERIAL_COLOR1); 164 setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 165 } 166 ~Device()167 Device::~Device() 168 { 169 if(depthStencil) 170 { 171 depthStencil->release(); 172 depthStencil = 0; 173 } 174 175 if(renderTarget) 176 { 177 renderTarget->release(); 178 renderTarget = 0; 179 } 180 181 delete context; 182 } 183 clearColor(float red,float green,float blue,float alpha,unsigned int rgbaMask)184 void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) 185 { 186 if(!renderTarget || !rgbaMask) 187 { 188 return; 189 } 190 191 sw::SliceRect clearRect = renderTarget->getRect(); 192 193 if(scissorEnable) 194 { 195 clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 196 } 197 198 float rgba[4]; 199 rgba[0] = red; 200 rgba[1] = green; 201 rgba[2] = blue; 202 rgba[3] = alpha; 203 204 clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask); 205 } 206 clearDepth(float z)207 void Device::clearDepth(float z) 208 { 209 if(!depthStencil) 210 { 211 return; 212 } 213 214 z = clamp01(z); 215 sw::SliceRect clearRect = depthStencil->getRect(); 216 217 if(scissorEnable) 218 { 219 clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 220 } 221 222 depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 223 } 224 clearStencil(unsigned int stencil,unsigned int mask)225 void Device::clearStencil(unsigned int stencil, unsigned int mask) 226 { 227 if(!depthStencil) 228 { 229 return; 230 } 231 232 sw::SliceRect clearRect = depthStencil->getRect(); 233 234 if(scissorEnable) 235 { 236 clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 237 } 238 239 depthStencil->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 240 } 241 createDepthStencilSurface(unsigned int width,unsigned int height,sw::Format format,int multiSampleDepth,bool discard)242 Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) 243 { 244 if(height > OUTLINE_RESOLUTION) 245 { 246 ERR("Invalid parameters: %dx%d", width, height); 247 return 0; 248 } 249 250 bool lockable = true; 251 252 switch(format) 253 { 254 // case FORMAT_D15S1: 255 case FORMAT_D24S8: 256 case FORMAT_D24X8: 257 // case FORMAT_D24X4S4: 258 case FORMAT_D24FS8: 259 case FORMAT_D32: 260 case FORMAT_D16: 261 lockable = false; 262 break; 263 // case FORMAT_S8_LOCKABLE: 264 // case FORMAT_D16_LOCKABLE: 265 case FORMAT_D32F_LOCKABLE: 266 // case FORMAT_D32_LOCKABLE: 267 case FORMAT_DF24S8: 268 case FORMAT_DF16S8: 269 lockable = true; 270 break; 271 default: 272 UNREACHABLE(format); 273 } 274 275 Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true); 276 277 if(!surface) 278 { 279 ERR("Out of memory"); 280 return 0; 281 } 282 283 return surface; 284 } 285 createRenderTarget(unsigned int width,unsigned int height,sw::Format format,int multiSampleDepth,bool lockable)286 Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable) 287 { 288 if(height > OUTLINE_RESOLUTION) 289 { 290 ERR("Invalid parameters: %dx%d", width, height); 291 return 0; 292 } 293 294 Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true); 295 296 if(!surface) 297 { 298 ERR("Out of memory"); 299 return 0; 300 } 301 302 return surface; 303 } 304 drawIndexedPrimitive(PrimitiveType type,unsigned int indexOffset,unsigned int primitiveCount,int indexSize)305 void Device::drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize) 306 { 307 if(!bindResources() || !primitiveCount) 308 { 309 return; 310 } 311 312 DrawType drawType; 313 314 if(indexSize == 4) 315 { 316 switch(type) 317 { 318 case DRAW_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST32; break; 319 case DRAW_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST32; break; 320 case DRAW_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP32; break; 321 case DRAW_LINELOOP: drawType = sw::DRAW_INDEXEDLINELOOP32; break; 322 case DRAW_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST32; break; 323 case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break; 324 case DRAW_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN32; break; 325 default: UNREACHABLE(type); 326 } 327 } 328 else if(indexSize == 2) 329 { 330 switch(type) 331 { 332 case DRAW_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST16; break; 333 case DRAW_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST16; break; 334 case DRAW_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP16; break; 335 case DRAW_LINELOOP: drawType = sw::DRAW_INDEXEDLINELOOP16; break; 336 case DRAW_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST16; break; 337 case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break; 338 case DRAW_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN16; break; 339 default: UNREACHABLE(type); 340 } 341 } 342 else if(indexSize == 1) 343 { 344 switch(type) 345 { 346 case DRAW_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST8; break; 347 case DRAW_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST8; break; 348 case DRAW_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP8; break; 349 case DRAW_LINELOOP: drawType = sw::DRAW_INDEXEDLINELOOP8; break; 350 case DRAW_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST8; break; 351 case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP8; break; 352 case DRAW_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN8; break; 353 default: UNREACHABLE(type); 354 } 355 } 356 else UNREACHABLE(indexSize); 357 358 draw(drawType, indexOffset, primitiveCount); 359 } 360 drawPrimitive(PrimitiveType primitiveType,unsigned int primitiveCount)361 void Device::drawPrimitive(PrimitiveType primitiveType, unsigned int primitiveCount) 362 { 363 if(!bindResources() || !primitiveCount) 364 { 365 return; 366 } 367 368 setIndexBuffer(0); 369 370 DrawType drawType; 371 372 switch(primitiveType) 373 { 374 case DRAW_POINTLIST: drawType = sw::DRAW_POINTLIST; break; 375 case DRAW_LINELIST: drawType = sw::DRAW_LINELIST; break; 376 case DRAW_LINESTRIP: drawType = sw::DRAW_LINESTRIP; break; 377 case DRAW_LINELOOP: drawType = sw::DRAW_LINELOOP; break; 378 case DRAW_TRIANGLELIST: drawType = sw::DRAW_TRIANGLELIST; break; 379 case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break; 380 case DRAW_TRIANGLEFAN: drawType = sw::DRAW_TRIANGLEFAN; break; 381 case DRAW_QUADLIST: drawType = sw::DRAW_QUADLIST; break; 382 default: UNREACHABLE(primitiveType); 383 } 384 385 draw(drawType, 0, primitiveCount); 386 } 387 setDepthStencilSurface(Image * depthStencil)388 void Device::setDepthStencilSurface(Image *depthStencil) 389 { 390 if(this->depthStencil == depthStencil) 391 { 392 return; 393 } 394 395 if(depthStencil) 396 { 397 depthStencil->addRef(); 398 } 399 400 if(this->depthStencil) 401 { 402 this->depthStencil->release(); 403 } 404 405 this->depthStencil = depthStencil; 406 407 setDepthBuffer(depthStencil); 408 setStencilBuffer(depthStencil); 409 } 410 setPixelShader(PixelShader * pixelShader)411 void Device::setPixelShader(PixelShader *pixelShader) 412 { 413 this->pixelShader = pixelShader; 414 pixelShaderDirty = true; 415 } 416 setPixelShaderConstantF(unsigned int startRegister,const float * constantData,unsigned int count)417 void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count) 418 { 419 for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++) 420 { 421 pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0]; 422 pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1]; 423 pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2]; 424 pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3]; 425 } 426 427 pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty); 428 pixelShaderDirty = true; // Reload DEF constants 429 } 430 setScissorEnable(bool enable)431 void Device::setScissorEnable(bool enable) 432 { 433 scissorEnable = enable; 434 } 435 setRenderTarget(int index,Image * renderTarget)436 void Device::setRenderTarget(int index, Image *renderTarget) 437 { 438 if(renderTarget) 439 { 440 renderTarget->addRef(); 441 } 442 443 if(this->renderTarget) 444 { 445 this->renderTarget->release(); 446 } 447 448 this->renderTarget = renderTarget; 449 450 Renderer::setRenderTarget(index, renderTarget); 451 } 452 setScissorRect(const sw::Rect & rect)453 void Device::setScissorRect(const sw::Rect &rect) 454 { 455 scissorRect = rect; 456 } 457 setVertexShader(VertexShader * vertexShader)458 void Device::setVertexShader(VertexShader *vertexShader) 459 { 460 this->vertexShader = vertexShader; 461 vertexShaderDirty = true; 462 } 463 setVertexShaderConstantF(unsigned int startRegister,const float * constantData,unsigned int count)464 void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count) 465 { 466 for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++) 467 { 468 vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0]; 469 vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1]; 470 vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2]; 471 vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3]; 472 } 473 474 vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty); 475 vertexShaderDirty = true; // Reload DEF constants 476 } 477 setViewport(const Viewport & viewport)478 void Device::setViewport(const Viewport &viewport) 479 { 480 this->viewport = viewport; 481 } 482 stretchRect(Image * source,const sw::SliceRect * sourceRect,Image * dest,const sw::SliceRect * destRect,bool filter)483 bool Device::stretchRect(Image *source, const sw::SliceRect *sourceRect, Image *dest, const sw::SliceRect *destRect, bool filter) 484 { 485 if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest)) 486 { 487 ERR("Invalid parameters"); 488 return false; 489 } 490 491 int sWidth = source->getWidth(); 492 int sHeight = source->getHeight(); 493 int dWidth = dest->getWidth(); 494 int dHeight = dest->getHeight(); 495 496 SliceRect sRect; 497 SliceRect dRect; 498 499 if(sourceRect) 500 { 501 sRect = *sourceRect; 502 } 503 else 504 { 505 sRect.y0 = 0; 506 sRect.x0 = 0; 507 sRect.y1 = sHeight; 508 sRect.x1 = sWidth; 509 } 510 511 if(destRect) 512 { 513 dRect = *destRect; 514 } 515 else 516 { 517 dRect.y0 = 0; 518 dRect.x0 = 0; 519 dRect.y1 = dHeight; 520 dRect.x1 = dWidth; 521 } 522 523 bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0); 524 bool equalFormats = source->getInternalFormat() == dest->getInternalFormat(); 525 bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat()); 526 bool alpha0xFF = false; 527 528 if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) || 529 (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8)) 530 { 531 equalFormats = true; 532 alpha0xFF = true; 533 } 534 535 if(depthStencil) // Copy entirely, internally // FIXME: Check 536 { 537 if(source->hasDepth()) 538 { 539 sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC); 540 sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC); 541 542 unsigned int width = source->getWidth(); 543 unsigned int height = source->getHeight(); 544 unsigned int pitch = source->getInternalPitchB(); 545 546 for(unsigned int y = 0; y < height; y++) 547 { 548 memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 549 550 sourceBuffer += pitch; 551 destBuffer += pitch; 552 } 553 554 source->unlockInternal(); 555 dest->unlockInternal(); 556 } 557 558 if(source->hasStencil()) 559 { 560 sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC); 561 sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC); 562 563 unsigned int width = source->getWidth(); 564 unsigned int height = source->getHeight(); 565 unsigned int pitch = source->getStencilPitchB(); 566 567 for(unsigned int y = 0; y < height; y++) 568 { 569 memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 570 571 sourceBuffer += pitch; 572 destBuffer += pitch; 573 } 574 575 source->unlockStencil(); 576 dest->unlockStencil(); 577 } 578 } 579 else if(!scaling && equalFormats) 580 { 581 unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC); 582 unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC); 583 unsigned int sourcePitch = source->getInternalPitchB(); 584 unsigned int destPitch = dest->getInternalPitchB(); 585 586 unsigned int width = dRect.x1 - dRect.x0; 587 unsigned int height = dRect.y1 - dRect.y0; 588 unsigned int bytes = width * Image::bytes(source->getInternalFormat()); 589 590 for(unsigned int y = 0; y < height; y++) 591 { 592 memcpy(destBytes, sourceBytes, bytes); 593 594 if(alpha0xFF) 595 { 596 for(unsigned int x = 0; x < width; x++) 597 { 598 destBytes[4 * x + 3] = 0xFF; 599 } 600 } 601 602 sourceBytes += sourcePitch; 603 destBytes += destPitch; 604 } 605 606 source->unlockInternal(); 607 dest->unlockInternal(); 608 } 609 else 610 { 611 blit(source, sRect, dest, dRect, scaling && filter); 612 } 613 614 return true; 615 } 616 bindResources()617 bool Device::bindResources() 618 { 619 if(!bindViewport()) 620 { 621 return false; // Zero-area target region 622 } 623 624 bindShaderConstants(); 625 626 return true; 627 } 628 bindShaderConstants()629 void Device::bindShaderConstants() 630 { 631 if(pixelShaderDirty) 632 { 633 if(pixelShader) 634 { 635 if(pixelShaderConstantsFDirty) 636 { 637 Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty); 638 } 639 640 Renderer::setPixelShader(pixelShader); // Loads shader constants set with DEF 641 pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF; // Shader DEF'ed constants are dirty 642 } 643 else 644 { 645 setPixelShader(0); 646 } 647 648 pixelShaderDirty = false; 649 } 650 651 if(vertexShaderDirty) 652 { 653 if(vertexShader) 654 { 655 if(vertexShaderConstantsFDirty) 656 { 657 Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty); 658 } 659 660 Renderer::setVertexShader(vertexShader); // Loads shader constants set with DEF 661 vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF; // Shader DEF'ed constants are dirty 662 } 663 else 664 { 665 setVertexShader(0); 666 } 667 668 vertexShaderDirty = false; 669 } 670 } 671 bindViewport()672 bool Device::bindViewport() 673 { 674 if(viewport.width <= 0 || viewport.height <= 0) 675 { 676 return false; 677 } 678 679 if(scissorEnable) 680 { 681 if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1) 682 { 683 return false; 684 } 685 686 sw::Rect scissor; 687 scissor.x0 = scissorRect.x0; 688 scissor.x1 = scissorRect.x1; 689 scissor.y0 = scissorRect.y0; 690 scissor.y1 = scissorRect.y1; 691 692 setScissor(scissor); 693 } 694 else 695 { 696 sw::Rect scissor; 697 scissor.x0 = viewport.x0; 698 scissor.x1 = viewport.x0 + viewport.width; 699 scissor.y0 = viewport.y0; 700 scissor.y1 = viewport.y0 + viewport.height; 701 702 if(renderTarget) 703 { 704 scissor.x0 = max(scissor.x0, 0); 705 scissor.x1 = min(scissor.x1, renderTarget->getWidth()); 706 scissor.y0 = max(scissor.y0, 0); 707 scissor.y1 = min(scissor.y1, renderTarget->getHeight()); 708 } 709 710 if(depthStencil) 711 { 712 scissor.x0 = max(scissor.x0, 0); 713 scissor.x1 = min(scissor.x1, depthStencil->getWidth()); 714 scissor.y0 = max(scissor.y0, 0); 715 scissor.y1 = min(scissor.y1, depthStencil->getHeight()); 716 } 717 718 setScissor(scissor); 719 } 720 721 sw::Viewport view; 722 view.x0 = (float)viewport.x0; 723 view.y0 = (float)viewport.y0; 724 view.width = (float)viewport.width; 725 view.height = (float)viewport.height; 726 view.minZ = viewport.minZ; 727 view.maxZ = viewport.maxZ; 728 729 Renderer::setViewport(view); 730 731 return true; 732 } 733 validRectangle(const sw::Rect * rect,Image * surface)734 bool Device::validRectangle(const sw::Rect *rect, Image *surface) 735 { 736 if(!rect) 737 { 738 return true; 739 } 740 741 if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0) 742 { 743 return false; 744 } 745 746 if(rect->x0 < 0 || rect->y0 < 0) 747 { 748 return false; 749 } 750 751 if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight()) 752 { 753 return false; 754 } 755 756 return true; 757 } 758 finish()759 void Device::finish() 760 { 761 synchronize(); 762 } 763 } 764