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