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