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 "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 gl 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 depthStencil = 0; 390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget = 0; 400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthBufferEnable(true); 420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFillMode(FILL_SOLID); 430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setShadingMode(SHADING_GOURAUD); 440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthWriteEnable(true); 450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaTestEnable(false); 460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSourceBlendFactor(BLEND_ONE); 470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDestBlendFactor(BLEND_ZERO); 480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setCullMode(CULL_COUNTERCLOCKWISE); 490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthCompare(DEPTH_LESSEQUAL); 500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaReference(0.0f); 510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaCompare(ALPHA_ALWAYS); 520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAlphaBlendEnable(false); 530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogEnable(false); 540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSpecularEnable(false); 550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogColor(0); 560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPixelFogMode(FOG_NONE); 570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogStart(0.0f); 580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogEnd(1.0f); 590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setFogDensity(1.0f); 600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setRangeFogEnable(false); 610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilEnable(false); 620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilFailOperation(OPERATION_KEEP); 630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilZFailOperation(OPERATION_KEEP); 640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilPassOperation(OPERATION_KEEP); 650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilCompare(STENCIL_ALWAYS); 660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilReference(0); 670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilMask(0xFFFFFFFF); 680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilWriteMask(0xFFFFFFFF); 690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setVertexFogMode(FOG_NONE); 700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setClipFlags(0); 710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSize(1.0f); 720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSizeMin(0.125f); 730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSizeMax(8192.0f); 740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(0, 0x0000000F); 750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBlendOperation(BLENDOP_ADD); 760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissorEnable = false; 770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSlopeDepthBias(0.0f); 780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setTwoSidedStencil(false); 790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilFailOperationCCW(OPERATION_KEEP); 800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilZFailOperationCCW(OPERATION_KEEP); 810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilPassOperationCCW(OPERATION_KEEP); 820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilCompareCCW(STENCIL_ALWAYS); 830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(1, 0x0000000F); 840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(2, 0x0000000F); 850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorWriteMask(3, 0x0000000F); 860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBlendConstant(0xFFFFFFFF); 870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setWriteSRGB(false); 880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthBias(0.0f); 890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSeparateAlphaBlendEnable(false); 900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSourceBlendFactorAlpha(BLEND_ONE); 910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDestBlendFactorAlpha(BLEND_ZERO); 920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setBlendOperationAlpha(BLENDOP_ADD); 930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPointSpriteEnable(true); 940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setColorLogicOpEnabled(false); 950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setLogicalOperation(LOGICALOP_COPY); 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 pixelShader = 0; 1270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShader = 0; 1280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderDirty = true; 1300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantsFDirty = 0; 1310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderDirty = true; 1320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantsFDirty = 0; 1330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++) 1350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens float zero[4] = {0, 0, 0, 0}; 1370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPixelShaderConstantF(i, zero, 1); 1390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++) 1420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens float zero[4] = {0, 0, 0, 0}; 1440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setVertexShaderConstantF(i, zero, 1); 1460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setLightingEnable(false); 1490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setGlobalAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f)); 1510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMaterialAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f)); 1520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMaterialDiffuse(sw::Color<float>(0.8f, 0.8f, 0.8f, 1.0f)); 1530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMaterialSpecular(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f)); 1540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setMaterialEmission(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f)); 1550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < 8; i++) 1570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setLightEnable(i, false); 1590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setLightAttenuation(i, 1.0f, 0.0f, 0.0f); 1600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDiffuseMaterialSource(sw::MATERIAL_COLOR1); 1630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 1640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setAmbientMaterialSource(sw::MATERIAL_COLOR1); 1650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 1660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Device::~Device() 1690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthStencil) 1710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthStencil->release(); 1730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthStencil = 0; 1740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(renderTarget) 1770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget->release(); 1790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget = 0; 1800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens delete context; 1830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 18581519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu // This object has to be mem aligned 186b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens void* Device::operator new(size_t size) 187b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens { 188b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens ASSERT(size == sizeof(Device)); // This operator can't be called from a derived class 189b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens return sw::allocate(sizeof(gl::Device), 16); 190b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens } 191b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens 192b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens void Device::operator delete(void * mem) 193b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens { 194b7d5924b1c7641a0e30401b3b799a2355130ea90Nicolas Capens sw::deallocate(mem); 19581519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu } 19681519cfcdbc76c5969cd1d132fd1ca627848013fAlexis Hetu 1970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) 1980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!renderTarget || !rgbaMask) 2000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 204426cb5e11112c9a9c3a7f145474a29e5e81463caNicolas Capens sw::Rect clearRect = renderTarget->getRect(); 2050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 2070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 2090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens float rgba[4]; 2120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[0] = red; 2130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[1] = green; 2140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[2] = blue; 2150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens rgba[3] = alpha; 2160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask); 2180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::clearDepth(float z) 2210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!depthStencil) 2230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens z = clamp01(z); 228426cb5e11112c9a9c3a7f145474a29e5e81463caNicolas Capens sw::Rect clearRect = depthStencil->getRect(); 2290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 2310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 2330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 2360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::clearStencil(unsigned int stencil, unsigned int mask) 2390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!depthStencil) 2410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 2430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 245426cb5e11112c9a9c3a7f145474a29e5e81463caNicolas Capens sw::Rect clearRect = depthStencil->getRect(); 2460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 2480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 2500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthStencil->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 2530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) 2560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(height > OUTLINE_RESOLUTION) 2580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Invalid parameters: %dx%d", width, height); 2600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return 0; 2610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool lockable = true; 2640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens switch(format) 2660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // case FORMAT_D15S1: 2680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_D24S8: 2690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_D24X8: 2700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // case FORMAT_D24X4S4: 2710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_D24FS8: 2720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_D32: 2730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_D16: 2740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens lockable = false; 2750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens break; 2760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // case FORMAT_S8_LOCKABLE: 2770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // case FORMAT_D16_LOCKABLE: 2780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_D32F_LOCKABLE: 2790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // case FORMAT_D32_LOCKABLE: 2800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_DF24S8: 2810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case FORMAT_DF16S8: 2820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens lockable = true; 2830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens break; 2840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens default: 2850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens UNREACHABLE(format); 2860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true); 2890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!surface) 2910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Out of memory"); 2930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return 0; 2940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return surface; 2970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable) 3000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(height > OUTLINE_RESOLUTION) 3020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Invalid parameters: %dx%d", width, height); 3040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return 0; 3050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true); 3080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!surface) 3100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Out of memory"); 3120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return 0; 3130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return surface; 3160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize) 3190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!bindResources() || !primitiveCount) 3210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 3230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens DrawType drawType; 3260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(indexSize == 4) 3280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens switch(type) 3300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST32; break; 3320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST32; break; 3330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP32; break; 3340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELOOP: drawType = sw::DRAW_INDEXEDLINELOOP32; break; 3350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST32; break; 3360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break; 3370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN32; break; 3380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens default: UNREACHABLE(type); 3390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else if(indexSize == 2) 3420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens switch(type) 3440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST16; break; 3460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST16; break; 3470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP16; break; 3480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELOOP: drawType = sw::DRAW_INDEXEDLINELOOP16; break; 3490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST16; break; 3500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break; 3510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN16; break; 3520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens default: UNREACHABLE(type); 3530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else if(indexSize == 1) 3560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens switch(type) 3580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST8; break; 3600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST8; break; 3610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP8; break; 3620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELOOP: drawType = sw::DRAW_INDEXEDLINELOOP8; break; 3630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST8; break; 3640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP8; break; 3650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN8; break; 3660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens default: UNREACHABLE(type); 3670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else UNREACHABLE(indexSize); 3700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens draw(drawType, indexOffset, primitiveCount); 3720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::drawPrimitive(PrimitiveType primitiveType, unsigned int primitiveCount) 3750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!bindResources() || !primitiveCount) 3770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 3790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setIndexBuffer(0); 3820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens DrawType drawType; 3840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens switch(primitiveType) 3860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_POINTLIST: drawType = sw::DRAW_POINTLIST; break; 3880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELIST: drawType = sw::DRAW_LINELIST; break; 3890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINESTRIP: drawType = sw::DRAW_LINESTRIP; break; 3900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_LINELOOP: drawType = sw::DRAW_LINELOOP; break; 3910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLELIST: drawType = sw::DRAW_TRIANGLELIST; break; 3920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break; 3930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_TRIANGLEFAN: drawType = sw::DRAW_TRIANGLEFAN; break; 3940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case DRAW_QUADLIST: drawType = sw::DRAW_QUADLIST; break; 3950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens default: UNREACHABLE(primitiveType); 3960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens draw(drawType, 0, primitiveCount); 3990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setDepthStencilSurface(Image *depthStencil) 4020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->depthStencil == depthStencil) 4040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return; 4060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthStencil) 4090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens depthStencil->addRef(); 4110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->depthStencil) 4140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->depthStencil->release(); 4160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->depthStencil = depthStencil; 4190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setDepthBuffer(depthStencil); 4210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setStencilBuffer(depthStencil); 4220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setPixelShader(PixelShader *pixelShader) 4250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->pixelShader = pixelShader; 4270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderDirty = true; 4280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count) 4310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++) 4330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0]; 4350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1]; 4360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2]; 4370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3]; 4380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty); 4410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderDirty = true; // Reload DEF constants 4420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setScissorEnable(bool enable) 4450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissorEnable = enable; 4470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setRenderTarget(int index, Image *renderTarget) 4500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(renderTarget) 4520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens renderTarget->addRef(); 4540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(this->renderTarget) 4570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->renderTarget->release(); 4590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->renderTarget = renderTarget; 4620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setRenderTarget(index, renderTarget); 4640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setScissorRect(const sw::Rect &rect) 4670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissorRect = rect; 4690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setVertexShader(VertexShader *vertexShader) 4720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->vertexShader = vertexShader; 4740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderDirty = true; 4750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count) 4780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++) 4800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0]; 4820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1]; 4830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2]; 4840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3]; 4850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty); 4880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderDirty = true; // Reload DEF constants 4890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::setViewport(const Viewport &viewport) 4920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens this->viewport = viewport; 4940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 4950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 4960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::stretchRect(Image *source, const sw::SliceRect *sourceRect, Image *dest, const sw::SliceRect *destRect, bool filter) 4970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 4980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest)) 4990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Invalid parameters"); 5010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 5020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int sWidth = source->getWidth(); 5050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int sHeight = source->getHeight(); 5060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int dWidth = dest->getWidth(); 5070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int dHeight = dest->getHeight(); 5080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens SliceRect sRect; 5100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens SliceRect dRect; 5110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(sourceRect) 5130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect = *sourceRect; 5150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 5170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.y0 = 0; 5190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.x0 = 0; 5200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.y1 = sHeight; 5210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sRect.x1 = sWidth; 5220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(destRect) 5250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect = *destRect; 5270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 5290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.y0 = 0; 5310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.x0 = 0; 5320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.y1 = dHeight; 5330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dRect.x1 = dWidth; 5340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0); 5370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool equalFormats = source->getInternalFormat() == dest->getInternalFormat(); 5380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat()); 5390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool alpha0xFF = false; 5400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) || 5420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8)) 5430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens equalFormats = true; 5450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens alpha0xFF = true; 5460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthStencil) // Copy entirely, internally // FIXME: Check 5490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(source->hasDepth()) 5510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC); 5530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC); 5540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int width = source->getWidth(); 5560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int height = source->getHeight(); 5570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int pitch = source->getInternalPitchB(); 5580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int y = 0; y < height; y++) 5600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 5620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sourceBuffer += pitch; 5640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBuffer += pitch; 5650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens source->unlockInternal(); 5680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dest->unlockInternal(); 5690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(source->hasStencil()) 5720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 573a52dfbdae4b91f970793a0e3b1df6f210e3e1312Alexis Hetu sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, 0, 0, PUBLIC); 574a52dfbdae4b91f970793a0e3b1df6f210e3e1312Alexis Hetu sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, 0, 0, PUBLIC); 5750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int width = source->getWidth(); 5770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int height = source->getHeight(); 5780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int pitch = source->getStencilPitchB(); 5790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int y = 0; y < height; y++) 5810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 5830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sourceBuffer += pitch; 5850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBuffer += pitch; 5860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens source->unlockStencil(); 5890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dest->unlockStencil(); 5900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 5920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else if(!scaling && equalFormats) 5930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 5940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC); 5950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC); 5960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int sourcePitch = source->getInternalPitchB(); 5970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int destPitch = dest->getInternalPitchB(); 5980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 5990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int width = dRect.x1 - dRect.x0; 6000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int height = dRect.y1 - dRect.y0; 6010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int bytes = width * Image::bytes(source->getInternalFormat()); 6020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int y = 0; y < height; y++) 6040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(destBytes, sourceBytes, bytes); 6060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(alpha0xFF) 6080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(unsigned int x = 0; x < width; x++) 6100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBytes[4 * x + 3] = 0xFF; 6120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sourceBytes += sourcePitch; 6160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens destBytes += destPitch; 6170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens source->unlockInternal(); 6200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens dest->unlockInternal(); 6210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 6230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 62410c74a62ed7bcde6e4f48445bd43e2f8707c30d6Alexis Hetu sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice); 62510c74a62ed7bcde6e4f48445bd43e2f8707c30d6Alexis Hetu blit(source, sRectF, dest, dRect, scaling && filter); 6260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 6290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::bindResources() 6320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!bindViewport()) 6340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; // Zero-area target region 6360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bindShaderConstants(); 6390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 6410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::bindShaderConstants() 6440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(pixelShaderDirty) 6460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(pixelShader) 6480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(pixelShaderConstantsFDirty) 6500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty); 6520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setPixelShader(pixelShader); // Loads shader constants set with DEF 6550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF; // Shader DEF'ed constants are dirty 6560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 6580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setPixelShader(0); 6600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens pixelShaderDirty = false; 6630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(vertexShaderDirty) 6660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(vertexShader) 6680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(vertexShaderConstantsFDirty) 6700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty); 6720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setVertexShader(vertexShader); // Loads shader constants set with DEF 6750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF; // Shader DEF'ed constants are dirty 6760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 6780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setVertexShader(0); 6800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexShaderDirty = false; 6830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::bindViewport() 6870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(viewport.width <= 0 || viewport.height <= 0) 6890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 6910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 6930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorEnable) 6940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1) 6960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 6970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 6980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 6990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Rect scissor; 7010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = scissorRect.x0; 7020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = scissorRect.x1; 7030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = scissorRect.y0; 7040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = scissorRect.y1; 7050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setScissor(scissor); 7070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 7090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Rect scissor; 7110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = viewport.x0; 7120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = viewport.x0 + viewport.width; 7130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = viewport.y0; 7140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = viewport.y0 + viewport.height; 7150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(renderTarget) 7170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = max(scissor.x0, 0); 7190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = min(scissor.x1, renderTarget->getWidth()); 7200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = max(scissor.y0, 0); 7210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = min(scissor.y1, renderTarget->getHeight()); 7220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(depthStencil) 7250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x0 = max(scissor.x0, 0); 7270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.x1 = min(scissor.x1, depthStencil->getWidth()); 7280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y0 = max(scissor.y0, 0); 7290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens scissor.y1 = min(scissor.y1, depthStencil->getHeight()); 7300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens setScissor(scissor); 7330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Viewport view; 7360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.x0 = (float)viewport.x0; 7370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.y0 = (float)viewport.y0; 7380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.width = (float)viewport.width; 7390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.height = (float)viewport.height; 7400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.minZ = viewport.minZ; 7410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens view.maxZ = viewport.maxZ; 7420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Renderer::setViewport(view); 7440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 7460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens bool Device::validRectangle(const sw::Rect *rect, Image *surface) 7490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!rect) 7510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 7530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0) 7560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 7580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(rect->x0 < 0 || rect->y0 < 0) 7610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 7630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight()) 7660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return false; 7680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return true; 7710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 7730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void Device::finish() 7740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 7750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens synchronize(); 7760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 7770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 778