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