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 "common/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 es1 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 renderTarget = nullptr; 38d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens depthBuffer = nullptr; 39d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stencilBuffer = nullptr; 40d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 41d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setDepthBufferEnable(true); 42d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setFillMode(FILL_SOLID); 43d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setShadingMode(SHADING_GOURAUD); 44d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setDepthWriteEnable(true); 45d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setAlphaTestEnable(false); 46d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setSourceBlendFactor(BLEND_ONE); 47d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setDestBlendFactor(BLEND_ZERO); 48d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setCullMode(CULL_COUNTERCLOCKWISE); 49d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setDepthCompare(DEPTH_LESSEQUAL); 50d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setAlphaReference(0.0f); 51d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setAlphaCompare(ALPHA_ALWAYS); 52d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setAlphaBlendEnable(false); 53d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setFogEnable(false); 54d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setSpecularEnable(true); 55d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setLocalViewer(false); 56d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setFogColor(0); 57d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setPixelFogMode(FOG_NONE); 58d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setFogStart(0.0f); 59d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setFogEnd(1.0f); 60d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setFogDensity(1.0f); 61d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setRangeFogEnable(false); 62d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilEnable(false); 63d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilFailOperation(OPERATION_KEEP); 64d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilZFailOperation(OPERATION_KEEP); 65d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilPassOperation(OPERATION_KEEP); 66d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilCompare(STENCIL_ALWAYS); 67d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilReference(0); 68d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilMask(0xFFFFFFFF); 69d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilWriteMask(0xFFFFFFFF); 70d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setVertexFogMode(FOG_NONE); 71d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setClipFlags(0); 72d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setPointSize(1.0f); 73d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setPointSizeMin(0.125f); 74d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setPointSizeMax(8192.0f); 75d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setColorWriteMask(0, 0x0000000F); 76d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setBlendOperation(BLENDOP_ADD); 77d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissorEnable = false; 78d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setSlopeDepthBias(0.0f); 79d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setTwoSidedStencil(false); 80d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilFailOperationCCW(OPERATION_KEEP); 81d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilZFailOperationCCW(OPERATION_KEEP); 82d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilPassOperationCCW(OPERATION_KEEP); 83d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setStencilCompareCCW(STENCIL_ALWAYS); 84d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setColorWriteMask(1, 0x0000000F); 85d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setColorWriteMask(2, 0x0000000F); 86d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setColorWriteMask(3, 0x0000000F); 87d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setBlendConstant(0xFFFFFFFF); 88d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setWriteSRGB(false); 89d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setDepthBias(0.0f); 90d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setSeparateAlphaBlendEnable(false); 91d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setSourceBlendFactorAlpha(BLEND_ONE); 92d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setDestBlendFactorAlpha(BLEND_ZERO); 93d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setBlendOperationAlpha(BLENDOP_ADD); 94d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setPointSpriteEnable(true); 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 126d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens Device::~Device() 127d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 128d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(renderTarget) 129d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 130d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens renderTarget->release(); 131d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens renderTarget = nullptr; 132d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 133d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 134d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(depthBuffer) 135d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 136d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens depthBuffer->release(); 137d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens depthBuffer = nullptr; 138d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 139d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 140d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(stencilBuffer) 141d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 142d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stencilBuffer->release(); 143d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stencilBuffer = nullptr; 144d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 145d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 146d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens delete context; 147d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 148d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 149d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) 150d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 151d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!renderTarget || !rgbaMask) 152d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 153d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 154d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 155d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 156d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens float rgba[4]; 157d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgba[0] = red; 158d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgba[1] = green; 159d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgba[2] = blue; 160d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens rgba[3] = alpha; 161d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 162d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::SliceRect clearRect = renderTarget->getRect(); 163d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 164d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(scissorEnable) 165d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 166d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 167d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 168d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 169d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask); 170d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 171d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 172d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::clearDepth(float z) 173d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 174d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!depthBuffer) 175d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 176d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 177d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 178d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 179d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens z = clamp01(z); 180d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::SliceRect clearRect = depthBuffer->getRect(); 181d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 182d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(scissorEnable) 183d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 184d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 185d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 186d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 187d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 188d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 189d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 190d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::clearStencil(unsigned int stencil, unsigned int mask) 191d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 192d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!stencilBuffer) 193d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 194d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 195d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 196d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 197d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::SliceRect clearRect = stencilBuffer->getRect(); 198d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 199d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(scissorEnable) 200d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 201d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1); 202d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 203d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 204d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 205d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 206d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 207d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) 208d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 209d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(height > OUTLINE_RESOLUTION) 210d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 211d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens ERR("Invalid parameters: %dx%d", width, height); 212d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return nullptr; 213d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 214d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 215d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool lockable = true; 216d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 217d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens switch(format) 218d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 219d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // case FORMAT_D15S1: 220d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_D24S8: 221d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_D24X8: 222d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // case FORMAT_D24X4S4: 223d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_D24FS8: 224d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_D32: 225d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_D16: 226d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens lockable = false; 227d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens break; 228d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // case FORMAT_S8_LOCKABLE: 229d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // case FORMAT_D16_LOCKABLE: 230d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_D32F_LOCKABLE: 231d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // case FORMAT_D32_LOCKABLE: 232d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_DF24S8: 233d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens case FORMAT_DF16S8: 234d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens lockable = true; 235d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens break; 236d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens default: 237d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens UNREACHABLE(format); 238d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 239d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 240d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable); 241d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 242d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!surface) 243d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 244d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens ERR("Out of memory"); 245d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return nullptr; 246d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 247d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 248d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return surface; 249d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 250d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 251d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable) 252d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 253d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(height > OUTLINE_RESOLUTION) 254d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 255d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens ERR("Invalid parameters: %dx%d", width, height); 256d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return nullptr; 257d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 258d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 259d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable); 260d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 261d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!surface) 262d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 263d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens ERR("Out of memory"); 264d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return nullptr; 265d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 266d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 267d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return surface; 268d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 269d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 270d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount) 271d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 272d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!bindResources() || !primitiveCount) 273d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 274d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 275d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 276d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 277d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens draw(type, indexOffset, primitiveCount); 278d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 279d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 280d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount) 281d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 282d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!bindResources() || !primitiveCount) 283d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 284d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 285d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 286d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 287d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setIndexBuffer(nullptr); 288d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 289d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens draw(type, 0, primitiveCount); 290d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 291d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 292d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::setScissorEnable(bool enable) 293d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 294d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissorEnable = enable; 295d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 296d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 297d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::setRenderTarget(int index, egl::Image *renderTarget) 298d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 299d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(renderTarget) 300d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 301d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens renderTarget->addRef(); 302d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 303d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 304d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(this->renderTarget) 305d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 306d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->renderTarget->release(); 307d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 308d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 309d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->renderTarget = renderTarget; 310d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 311d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens Renderer::setRenderTarget(index, renderTarget); 312d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 313d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 314d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::setDepthBuffer(egl::Image *depthBuffer) 315d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 316d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(this->depthBuffer == depthBuffer) 317d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 318d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 319d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 320d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 321d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(depthBuffer) 322d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 323d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens depthBuffer->addRef(); 324d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 325d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 326d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(this->depthBuffer) 327d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 328d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->depthBuffer->release(); 329d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 330d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 331d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->depthBuffer = depthBuffer; 332d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 333d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens Renderer::setDepthBuffer(depthBuffer); 334d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 335d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 336d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::setStencilBuffer(egl::Image *stencilBuffer) 337d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 338d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(this->stencilBuffer == stencilBuffer) 339d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 340d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return; 341d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 342d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 343d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(stencilBuffer) 344d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 345d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stencilBuffer->addRef(); 346d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 347d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 348d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(this->stencilBuffer) 349d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 350d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->stencilBuffer->release(); 351d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 352d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 353d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->stencilBuffer = stencilBuffer; 354d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 355d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens Renderer::setStencilBuffer(stencilBuffer); 356d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 357d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 358d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::setScissorRect(const sw::Rect &rect) 359d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 360d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissorRect = rect; 361d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 362d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 363d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::setViewport(const Viewport &viewport) 364d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 365d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens this->viewport = viewport; 366d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 367d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 368d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter) 369d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 370d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest)) 371d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 372d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens ERR("Invalid parameters"); 373d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; 374d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 375d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 376d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int sWidth = source->getWidth(); 377d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int sHeight = source->getHeight(); 378d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int dWidth = dest->getWidth(); 379d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int dHeight = dest->getHeight(); 380d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 381d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens SliceRect sRect; 382d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens SliceRect dRect; 383d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 384d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(sourceRect) 385d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 386d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sRect = *sourceRect; 387d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 388d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 389d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 390d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sRect.y0 = 0; 391d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sRect.x0 = 0; 392d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sRect.y1 = sHeight; 393d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sRect.x1 = sWidth; 394d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 395d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 396d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(destRect) 397d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 398d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dRect = *destRect; 399d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 400d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 401d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 402d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dRect.y0 = 0; 403d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dRect.x0 = 0; 404d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dRect.y1 = dHeight; 405d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dRect.x1 = dWidth; 406d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 407d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 408d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0); 409d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool equalFormats = source->getInternalFormat() == dest->getInternalFormat(); 410d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat()); 411d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool alpha0xFF = false; 412d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 413d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) || 414d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8)) 415d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 416d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens equalFormats = true; 417d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens alpha0xFF = true; 418d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 419d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 420d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(depthStencil) // Copy entirely, internally // FIXME: Check 421d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 422d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(source->hasDepth()) 423d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 424d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC); 425d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC); 426d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 427d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int width = source->getWidth(); 428d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int height = source->getHeight(); 429d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int pitch = source->getInternalPitchB(); 430d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 431d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens for(unsigned int y = 0; y < height; y++) 432d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 433d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 434d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 435d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sourceBuffer += pitch; 436d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens destBuffer += pitch; 437d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 438d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 439d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens source->unlockInternal(); 440d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dest->unlockInternal(); 441d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 442d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 443d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(source->hasStencil()) 444d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 445d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC); 446d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC); 447d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 448d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int width = source->getWidth(); 449d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int height = source->getHeight(); 450d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int pitch = source->getStencilPitchB(); 451d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 452d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens for(unsigned int y = 0; y < height; y++) 453d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 454d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes 455d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 456d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sourceBuffer += pitch; 457d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens destBuffer += pitch; 458d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 459d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 460d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens source->unlockStencil(); 461d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dest->unlockStencil(); 462d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 463d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 464d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else if(!scaling && equalFormats) 465d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 466d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC); 467d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC); 468d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int sourcePitch = source->getInternalPitchB(); 469d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int destPitch = dest->getInternalPitchB(); 470d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 471d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int width = dRect.x1 - dRect.x0; 472d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int height = dRect.y1 - dRect.y0; 473d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens unsigned int bytes = width * egl::Image::bytes(source->getInternalFormat()); 474d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 475d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens for(unsigned int y = 0; y < height; y++) 476d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 477d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens memcpy(destBytes, sourceBytes, bytes); 478d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 479d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(alpha0xFF) 480d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 481d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens for(unsigned int x = 0; x < width; x++) 482d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 483d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens destBytes[4 * x + 3] = 0xFF; 484d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 485d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 486d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 487d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sourceBytes += sourcePitch; 488d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens destBytes += destPitch; 489d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 490d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 491d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens source->unlockInternal(); 492d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens dest->unlockInternal(); 493d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 494d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 495d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 496d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens blit(source, sRect, dest, dRect, scaling && filter); 497d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 498d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 499d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return true; 500d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 501d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 502d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool Device::bindResources() 503d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 504d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!bindViewport()) 505d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 506d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; // Zero-area target region 507d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 508d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 509d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return true; 510d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 511d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 512d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool Device::bindViewport() 513d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 514d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(viewport.width <= 0 || viewport.height <= 0) 515d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 516d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; 517d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 518d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 519d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(scissorEnable) 520d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 521d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1) 522d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 523d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; 524d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 525d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 526d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::Rect scissor; 527d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x0 = scissorRect.x0; 528d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x1 = scissorRect.x1; 529d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y0 = scissorRect.y0; 530d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y1 = scissorRect.y1; 531d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 532d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setScissor(scissor); 533d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 534d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens else 535d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 536d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::Rect scissor; 537d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x0 = viewport.x0; 538d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x1 = viewport.x0 + viewport.width; 539d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y0 = viewport.y0; 540d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y1 = viewport.y0 + viewport.height; 541d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 542d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(renderTarget) 543d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 544d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x0 = max(scissor.x0, 0); 545d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x1 = min(scissor.x1, renderTarget->getWidth()); 546d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y0 = max(scissor.y0, 0); 547d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y1 = min(scissor.y1, renderTarget->getHeight()); 548d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 549d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 550d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(depthBuffer) 551d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 552d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x0 = max(scissor.x0, 0); 553d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x1 = min(scissor.x1, depthBuffer->getWidth()); 554d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y0 = max(scissor.y0, 0); 555d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y1 = min(scissor.y1, depthBuffer->getHeight()); 556d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 557d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 558d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(stencilBuffer) 559d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 560d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x0 = max(scissor.x0, 0); 561d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.x1 = min(scissor.x1, stencilBuffer->getWidth()); 562d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y0 = max(scissor.y0, 0); 563d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens scissor.y1 = min(scissor.y1, stencilBuffer->getHeight()); 564d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 565d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 566d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens setScissor(scissor); 567d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 568d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 569d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sw::Viewport view; 570d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens view.x0 = (float)viewport.x0; 571d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens view.y0 = (float)viewport.y0; 572d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens view.width = (float)viewport.width; 573d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens view.height = (float)viewport.height; 574d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens view.minZ = viewport.minZ; 575d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens view.maxZ = viewport.maxZ; 576d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 577d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens Renderer::setViewport(view); 578d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 579d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return true; 580d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 581d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 582d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface) 583d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 584d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(!rect) 585d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 586d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return true; 587d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 588d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 589d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0) 590d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 591d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; 592d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 593d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 594d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(rect->x0 < 0 || rect->y0 < 0) 595d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 596d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; 597d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 598d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 599d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight()) 600d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 601d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return false; 602d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 603d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 604d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return true; 605d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 606d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens 607d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void Device::finish() 608d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens { 609d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens synchronize(); 610d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 611d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens} 612