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