10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 20bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// 30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// you may not use this file except in compliance with the License. 50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// You may obtain a copy of the License at 60bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// 70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 80bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// 90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Unless required by applicable law or agreed to in writing, software 100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// See the License for the specific language governing permissions and 130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// limitations under the License. 140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Device.hpp" 160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "common/Image.hpp" 180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Texture.h" 190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Renderer/Renderer.hpp" 210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Renderer/Clipper.hpp" 220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Shader/PixelShader.hpp" 230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Shader/VertexShader.hpp" 240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Main/Config.hpp" 250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Main/FrameBuffer.hpp" 260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Common/Math.hpp" 270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Common/Configurator.hpp" 2881519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu#include "Common/Memory.hpp" 290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Common/Timer.hpp" 300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "../common/debug.h" 310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensnamespace es1 330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens using namespace sw; 350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context) 370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget = nullptr; 390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthBuffer = nullptr; 400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens stencilBuffer = nullptr; 410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthBufferEnable(true); 430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFillMode(FILL_SOLID); 440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setShadingMode(SHADING_GOURAUD); 450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthWriteEnable(true); 460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaTestEnable(false); 470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSourceBlendFactor(BLEND_ONE); 480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDestBlendFactor(BLEND_ZERO); 490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setCullMode(CULL_COUNTERCLOCKWISE); 500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthCompare(DEPTH_LESSEQUAL); 510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaReference(0.0f); 520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaCompare(ALPHA_ALWAYS); 530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaBlendEnable(false); 540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogEnable(false); 550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSpecularEnable(true); 560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setLocalViewer(false); 570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogColor(0); 580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPixelFogMode(FOG_NONE); 590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogStart(0.0f); 600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogEnd(1.0f); 610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogDensity(1.0f); 620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setRangeFogEnable(false); 630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilEnable(false); 640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilFailOperation(OPERATION_KEEP); 650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilZFailOperation(OPERATION_KEEP); 660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilPassOperation(OPERATION_KEEP); 670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilCompare(STENCIL_ALWAYS); 680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilReference(0); 690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilMask(0xFFFFFFFF); 700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilWriteMask(0xFFFFFFFF); 710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setVertexFogMode(FOG_NONE); 720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setClipFlags(0); 730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSize(1.0f); 740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSizeMin(0.125f); 750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSizeMax(8192.0f); 760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(0, 0x0000000F); 770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBlendOperation(BLENDOP_ADD); 780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissorEnable = false; 790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSlopeDepthBias(0.0f); 800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setTwoSidedStencil(false); 810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilFailOperationCCW(OPERATION_KEEP); 820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilZFailOperationCCW(OPERATION_KEEP); 830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilPassOperationCCW(OPERATION_KEEP); 840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilCompareCCW(STENCIL_ALWAYS); 850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(1, 0x0000000F); 860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(2, 0x0000000F); 870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(3, 0x0000000F); 880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBlendConstant(0xFFFFFFFF); 890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setWriteSRGB(false); 900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthBias(0.0f); 910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSeparateAlphaBlendEnable(false); 920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSourceBlendFactorAlpha(BLEND_ONE); 930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDestBlendFactorAlpha(BLEND_ZERO); 940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBlendOperationAlpha(BLENDOP_ADD); 950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSpriteEnable(true); 960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < 16; i++) 980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP); 1000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP); 1010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP); 1020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000); 1030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT); 1040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE); 1050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f); 1060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < 4; i++) 1090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP); 1110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP); 1120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP); 1130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000); 1140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT); 1150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE); 1160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f); 1170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < 6; i++) 1200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens float plane[4] = {0, 0, 0, 0}; 1220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setClipPlane(i, plane); 1240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Device::~Device() 1280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(renderTarget) 1300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget->release(); 1320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget = nullptr; 1330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthBuffer) 1360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthBuffer->release(); 1380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthBuffer = nullptr; 1390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(stencilBuffer) 1420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens stencilBuffer->release(); 1440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens stencilBuffer = nullptr; 1450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens delete context; 1480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 15081519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu // This object has to be mem aligned 151b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens void* Device::operator new(size_t size) 152b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens { 153b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens ASSERT(size == sizeof(Device)); // This operator can't be called from a derived class 154b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens return sw::allocate(sizeof(Device), 16); 155b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens } 156b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens 157b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens void Device::operator delete(void * mem) 158b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens { 159b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens sw::deallocate(mem); 16081519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu } 16181519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu 1620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) 1630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!renderTarget || !rgbaMask) 1650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 1670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens float rgba[4]; 1700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[0] = red; 1710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[1] = green; 1720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[2] = blue; 1730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[3] = alpha; 1740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 175426cb5e11112c9a9c3a7f145474a29e5e81463caNicolas Capens sw::Rect clearRect = renderTarget->getRect(); 1760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 1780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 1800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask); 1830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::clearDepth(float z) 1860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!depthBuffer) 1880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 1900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens z = clamp01(z); 193426cb5e11112c9a9c3a7f145474a29e5e81463caNicolas Capens sw::Rect clearRect = depthBuffer->getRect(); 1940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 1960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 1980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 2010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::clearStencil(unsigned int stencil, unsigned int mask) 2040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!stencilBuffer) 2060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 210426cb5e11112c9a9c3a7f145474a29e5e81463caNicolas Capens sw::Rect clearRect = stencilBuffer->getRect(); 2110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 2130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 2150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 2180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount) 2210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!bindResources() || !primitiveCount) 2230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens draw(type, indexOffset, primitiveCount); 2280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount) 2310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!bindResources() || !primitiveCount) 2330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setIndexBuffer(nullptr); 2380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens draw(type, 0, primitiveCount); 2400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setScissorEnable(bool enable) 2430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissorEnable = enable; 2450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setRenderTarget(int index, egl::Image *renderTarget) 2480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(renderTarget) 2500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget->addRef(); 2520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->renderTarget) 2550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->renderTarget->release(); 2570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->renderTarget = renderTarget; 2600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setRenderTarget(index, renderTarget); 2620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setDepthBuffer(egl::Image *depthBuffer) 2650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->depthBuffer == depthBuffer) 2670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthBuffer) 2720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthBuffer->addRef(); 2740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->depthBuffer) 2770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->depthBuffer->release(); 2790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->depthBuffer = depthBuffer; 2820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setDepthBuffer(depthBuffer); 2840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setStencilBuffer(egl::Image *stencilBuffer) 2870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->stencilBuffer == stencilBuffer) 2890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(stencilBuffer) 2940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens stencilBuffer->addRef(); 2960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->stencilBuffer) 2990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->stencilBuffer->release(); 3010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->stencilBuffer = stencilBuffer; 3040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setStencilBuffer(stencilBuffer); 3060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setScissorRect(const sw::Rect &rect) 3090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissorRect = rect; 3110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setViewport(const Viewport &viewport) 3140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->viewport = viewport; 3160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter) 3190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest)) 3210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Invalid parameters"); 3230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 3240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int sWidth = source->getWidth(); 3270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int sHeight = source->getHeight(); 3280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int dWidth = dest->getWidth(); 3290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int dHeight = dest->getHeight(); 3300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens SliceRect sRect; 3320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens SliceRect dRect; 3330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(sourceRect) 3350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect = *sourceRect; 3370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 3390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.y0 = 0; 3410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.x0 = 0; 3420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.y1 = sHeight; 3430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.x1 = sWidth; 3440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(destRect) 3470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect = *destRect; 3490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 3510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.y0 = 0; 3530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.x0 = 0; 3540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.y1 = dHeight; 3550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.x1 = dWidth; 3560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0); 3590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool equalFormats = source->getInternalFormat() == dest->getInternalFormat(); 3600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat()); 3610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool alpha0xFF = false; 3620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) || 3640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8)) 3650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens equalFormats = true; 3670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens alpha0xFF = true; 3680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthStencil) // Copy entirely, internally // FIXME: Check 3710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(source->hasDepth()) 3730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC); 3750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC); 3760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int width = source->getWidth(); 3780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int height = source->getHeight(); 3790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int pitch = source->getInternalPitchB(); 3800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int y = 0; y < height; y++) 3820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 3840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sourceBuffer += pitch; 3860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBuffer += pitch; 3870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens source->unlockInternal(); 3900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dest->unlockInternal(); 3910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(source->hasStencil()) 3940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 395a52dfbdae4b91f970793a0e3b1df6f210e3e1312Alexis Hetu sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, 0, 0, PUBLIC); 396a52dfbdae4b91f970793a0e3b1df6f210e3e1312Alexis Hetu sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, 0, 0, PUBLIC); 3970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int width = source->getWidth(); 3990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int height = source->getHeight(); 4000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int pitch = source->getStencilPitchB(); 4010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int y = 0; y < height; y++) 4030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 4050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sourceBuffer += pitch; 4070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBuffer += pitch; 4080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens source->unlockStencil(); 4110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dest->unlockStencil(); 4120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else if(!scaling && equalFormats) 4150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC); 4170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC); 4180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int sourcePitch = source->getInternalPitchB(); 4190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int destPitch = dest->getInternalPitchB(); 4200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int width = dRect.x1 - dRect.x0; 4220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int height = dRect.y1 - dRect.y0; 4230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int bytes = width * egl::Image::bytes(source->getInternalFormat()); 4240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int y = 0; y < height; y++) 4260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(destBytes, sourceBytes, bytes); 4280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(alpha0xFF) 4300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int x = 0; x < width; x++) 4320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBytes[4 * x + 3] = 0xFF; 4340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sourceBytes += sourcePitch; 4380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBytes += destPitch; 4390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens source->unlockInternal(); 4420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dest->unlockInternal(); 4430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 4450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 44610c74a62ed7bcde6e4f48445bd43e2f8707c30d6Alexis Hetu sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice); 44710c74a62ed7bcde6e4f48445bd43e2f8707c30d6Alexis Hetu blit(source, sRectF, dest, dRect, scaling && filter); 4480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 4510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::bindResources() 4540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!bindViewport()) 4560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; // Zero-area target region 4580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 4610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::bindViewport() 4640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(viewport.width <= 0 || viewport.height <= 0) 4660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 4680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 4710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1) 4730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 4750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Rect scissor; 4780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = scissorRect.x0; 4790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = scissorRect.x1; 4800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = scissorRect.y0; 4810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = scissorRect.y1; 4820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setScissor(scissor); 4840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 4860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Rect scissor; 4880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = viewport.x0; 4890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = viewport.x0 + viewport.width; 4900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = viewport.y0; 4910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = viewport.y0 + viewport.height; 4920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(renderTarget) 4940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = max(scissor.x0, 0); 4960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = min(scissor.x1, renderTarget->getWidth()); 4970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = max(scissor.y0, 0); 4980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = min(scissor.y1, renderTarget->getHeight()); 4990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthBuffer) 5020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = max(scissor.x0, 0); 5040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = min(scissor.x1, depthBuffer->getWidth()); 5050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = max(scissor.y0, 0); 5060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = min(scissor.y1, depthBuffer->getHeight()); 5070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(stencilBuffer) 5100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = max(scissor.x0, 0); 5120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = min(scissor.x1, stencilBuffer->getWidth()); 5130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = max(scissor.y0, 0); 5140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = min(scissor.y1, stencilBuffer->getHeight()); 5150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setScissor(scissor); 5180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Viewport view; 5210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.x0 = (float)viewport.x0; 5220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.y0 = (float)viewport.y0; 5230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.width = (float)viewport.width; 5240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.height = (float)viewport.height; 5250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.minZ = viewport.minZ; 5260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.maxZ = viewport.maxZ; 5270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setViewport(view); 5290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 5310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface) 5340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!rect) 5360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 5380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0) 5410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 5430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(rect->x0 < 0 || rect->y0 < 0) 5460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 5480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight()) 5510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 5530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 5560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::finish() 5590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens synchronize(); 5610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 563