13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Reference Renderer 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Reference renderer interface. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrRenderer.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrPrimitiveAssembler.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrFragmentOperations.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrRasterizer.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rr 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytypedef double ClipFloat; // floating point type used in clipping 418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytypedef tcu::Vector<ClipFloat, 4> ClipVec4; 438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct RasterizationInternalBuffers 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<FragmentPacket> fragmentPackets; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<GenericVec4> shaderOutputs; 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<Fragment> shadedFragments; 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* fragmentDepthBuffer; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 readIndexArray (const IndexType type, const void* ptr, size_t ndx) 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT8: 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ((const deUint8*)ptr)[ndx]; 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT16: 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint16 retVal; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(&retVal, (const deUint8*)ptr + ndx * sizeof(deUint16), sizeof(deUint16)); 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT32: 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 retVal; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(&retVal, (const deUint8*)ptr + ndx * sizeof(deUint32), sizeof(deUint32)); 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::IVec4 getBufferSize (const rr::MultisampleConstPixelBufferAccess& multisampleBuffer) 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tcu::IVec4(0, 0, multisampleBuffer.raw().getHeight(), multisampleBuffer.raw().getDepth()); 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isEmpty (const rr::MultisampleConstPixelBufferAccess& access) 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return access.raw().getWidth() == 0 || access.raw().getHeight() == 0 || access.raw().getDepth() == 0; 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DrawContext 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int primitiveID; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DrawContext (void) 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : primitiveID(0) 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Calculates intersection of two rects given as (left, bottom, width, height) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::IVec4 rectIntersection (const tcu::IVec4& a, const tcu::IVec4& b) 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec2 pos = tcu::IVec2(de::max(a.x(), b.x()), de::max(a.y(), b.y())); 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec2 endPos = tcu::IVec2(de::min(a.x() + a.z(), b.x() + b.z()), de::min(a.y() + a.w(), b.y() + b.w())); 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tcu::IVec4(pos.x(), pos.y(), endPos.x() - pos.x(), endPos.y() - pos.y()); 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertPrimitiveToBaseType(std::vector<pa::Triangle>& output, std::vector<pa::Triangle>& input) 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::swap(output, input); 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertPrimitiveToBaseType(std::vector<pa::Line>& output, std::vector<pa::Line>& input) 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::swap(output, input); 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertPrimitiveToBaseType(std::vector<pa::Point>& output, std::vector<pa::Point>& input) 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::swap(output, input); 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertPrimitiveToBaseType(std::vector<pa::Line>& output, std::vector<pa::LineAdjacency>& input) 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry output.resize(input.size()); 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t i = 0; i < input.size(); ++i) 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int adjacentProvokingVertex = input[i].provokingIndex; 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int baseProvokingVertexIndex = adjacentProvokingVertex-1; 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry output[i] = pa::Line(input[i].v1, input[i].v2, baseProvokingVertexIndex); 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertPrimitiveToBaseType(std::vector<pa::Triangle>& output, std::vector<pa::TriangleAdjacency>& input) 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry output.resize(input.size()); 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t i = 0; i < input.size(); ++i) 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int adjacentProvokingVertex = input[i].provokingIndex; 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int baseProvokingVertexIndex = adjacentProvokingVertex/2; 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry output[i] = pa::Triangle(input[i].v0, input[i].v2, input[i].v4, baseProvokingVertexIndex); 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace cliputil 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Get clipped portion of the second endpoint 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Calculate the intersection of line segment v0-v1 and a given plane. Line 1568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * segment is defined by a pair of one-dimensional homogeneous coordinates. 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryClipFloat getSegmentVolumeEdgeClip (const ClipFloat v0, 1608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat w0, 1618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat v1, 1628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat w1, 1638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat plane) 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return (plane*w0 - v0) / ((v1 - v0) - plane*(w1 - w0)); 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Get clipped portion of the endpoint 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * How much (in [0-1] range) of a line segment v0-v1 would be clipped 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * of the v0 end of the line segment by clipping. 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryClipFloat getLineEndpointClipping (const ClipVec4& v0, const ClipVec4& v1) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat clipVolumeSize = (ClipFloat)1.0; 1778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (v0.z() > v0.w()) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Clip +Z 1818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return getSegmentVolumeEdgeClip(v0.z(), v0.w(), v1.z(), v1.w(), clipVolumeSize); 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (v0.z() < -v0.w()) 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Clip -Z 1868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return getSegmentVolumeEdgeClip(v0.z(), v0.w(), v1.z(), v1.w(), -clipVolumeSize); 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // no clipping 1918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return (ClipFloat)0.0; 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryClipVec4 vec4ToClipVec4 (const tcu::Vec4& v) 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return ClipVec4((ClipFloat)v.x(), (ClipFloat)v.y(), (ClipFloat)v.z(), (ClipFloat)v.w()); 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytcu::Vec4 clipVec4ToVec4 (const ClipVec4& v) 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return tcu::Vec4((float)v.x(), (float)v.y(), (float)v.z(), (float)v.w()); 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ClipVolumePlane 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry virtual bool pointInClipVolume (const ClipVec4& p) const = 0; 2098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry virtual ClipFloat clipLineSegmentEnd (const ClipVec4& v0, const ClipVec4& v1) const = 0; 2108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry virtual ClipVec4 getLineIntersectionPoint (const ClipVec4& v0, const ClipVec4& v1) const = 0; 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytemplate <int Sign, int CompNdx> 2148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryclass ComponentPlane : public ClipVolumePlane 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_STATIC_ASSERT(Sign == +1 || Sign == -1); 2178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool pointInClipVolume (const ClipVec4& p) const; 2208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ClipFloat clipLineSegmentEnd (const ClipVec4& v0, const ClipVec4& v1) const; 2218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ClipVec4 getLineIntersectionPoint (const ClipVec4& v0, const ClipVec4& v1) const; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytemplate <int Sign, int CompNdx> 2258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrybool ComponentPlane<Sign, CompNdx>::pointInClipVolume (const ClipVec4& p) const 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat clipVolumeSize = (ClipFloat)1.0; 2288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return (ClipFloat)(Sign * p[CompNdx]) <= clipVolumeSize * p.w(); 2308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 2318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytemplate <int Sign, int CompNdx> 2338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryClipFloat ComponentPlane<Sign, CompNdx>::clipLineSegmentEnd (const ClipVec4& v0, const ClipVec4& v1) const 2348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 2358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat clipVolumeSize = (ClipFloat)1.0; 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return getSegmentVolumeEdgeClip(v0[CompNdx], v0.w(), 2388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry v1[CompNdx], v1.w(), 2398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry (ClipFloat)Sign * clipVolumeSize); 2408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 2418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytemplate <int Sign, int CompNdx> 2438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryClipVec4 ComponentPlane<Sign, CompNdx>::getLineIntersectionPoint (const ClipVec4& v0, const ClipVec4& v1) const 2448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 2458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // A point on line might be far away, causing clipping ratio (clipLineSegmentEnd) to become extremely close to 1.0 2468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // even if the another point is not on the plane. Prevent clipping ratio from saturating by using points on line 2478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // that are (nearly) on this and (nearly) on the opposite plane. 2488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 249919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipVec4 clippedV0 = tcu::mix(v0, v1, ComponentPlane<+1, CompNdx>().clipLineSegmentEnd(v0, v1)); 250919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipVec4 clippedV1 = tcu::mix(v0, v1, ComponentPlane<-1, CompNdx>().clipLineSegmentEnd(v0, v1)); 251919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat clipRatio = clipLineSegmentEnd(clippedV0, clippedV1); 252919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry 253919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry // Find intersection point of line from v0 to v1 and the current plane. Avoid ratios near 1.0 254919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry if (clipRatio <= (ClipFloat)0.5) 255919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry return tcu::mix(clippedV0, clippedV1, clipRatio); 256919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry else 257919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry { 258919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat complementClipRatio = clipLineSegmentEnd(clippedV1, clippedV0); 259919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry return tcu::mix(clippedV1, clippedV0, complementClipRatio); 260919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry } 2618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct TriangleVertex 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ClipVec4 position; 2668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ClipFloat weight[3]; //!< barycentrics 2678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}; 2688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystruct SubTriangle 2708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 2718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TriangleVertex vertices[3]; 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid clipTriangleOneVertex (std::vector<TriangleVertex>& clippedEdges, const ClipVolumePlane& plane, const TriangleVertex& clipped, const TriangleVertex& v1, const TriangleVertex& v2) 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat degenerateLimit = (ClipFloat)1.0; 2778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // calc clip pos 2798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TriangleVertex mid1; 2808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TriangleVertex mid2; 2818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool outputDegenerate = false; 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 284919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& inside = v1; 285919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& outside = clipped; 286919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry TriangleVertex& middle = mid1; 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 288919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat hitDist = plane.clipLineSegmentEnd(inside.position, outside.position); 2898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (hitDist >= degenerateLimit) 2918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 2928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // do not generate degenerate triangles 2938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry outputDegenerate = true; 2948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 2968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 2978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 approximatedClipPoint = tcu::mix(inside.position, outside.position, hitDist); 2988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 anotherPointOnLine = (hitDist > (ClipFloat)0.5) ? (inside.position) : (outside.position); 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.position = plane.getLineIntersectionPoint(approximatedClipPoint, anotherPointOnLine); 3018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[0] = tcu::mix(inside.weight[0], outside.weight[0], hitDist); 3028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[1] = tcu::mix(inside.weight[1], outside.weight[1], hitDist); 3038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[2] = tcu::mix(inside.weight[2], outside.weight[2], hitDist); 3048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 308919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& inside = v2; 309919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& outside = clipped; 310919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry TriangleVertex& middle = mid2; 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 312919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat hitDist = plane.clipLineSegmentEnd(inside.position, outside.position); 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (hitDist >= degenerateLimit) 3158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // do not generate degenerate triangles 3178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry outputDegenerate = true; 3188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 3208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 approximatedClipPoint = tcu::mix(inside.position, outside.position, hitDist); 3228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 anotherPointOnLine = (hitDist > (ClipFloat)0.5) ? (inside.position) : (outside.position); 3238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.position = plane.getLineIntersectionPoint(approximatedClipPoint, anotherPointOnLine); 3258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[0] = tcu::mix(inside.weight[0], outside.weight[0], hitDist); 3268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[1] = tcu::mix(inside.weight[1], outside.weight[1], hitDist); 3278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[2] = tcu::mix(inside.weight[2], outside.weight[2], hitDist); 3288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!outputDegenerate) 3328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // gen quad (v1) -> mid1 -> mid2 -> (v2) 3348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(v1); 3358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(mid1); 3368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(mid2); 3378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(v2); 3388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 3408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // don't modify 3428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(v1); 3438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(clipped); 3448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(v2); 3458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid clipTriangleTwoVertices (std::vector<TriangleVertex>& clippedEdges, const ClipVolumePlane& plane, const TriangleVertex& v0, const TriangleVertex& clipped1, const TriangleVertex& clipped2) 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 350919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat unclippableLimit = (ClipFloat)1.0; 3518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // calc clip pos 3538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TriangleVertex mid1; 3548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TriangleVertex mid2; 355919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry bool unclippableVertex1 = false; 356919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry bool unclippableVertex2 = false; 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 359919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& inside = v0; 360919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& outside = clipped1; 361919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry TriangleVertex& middle = mid1; 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 363919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat hitDist = plane.clipLineSegmentEnd(inside.position, outside.position); 3648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 365919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry if (hitDist >= unclippableLimit) 3668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 367919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry // this edge cannot be clipped because the edge is really close to the volume boundary 368919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry unclippableVertex1 = true; 3698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 3718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 approximatedClipPoint = tcu::mix(inside.position, outside.position, hitDist); 3738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 anotherPointOnLine = (hitDist > (ClipFloat)0.5) ? (inside.position) : (outside.position); 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.position = plane.getLineIntersectionPoint(approximatedClipPoint, anotherPointOnLine); 3768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[0] = tcu::mix(inside.weight[0], outside.weight[0], hitDist); 3778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[1] = tcu::mix(inside.weight[1], outside.weight[1], hitDist); 3788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[2] = tcu::mix(inside.weight[2], outside.weight[2], hitDist); 3798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 383919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& inside = v0; 384919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const TriangleVertex& outside = clipped2; 385919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry TriangleVertex& middle = mid2; 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 387919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry const ClipFloat hitDist = plane.clipLineSegmentEnd(inside.position, outside.position); 3888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 389919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry if (hitDist >= unclippableLimit) 3908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 391919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry // this edge cannot be clipped because the edge is really close to the volume boundary 392919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry unclippableVertex2 = true; 3938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 3958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 approximatedClipPoint = tcu::mix(inside.position, outside.position, hitDist); 3978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 anotherPointOnLine = (hitDist > (ClipFloat)0.5) ? (inside.position) : (outside.position); 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.position = plane.getLineIntersectionPoint(approximatedClipPoint, anotherPointOnLine); 4008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[0] = tcu::mix(inside.weight[0], outside.weight[0], hitDist); 4018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[1] = tcu::mix(inside.weight[1], outside.weight[1], hitDist); 4028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry middle.weight[2] = tcu::mix(inside.weight[2], outside.weight[2], hitDist); 4038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 406919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry if (!unclippableVertex1 && !unclippableVertex2) 4078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 4088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // gen triangle (v0) -> mid1 -> mid2 4098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(v0); 4108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(mid1); 4118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(mid2); 4128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 413919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry else if (!unclippableVertex1 && unclippableVertex2) 414919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry { 415919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry // clip just vertex 1 416919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry clippedEdges.push_back(v0); 417919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry clippedEdges.push_back(mid1); 418919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry clippedEdges.push_back(clipped2); 419919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry } 420919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry else if (unclippableVertex1 && !unclippableVertex2) 421919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry { 422919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry // clip just vertex 2 423919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry clippedEdges.push_back(v0); 424919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry clippedEdges.push_back(clipped1); 425919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry clippedEdges.push_back(mid2); 426919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry } 4278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 4288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 4298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // don't modify 4308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(v0); 4318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(clipped1); 4328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedEdges.push_back(clipped2); 4338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid clipTriangleToPlane (std::vector<TriangleVertex>& clippedEdges, const TriangleVertex* vertices, const ClipVolumePlane& plane) 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool v0Clipped = !plane.pointInClipVolume(vertices[0].position); 4398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool v1Clipped = !plane.pointInClipVolume(vertices[1].position); 4408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool v2Clipped = !plane.pointInClipVolume(vertices[2].position); 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int clipCount = ((v0Clipped) ? (1) : (0)) + ((v1Clipped) ? (1) : (0)) + ((v2Clipped) ? (1) : (0)); 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (clipCount == 0) 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // pass 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry clippedEdges.insert(clippedEdges.begin(), vertices, vertices + 3); 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (clipCount == 1) 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // clip one vertex 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (v0Clipped) clipTriangleOneVertex(clippedEdges, plane, vertices[0], vertices[1], vertices[2]); 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (v1Clipped) clipTriangleOneVertex(clippedEdges, plane, vertices[1], vertices[2], vertices[0]); 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else clipTriangleOneVertex(clippedEdges, plane, vertices[2], vertices[0], vertices[1]); 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (clipCount == 2) 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // clip two vertices 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!v0Clipped) clipTriangleTwoVertices(clippedEdges, plane, vertices[0], vertices[1], vertices[2]); 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (!v1Clipped) clipTriangleTwoVertices(clippedEdges, plane, vertices[1], vertices[2], vertices[0]); 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else clipTriangleTwoVertices(clippedEdges, plane, vertices[2], vertices[0], vertices[1]); 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (clipCount == 3) 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // discard 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // cliputil 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytcu::Vec2 to2DCartesian (const tcu::Vec4& p) 4758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 4768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return tcu::Vec2(p.x(), p.y()) / p.w(); 4778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 4788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryfloat cross2D (const tcu::Vec2& a, const tcu::Vec2& b) 4808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 4818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return tcu::cross(tcu::Vec3(a.x(), a.y(), 0.0f), tcu::Vec3(b.x(), b.y(), 0.0f)).z(); 4828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 4838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid flatshadePrimitiveVertices (pa::Triangle& target, size_t outputNdx) 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const rr::GenericVec4 flatValue = target.getProvokingVertex()->outputs[outputNdx]; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v0->outputs[outputNdx] = flatValue; 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v1->outputs[outputNdx] = flatValue; 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v2->outputs[outputNdx] = flatValue; 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid flatshadePrimitiveVertices (pa::Line& target, size_t outputNdx) 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const rr::GenericVec4 flatValue = target.getProvokingVertex()->outputs[outputNdx]; 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v0->outputs[outputNdx] = flatValue; 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v1->outputs[outputNdx] = flatValue; 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid flatshadePrimitiveVertices (pa::Point& target, size_t outputNdx) 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(target); 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(outputNdx); 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerType> 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid flatshadeVertices (const Program& program, ContainerType& list) 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // flatshade 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<rr::VertexVaryingInfo>& fragInputs = (program.geometryShader) ? (program.geometryShader->getOutputs()) : (program.vertexShader->getOutputs()); 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t inputNdx = 0; inputNdx < fragInputs.size(); ++inputNdx) 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (fragInputs[inputNdx].flatshade) 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (typename ContainerType::iterator it = list.begin(); it != list.end(); ++it) 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry flatshadePrimitiveVertices(*it, inputNdx); 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/*--------------------------------------------------------------------*//*! 5188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Clip triangles to the clip volume. 5198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *//*--------------------------------------------------------------------*/ 5208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid clipPrimitives (std::vector<pa::Triangle>& list, 5218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 5228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool clipWithZPlanes, 5238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry VertexPacketAllocator& vpalloc) 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using namespace cliputil; 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry cliputil::ComponentPlane<+1, 0> clipPosX; 5288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry cliputil::ComponentPlane<-1, 0> clipNegX; 5298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry cliputil::ComponentPlane<+1, 1> clipPosY; 5308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry cliputil::ComponentPlane<-1, 1> clipNegY; 5318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry cliputil::ComponentPlane<+1, 2> clipPosZ; 5328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry cliputil::ComponentPlane<-1, 2> clipNegZ; 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<rr::VertexVaryingInfo>& fragInputs = (program.geometryShader) ? (program.geometryShader->getOutputs()) : (program.vertexShader->getOutputs()); 5358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVolumePlane* planes[] = { &clipPosX, &clipNegX, &clipPosY, &clipNegY, &clipPosZ, &clipNegZ }; 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPlanes = (clipWithZPlanes) ? (6) : (4); 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::vector<pa::Triangle> outputTriangles; 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int inputTriangleNdx = 0; inputTriangleNdx < (int)list.size(); ++inputTriangleNdx) 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool clippedByPlane[6]; 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Needs clipping? 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool discardPrimitive = false; 5478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool fullyInClipVolume = true; 5488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 5498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int planeNdx = 0; planeNdx < numPlanes; ++planeNdx) 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVolumePlane* plane = planes[planeNdx]; 5528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool v0InsidePlane = plane->pointInClipVolume(vec4ToClipVec4(list[inputTriangleNdx].v0->position)); 5538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool v1InsidePlane = plane->pointInClipVolume(vec4ToClipVec4(list[inputTriangleNdx].v1->position)); 5548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool v2InsidePlane = plane->pointInClipVolume(vec4ToClipVec4(list[inputTriangleNdx].v2->position)); 5558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 5568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Fully outside 5578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!v0InsidePlane && !v1InsidePlane && !v2InsidePlane) 5588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 5598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry discardPrimitive = true; 5608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 5618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 5628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Partially outside 5638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (!v0InsidePlane || !v1InsidePlane || !v2InsidePlane) 5648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 5658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedByPlane[planeNdx] = true; 5668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry fullyInClipVolume = false; 5678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 5688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Fully inside 5698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 5708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clippedByPlane[planeNdx] = false; 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (discardPrimitive) 5748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 5758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 5768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (fullyInClipVolume) 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry outputTriangles.push_back(list[inputTriangleNdx]); 5798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Clip 5848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 5858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::vector<SubTriangle> subTriangles (1); 5868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SubTriangle& initialTri = subTriangles[0]; 5878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 5888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[0].position = vec4ToClipVec4(list[inputTriangleNdx].v0->position); 5898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[0].weight[0] = (ClipFloat)1.0; 5908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[0].weight[1] = (ClipFloat)0.0; 5918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[0].weight[2] = (ClipFloat)0.0; 5928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 5938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[1].position = vec4ToClipVec4(list[inputTriangleNdx].v1->position); 5948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[1].weight[0] = (ClipFloat)0.0; 5958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[1].weight[1] = (ClipFloat)1.0; 5968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[1].weight[2] = (ClipFloat)0.0; 5978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 5988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[2].position = vec4ToClipVec4(list[inputTriangleNdx].v2->position); 5998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[2].weight[0] = (ClipFloat)0.0; 6008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[2].weight[1] = (ClipFloat)0.0; 6018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry initialTri.vertices[2].weight[2] = (ClipFloat)1.0; 6028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Clip all subtriangles to all relevant planes 6048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int planeNdx = 0; planeNdx < numPlanes; ++planeNdx) 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::vector<SubTriangle> nextPhaseSubTriangles; 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!clippedByPlane[planeNdx]) 6098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 6108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int subTriangleNdx = 0; subTriangleNdx < (int)subTriangles.size(); ++subTriangleNdx) 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::vector<TriangleVertex> convexPrimitive; 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 615919f1341e41b3a1e31f5746b30db0f648c47b757Jarkko Pöyry // Clip triangle and form a convex n-gon ( n c {3, 4} ) 6168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry clipTriangleToPlane(convexPrimitive, subTriangles[subTriangleNdx].vertices, *planes[planeNdx]); 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Subtriangle completely discarded 6198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (convexPrimitive.empty()) 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(convexPrimitive.size() == 3 || convexPrimitive.size() == 4); 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry //Triangulate planar convex n-gon 6258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 6268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TriangleVertex& v0 = convexPrimitive[0]; 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int subsubTriangleNdx = 1; subsubTriangleNdx + 1 < (int)convexPrimitive.size(); ++subsubTriangleNdx) 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const float degenerateEpsilon = 1.0e-6f; 6318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const TriangleVertex& v1 = convexPrimitive[subsubTriangleNdx]; 6328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const TriangleVertex& v2 = convexPrimitive[subsubTriangleNdx + 1]; 6338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const float visibleArea = de::abs(cross2D(to2DCartesian(clipVec4ToVec4(v1.position)) - to2DCartesian(clipVec4ToVec4(v0.position)), 6348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry to2DCartesian(clipVec4ToVec4(v2.position)) - to2DCartesian(clipVec4ToVec4(v0.position)))); 6358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // has surface area (is not a degenerate) 6378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (visibleArea >= degenerateEpsilon) 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SubTriangle subsubTriangle; 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry subsubTriangle.vertices[0] = v0; 6428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry subsubTriangle.vertices[1] = v1; 6438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry subsubTriangle.vertices[2] = v2; 6448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry nextPhaseSubTriangles.push_back(subsubTriangle); 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 6498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 6508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry subTriangles.swap(nextPhaseSubTriangles); 6528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 6538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Rebuild pa::Triangles from subtriangles 6558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int subTriangleNdx = 0; subTriangleNdx < (int)subTriangles.size(); ++subTriangleNdx) 6568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 6578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry VertexPacket* p0 = vpalloc.alloc(); 6588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry VertexPacket* p1 = vpalloc.alloc(); 6598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry VertexPacket* p2 = vpalloc.alloc(); 6608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry pa::Triangle ngonFragment (p0, p1, p2, -1); 6618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p0->position = clipVec4ToVec4(subTriangles[subTriangleNdx].vertices[0].position); 6638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p1->position = clipVec4ToVec4(subTriangles[subTriangleNdx].vertices[1].position); 6648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p2->position = clipVec4ToVec4(subTriangles[subTriangleNdx].vertices[2].position); 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (size_t outputNdx = 0; outputNdx < fragInputs.size(); ++outputNdx) 6678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 6688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (fragInputs[outputNdx].type == GENERICVECTYPE_FLOAT) 6698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 6708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::Vec4 out0 = list[inputTriangleNdx].v0->outputs[outputNdx].get<float>(); 6718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::Vec4 out1 = list[inputTriangleNdx].v1->outputs[outputNdx].get<float>(); 6728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::Vec4 out2 = list[inputTriangleNdx].v2->outputs[outputNdx].get<float>(); 6738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p0->outputs[outputNdx] = (float)subTriangles[subTriangleNdx].vertices[0].weight[0] * out0 6758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry + (float)subTriangles[subTriangleNdx].vertices[0].weight[1] * out1 6768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry + (float)subTriangles[subTriangleNdx].vertices[0].weight[2] * out2; 6778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p1->outputs[outputNdx] = (float)subTriangles[subTriangleNdx].vertices[1].weight[0] * out0 6798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry + (float)subTriangles[subTriangleNdx].vertices[1].weight[1] * out1 6808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry + (float)subTriangles[subTriangleNdx].vertices[1].weight[2] * out2; 6818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p2->outputs[outputNdx] = (float)subTriangles[subTriangleNdx].vertices[2].weight[0] * out0 6838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry + (float)subTriangles[subTriangleNdx].vertices[2].weight[1] * out1 6848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry + (float)subTriangles[subTriangleNdx].vertices[2].weight[2] * out2; 6858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 6868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 6878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 6888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // only floats are interpolated, all others must be flatshaded then 6898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p0->outputs[outputNdx] = list[inputTriangleNdx].getProvokingVertex()->outputs[outputNdx]; 6908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p1->outputs[outputNdx] = list[inputTriangleNdx].getProvokingVertex()->outputs[outputNdx]; 6918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry p2->outputs[outputNdx] = list[inputTriangleNdx].getProvokingVertex()->outputs[outputNdx]; 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 6958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry outputTriangles.push_back(ngonFragment); 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // output result 7018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry list.swap(outputTriangles); 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/*--------------------------------------------------------------------*//*! 7058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Clip lines to the near and far clip planes. 7068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * 7078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Clipping to other planes is a by-product of the viewport test (i.e. 7088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * rasterization area selection). 7098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *//*--------------------------------------------------------------------*/ 7108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid clipPrimitives (std::vector<pa::Line>& list, 7118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 7128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool clipWithZPlanes, 7138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry VertexPacketAllocator& vpalloc) 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(vpalloc); 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using namespace cliputil; 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Lines are clipped only by the far and the near planes here. Line clipping by other planes done in the rasterization phase 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<rr::VertexVaryingInfo>& fragInputs = (program.geometryShader) ? (program.geometryShader->getOutputs()) : (program.vertexShader->getOutputs()); 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<pa::Line> visibleLines; 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Z-clipping disabled, don't do anything 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!clipWithZPlanes) 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < list.size(); ++ndx) 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pa::Line& l = list[ndx]; 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Totally discarded? 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((l.v0->position.z() < -l.v0->position.w() && l.v1->position.z() < -l.v1->position.w()) || 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (l.v0->position.z() > l.v0->position.w() && l.v1->position.z() > l.v1->position.w())) 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // discard 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Something is visible 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 p0 = vec4ToClipVec4(l.v0->position); 7408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipVec4 p1 = vec4ToClipVec4(l.v1->position); 7418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat t0 = getLineEndpointClipping(p0, p1); 7428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ClipFloat t1 = getLineEndpointClipping(p1, p0); 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Not clipped at all? 7458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (t0 == (ClipFloat)0.0 && t1 == (ClipFloat)0.0) 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry visibleLines.push_back(pa::Line(l.v0, l.v1, -1)); 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Clip position 7528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry l.v0->position = clipVec4ToVec4(tcu::mix(p0, p1, t0)); 7538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry l.v1->position = clipVec4ToVec4(tcu::mix(p1, p0, t1)); 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Clip attributes 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t outputNdx = 0; outputNdx < fragInputs.size(); ++outputNdx) 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // only floats are clipped, other types are flatshaded 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (fragInputs[outputNdx].type == GENERICVECTYPE_FLOAT) 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::Vec4 a0 = l.v0->outputs[outputNdx].get<float>(); 7628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::Vec4 a1 = l.v1->outputs[outputNdx].get<float>(); 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry l.v0->outputs[outputNdx] = tcu::mix(a0, a1, (float)t0); 7658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry l.v1->outputs[outputNdx] = tcu::mix(a1, a0, (float)t1); 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry visibleLines.push_back(pa::Line(l.v0, l.v1, -1)); 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // return visible in list 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::swap(visibleLines, list); 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/*--------------------------------------------------------------------*//*! 7788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Discard points not within clip volume. Clipping is a by-product 7798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * of the viewport test. 7808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *//*--------------------------------------------------------------------*/ 7818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid clipPrimitives (std::vector<pa::Point>& list, 7828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 7838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool clipWithZPlanes, 7848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry VertexPacketAllocator& vpalloc) 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(vpalloc); 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(program); 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<pa::Point> visiblePoints; 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Z-clipping disabled, don't do anything 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!clipWithZPlanes) 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < list.size(); ++ndx) 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pa::Point& p = list[ndx]; 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // points are discarded if Z is not in range. (Wide) point clipping is done in the rasterization phase 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::inRange(p.v0->position.z(), -p.v0->position.w(), p.v0->position.w())) 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry visiblePoints.push_back(pa::Point(p.v0)); 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // return visible in list 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::swap(visiblePoints, list); 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid transformVertexClipCoordsToWindowCoords (const RenderState& state, VertexPacket& packet) 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // To normalized device coords 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position = tcu::Vec4(packet.position.x()/packet.position.w(), 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position.y()/packet.position.w(), 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position.z()/packet.position.w(), 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f /packet.position.w()); 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // To window coords 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const WindowRectangle& viewport = state.viewport.rect; 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float halfW = (float)(viewport.width) / 2.0f; 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float halfH = (float)(viewport.height) / 2.0f; 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float oX = (float)viewport.left + halfW; 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float oY = (float)viewport.bottom + halfH; 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float zn = state.viewport.zn; 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float zf = state.viewport.zf; 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position = tcu::Vec4(packet.position.x()*halfW + oX, 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position.y()*halfH + oY, 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position.z()*(zf - zn)/2.0f + (zn + zf)/2.0f, 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet.position.w()); 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid transformPrimitiveClipCoordsToWindowCoords (const RenderState& state, pa::Triangle& target) 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformVertexClipCoordsToWindowCoords(state, *target.v0); 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformVertexClipCoordsToWindowCoords(state, *target.v1); 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformVertexClipCoordsToWindowCoords(state, *target.v2); 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid transformPrimitiveClipCoordsToWindowCoords (const RenderState& state, pa::Line& target) 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformVertexClipCoordsToWindowCoords(state, *target.v0); 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformVertexClipCoordsToWindowCoords(state, *target.v1); 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid transformPrimitiveClipCoordsToWindowCoords (const RenderState& state, pa::Point& target) 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformVertexClipCoordsToWindowCoords(state, *target.v0); 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerType> 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid transformClipCoordsToWindowCoords (const RenderState& state, ContainerType& list) 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (typename ContainerType::iterator it = list.begin(); it != list.end(); ++it) 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformPrimitiveClipCoordsToWindowCoords(state, *it); 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid makeSharedVerticeDistinct (VertexPacket*& packet, std::set<VertexPacket*, std::less<void*> >& vertices, VertexPacketAllocator& vpalloc) 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // distinct 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (vertices.find(packet) == vertices.end()) 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertices.insert(packet); 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexPacket* newPacket = vpalloc.alloc(); 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // copy packet output values 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newPacket->position = packet->position; 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newPacket->pointSize = packet->pointSize; 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newPacket->primitiveID = packet->primitiveID; 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t outputNdx = 0; outputNdx < vpalloc.getNumVertexOutputs(); ++outputNdx) 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newPacket->outputs[outputNdx] = packet->outputs[outputNdx]; 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // no need to insert new packet to "vertices" as newPacket is unique 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry packet = newPacket; 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid makeSharedVerticesDistinct (pa::Triangle& target, std::set<VertexPacket*, std::less<void*> >& vertices, VertexPacketAllocator& vpalloc) 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticeDistinct(target.v0, vertices, vpalloc); 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticeDistinct(target.v1, vertices, vpalloc); 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticeDistinct(target.v2, vertices, vpalloc); 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid makeSharedVerticesDistinct (pa::Line& target, std::set<VertexPacket*, std::less<void*> >& vertices, VertexPacketAllocator& vpalloc) 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticeDistinct(target.v0, vertices, vpalloc); 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticeDistinct(target.v1, vertices, vpalloc); 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid makeSharedVerticesDistinct (pa::Point& target, std::set<VertexPacket*, std::less<void*> >& vertices, VertexPacketAllocator& vpalloc) 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticeDistinct(target.v0, vertices, vpalloc); 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerType> 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid makeSharedVerticesDistinct (ContainerType& list, VertexPacketAllocator& vpalloc) 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::set<VertexPacket*, std::less<void*> > vertices; 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (typename ContainerType::iterator it = list.begin(); it != list.end(); ++it) 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticesDistinct(*it, vertices, vpalloc); 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generatePrimitiveIDs (pa::Triangle& target, int id) 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v0->primitiveID = id; 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v1->primitiveID = id; 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v2->primitiveID = id; 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generatePrimitiveIDs (pa::Line& target, int id) 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v0->primitiveID = id; 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v1->primitiveID = id; 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generatePrimitiveIDs (pa::Point& target, int id) 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry target.v0->primitiveID = id; 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerType> 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generatePrimitiveIDs (ContainerType& list, DrawContext& drawContext) 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (typename ContainerType::iterator it = list.begin(); it != list.end(); ++it) 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generatePrimitiveIDs(*it, drawContext.primitiveID++); 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float findTriangleVertexDepthSlope (const tcu::Vec4& p, const tcu::Vec4& v0, const tcu::Vec4& v1) 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // screen space 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec3 ssp = p.swizzle(0, 1, 2); 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec3 ssv0 = v0.swizzle(0, 1, 2); 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec3 ssv1 = v1.swizzle(0, 1, 2); 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // dx & dy 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec3 a = ssv0.swizzle(0,1,2) - ssp.swizzle(0,1,2); 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec3 b = ssv1.swizzle(0,1,2) - ssp.swizzle(0,1,2); 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float epsilon = 0.0001f; 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float det = (a.x() * b.y() - b.x() * a.y()); 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // degenerate triangle, it won't generate any fragments anyway. Return value doesn't matter 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::abs(det) < epsilon) 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0.0f; 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec2 dxDir = tcu::Vec2( b.y(), -a.y()) / det; 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec2 dyDir = tcu::Vec2(-b.x(), a.x()) / det; 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float dzdx = dxDir.x() * a.z() + dxDir.y() * b.z(); 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float dzdy = dyDir.x() * a.z() + dyDir.y() * b.z(); 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // approximate using max(|dz/dx|, |dz/dy|) 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::max(de::abs(dzdx), de::abs(dzdy)); 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float findPrimitiveMaximumDepthSlope (const pa::Triangle& triangle) 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float d1 = findTriangleVertexDepthSlope(triangle.v0->position, triangle.v1->position, triangle.v2->position); 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float d2 = findTriangleVertexDepthSlope(triangle.v1->position, triangle.v2->position, triangle.v0->position); 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float d3 = findTriangleVertexDepthSlope(triangle.v2->position, triangle.v0->position, triangle.v1->position); 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::max(d1, de::max(d2, d3)); 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float getFloatingPointMinimumResolvableDifference (float maxZValue, tcu::TextureFormat::ChannelType type) 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type == tcu::TextureFormat::FLOAT) 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // 32f 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxExponent = tcu::Float32(maxZValue).exponent(); 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tcu::Float32::construct(+1, maxExponent - 23, 1 << 23).asFloat(); 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // unexpected format 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0.0f; 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float getFixedPointMinimumResolvableDifference (int numBits) 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tcu::Float32::construct(+1, -numBits, 1 << 23).asFloat(); 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float findPrimitiveMinimumResolvableDifference (const pa::Triangle& triangle, const rr::MultisampleConstPixelBufferAccess& depthAccess) 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float maxZvalue = de::max(de::max(triangle.v0->position.z(), triangle.v1->position.z()), triangle.v2->position.z()); 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureFormat format = depthAccess.raw().getFormat(); 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureFormat::ChannelOrder order = format.order; 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (order == tcu::TextureFormat::D) 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // depth only 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureFormat::ChannelType channelType = format.type; 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(channelType); 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBits = tcu::getTextureFormatBitDepth(format).x(); 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getFloatingPointMinimumResolvableDifference(maxZvalue, channelType); 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note channelClass might be CLASS_LAST but that's ok 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getFixedPointMinimumResolvableDifference(numBits); 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (order == tcu::TextureFormat::DS) 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // depth stencil, special cases for possible combined formats 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV) 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getFloatingPointMinimumResolvableDifference(maxZvalue, tcu::TextureFormat::FLOAT); 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (format.type == tcu::TextureFormat::UNSIGNED_INT_24_8) 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getFixedPointMinimumResolvableDifference(24); 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // unexpected format 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0.0f; 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid writeFragmentPackets (const RenderState& state, 10268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const RenderTarget& renderTarget, 10278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 10288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const FragmentPacket* fragmentPackets, 10298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry int numRasterizedPackets, 10308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry rr::FaceType facetype, 10318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const std::vector<rr::GenericVec4>& fragmentOutputArray, 10328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const float* depthValues, 10338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::vector<Fragment>& fragmentBuffer) 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSamples = renderTarget.colorBuffers[0].getNumSamples(); 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t numOutputs = program.fragmentShader->getOutputs().size(); 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FragmentProcessor fragProcessor; 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(fragmentOutputArray.size() >= (size_t)numRasterizedPackets*4*numOutputs); 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(fragmentBuffer.size() >= (size_t)numRasterizedPackets*4); 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Translate fragments but do not set the value yet 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int fragCount = 0; 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int packetNdx = 0; packetNdx < numRasterizedPackets; ++packetNdx) 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int fragNdx = 0; fragNdx < 4; fragNdx++) 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FragmentPacket& packet = fragmentPackets[packetNdx]; 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int xo = fragNdx%2; 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int yo = fragNdx/2; 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getCoverageAnyFragmentSampleLive(packet.coverage, numSamples, xo, yo)) 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Fragment& fragment = fragmentBuffer[fragCount++]; 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fragment.pixelCoord = packet.position + tcu::IVec2(xo, yo); 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fragment.coverage = (deUint32)((packet.coverage & getCoverageFragmentSampleBits(numSamples, xo, yo)) >> getCoverageOffset(numSamples, xo, yo)); 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fragment.sampleDepths = (depthValues) ? (&depthValues[(packetNdx*4 + yo*2 + xo)*numSamples]) : (DE_NULL); 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Set per output output values 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rr::FragmentOperationState noStencilDepthWriteState(state.fragOps); 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry noStencilDepthWriteState.depthMask = false; 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry noStencilDepthWriteState.stencilStates[facetype].sFail = STENCILOP_KEEP; 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry noStencilDepthWriteState.stencilStates[facetype].dpFail = STENCILOP_KEEP; 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry noStencilDepthWriteState.stencilStates[facetype].dpPass = STENCILOP_KEEP; 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int fragCount = 0; 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t outputNdx = 0; outputNdx < numOutputs; ++outputNdx) 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Only the last output-pass has default state, other passes have stencil & depth writemask=0 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const rr::FragmentOperationState& fragOpsState = (outputNdx == numOutputs-1) ? (state.fragOps) : (noStencilDepthWriteState); 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int packetNdx = 0; packetNdx < numRasterizedPackets; ++packetNdx) 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int fragNdx = 0; fragNdx < 4; fragNdx++) 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FragmentPacket& packet = fragmentPackets[packetNdx]; 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int xo = fragNdx%2; 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int yo = fragNdx/2; 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Add only fragments that have live samples to shaded fragments queue. 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getCoverageAnyFragmentSampleLive(packet.coverage, numSamples, xo, yo)) 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Fragment& fragment = fragmentBuffer[fragCount++]; 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fragment.value = fragmentOutputArray[(packetNdx*4 + fragNdx) * numOutputs + outputNdx]; 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Execute per-fragment ops and write 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fragProcessor.render(renderTarget.colorBuffers[outputNdx], renderTarget.depthBuffer, renderTarget.stencilBuffer, &fragmentBuffer[0], fragCount, facetype, fragOpsState); 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid rasterizePrimitive (const RenderState& state, 10998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const RenderTarget& renderTarget, 11008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 11018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const pa::Triangle& triangle, 11028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::IVec4& renderTargetRect, 11038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry RasterizationInternalBuffers& buffers) 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSamples = renderTarget.colorBuffers[0].getNumSamples(); 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float depthClampMin = de::min(state.viewport.zn, state.viewport.zf); 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float depthClampMax = de::max(state.viewport.zn, state.viewport.zf); 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleRasterizer rasterizer (renderTargetRect, numSamples, state.rasterization); 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float depthOffset = 0.0f; 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizer.init(triangle.v0->position, triangle.v1->position, triangle.v2->position); 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Culling 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FaceType visibleFace = rasterizer.getVisibleFace(); 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((state.cullMode == CULLMODE_FRONT && visibleFace == FACETYPE_FRONT) || 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (state.cullMode == CULLMODE_BACK && visibleFace == FACETYPE_BACK)) 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shading context 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FragmentShadingContext shadingContext(triangle.v0->outputs, triangle.v1->outputs, triangle.v2->outputs, &buffers.shaderOutputs[0], buffers.fragmentDepthBuffer, triangle.v2->primitiveID, (int)program.fragmentShader->getOutputs().size(), numSamples); 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Polygon offset 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers.fragmentDepthBuffer && state.fragOps.polygonOffsetEnabled) 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float maximumDepthSlope = findPrimitiveMaximumDepthSlope(triangle); 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float minimumResolvableDifference = findPrimitiveMinimumResolvableDifference(triangle, renderTarget.depthBuffer); 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry depthOffset = maximumDepthSlope * state.fragOps.polygonOffsetFactor + minimumResolvableDifference * state.fragOps.polygonOffsetUnits; 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Execute rasterize - shade - write loop 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxFragmentPackets = (int)buffers.fragmentPackets.size(); 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRasterizedPackets = 0; 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Rasterize 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizer.rasterize(&buffers.fragmentPackets[0], buffers.fragmentDepthBuffer, maxFragmentPackets, numRasterizedPackets); 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // numRasterizedPackets is guaranteed to be greater than zero for shadeFragments() 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!numRasterizedPackets) 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; // Rasterization finished. 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Polygon offset 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers.fragmentDepthBuffer && state.fragOps.polygonOffsetEnabled) 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int sampleNdx = 0; sampleNdx < numRasterizedPackets * 4 * numSamples; ++sampleNdx) 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.fragmentDepthBuffer[sampleNdx] = de::clamp(buffers.fragmentDepthBuffer[sampleNdx] + depthOffset, 0.0f, 1.0f); 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shade 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry program.fragmentShader->shadeFragments(&buffers.fragmentPackets[0], numRasterizedPackets, shadingContext); 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Depth clamp 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers.fragmentDepthBuffer && state.fragOps.depthClampEnabled) 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int sampleNdx = 0; sampleNdx < numRasterizedPackets * 4 * numSamples; ++sampleNdx) 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.fragmentDepthBuffer[sampleNdx] = de::clamp(buffers.fragmentDepthBuffer[sampleNdx], depthClampMin, depthClampMax); 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Handle fragment shader outputs 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeFragmentPackets(state, renderTarget, program, &buffers.fragmentPackets[0], numRasterizedPackets, visibleFace, buffers.shaderOutputs, buffers.fragmentDepthBuffer, buffers.shadedFragments); 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid rasterizePrimitive (const RenderState& state, 11678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const RenderTarget& renderTarget, 11688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 11698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const pa::Line& line, 11708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::IVec4& renderTargetRect, 11718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry RasterizationInternalBuffers& buffers) 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSamples = renderTarget.colorBuffers[0].getNumSamples(); 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float depthClampMin = de::min(state.viewport.zn, state.viewport.zf); 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float depthClampMax = de::max(state.viewport.zn, state.viewport.zf); 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool msaa = numSamples > 1; 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FragmentShadingContext shadingContext (line.v0->outputs, line.v1->outputs, DE_NULL, &buffers.shaderOutputs[0], buffers.fragmentDepthBuffer, line.v1->primitiveID, (int)program.fragmentShader->getOutputs().size(), numSamples); 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SingleSampleLineRasterizer aliasedRasterizer (renderTargetRect); 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MultiSampleLineRasterizer msaaRasterizer (numSamples, renderTargetRect); 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize rasterization. 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (msaa) 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msaaRasterizer.init(line.v0->position, line.v1->position, state.line.lineWidth); 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry aliasedRasterizer.init(line.v0->position, line.v1->position, state.line.lineWidth); 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxFragmentPackets = (int)buffers.fragmentPackets.size(); 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRasterizedPackets = 0; 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Rasterize 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (msaa) 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msaaRasterizer.rasterize (&buffers.fragmentPackets[0], buffers.fragmentDepthBuffer, maxFragmentPackets, numRasterizedPackets); 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry aliasedRasterizer.rasterize (&buffers.fragmentPackets[0], buffers.fragmentDepthBuffer, maxFragmentPackets, numRasterizedPackets); 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // numRasterizedPackets is guaranteed to be greater than zero for shadeFragments() 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!numRasterizedPackets) 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; // Rasterization finished. 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shade 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry program.fragmentShader->shadeFragments(&buffers.fragmentPackets[0], numRasterizedPackets, shadingContext); 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Depth clamp 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers.fragmentDepthBuffer && state.fragOps.depthClampEnabled) 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int sampleNdx = 0; sampleNdx < numRasterizedPackets * 4 * numSamples; ++sampleNdx) 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.fragmentDepthBuffer[sampleNdx] = de::clamp(buffers.fragmentDepthBuffer[sampleNdx], depthClampMin, depthClampMax); 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Handle fragment shader outputs 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeFragmentPackets(state, renderTarget, program, &buffers.fragmentPackets[0], numRasterizedPackets, rr::FACETYPE_FRONT, buffers.shaderOutputs, buffers.fragmentDepthBuffer, buffers.shadedFragments); 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid rasterizePrimitive (const RenderState& state, 12208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const RenderTarget& renderTarget, 12218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 12228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const pa::Point& point, 12238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const tcu::IVec4& renderTargetRect, 12248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry RasterizationInternalBuffers& buffers) 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSamples = renderTarget.colorBuffers[0].getNumSamples(); 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float depthClampMin = de::min(state.viewport.zn, state.viewport.zf); 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float depthClampMax = de::max(state.viewport.zn, state.viewport.zf); 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleRasterizer rasterizer1 (renderTargetRect, numSamples, state.rasterization); 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleRasterizer rasterizer2 (renderTargetRect, numSamples, state.rasterization); 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // draw point as two triangles 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float offset = point.v0->pointSize / 2.0f; 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 w0 = tcu::Vec4(point.v0->position.x() + offset, point.v0->position.y() + offset, point.v0->position.z(), point.v0->position.w()); 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 w1 = tcu::Vec4(point.v0->position.x() - offset, point.v0->position.y() + offset, point.v0->position.z(), point.v0->position.w()); 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 w2 = tcu::Vec4(point.v0->position.x() - offset, point.v0->position.y() - offset, point.v0->position.z(), point.v0->position.w()); 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 w3 = tcu::Vec4(point.v0->position.x() + offset, point.v0->position.y() - offset, point.v0->position.z(), point.v0->position.w()); 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizer1.init(w0, w1, w2); 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizer2.init(w0, w2, w3); 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shading context 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FragmentShadingContext shadingContext(point.v0->outputs, DE_NULL, DE_NULL, &buffers.shaderOutputs[0], buffers.fragmentDepthBuffer, point.v0->primitiveID, (int)program.fragmentShader->getOutputs().size(), numSamples); 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Execute rasterize - shade - write loop 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxFragmentPackets = (int)buffers.fragmentPackets.size(); 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRasterizedPackets = 0; 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Rasterize both triangles 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizer1.rasterize(&buffers.fragmentPackets[0], buffers.fragmentDepthBuffer, maxFragmentPackets, numRasterizedPackets); 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numRasterizedPackets != maxFragmentPackets) 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* const depthBufferAppendPointer = (buffers.fragmentDepthBuffer) ? (buffers.fragmentDepthBuffer + numRasterizedPackets*numSamples*4) : (DE_NULL); 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRasterizedPackets2 = 0; 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizer2.rasterize(&buffers.fragmentPackets[numRasterizedPackets], depthBufferAppendPointer, maxFragmentPackets - numRasterizedPackets, numRasterizedPackets2); 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numRasterizedPackets += numRasterizedPackets2; 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // numRasterizedPackets is guaranteed to be greater than zero for shadeFragments() 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!numRasterizedPackets) 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; // Rasterization finished. 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shade 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry program.fragmentShader->shadeFragments(&buffers.fragmentPackets[0], numRasterizedPackets, shadingContext); 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Depth clamp 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers.fragmentDepthBuffer && state.fragOps.depthClampEnabled) 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int sampleNdx = 0; sampleNdx < numRasterizedPackets * 4 * numSamples; ++sampleNdx) 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.fragmentDepthBuffer[sampleNdx] = de::clamp(buffers.fragmentDepthBuffer[sampleNdx], depthClampMin, depthClampMax); 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Handle fragment shader outputs 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeFragmentPackets(state, renderTarget, program, &buffers.fragmentPackets[0], numRasterizedPackets, rr::FACETYPE_FRONT, buffers.shaderOutputs, buffers.fragmentDepthBuffer, buffers.shadedFragments); 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerType> 12858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid rasterize (const RenderState& state, 12868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const RenderTarget& renderTarget, 12878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Program& program, 12888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const ContainerType& list) 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSamples = renderTarget.colorBuffers[0].getNumSamples(); 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numFragmentOutputs = (int)program.fragmentShader->getOutputs().size(); 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t maxFragmentPackets = 128; 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec4 viewportRect = tcu::IVec4(state.viewport.rect.left, state.viewport.rect.bottom, state.viewport.rect.width, state.viewport.rect.height); 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec4 bufferRect = getBufferSize(renderTarget.colorBuffers[0]); 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec4 renderTargetRect = rectIntersection(viewportRect, bufferRect); 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // shared buffers for all primitives 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<FragmentPacket> fragmentPackets (maxFragmentPackets); 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<GenericVec4> shaderOutputs (maxFragmentPackets*4*numFragmentOutputs); 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<Fragment> shadedFragments (maxFragmentPackets*4); 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<float> depthValues (0); 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* depthBufferPointer = DE_NULL; 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RasterizationInternalBuffers buffers; 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // calculate depth only if we have a depth buffer 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isEmpty(renderTarget.depthBuffer)) 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry depthValues.resize(maxFragmentPackets*4*numSamples); 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry depthBufferPointer = &depthValues[0]; 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set buffers 13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.fragmentPackets.swap(fragmentPackets); 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.shaderOutputs.swap(shaderOutputs); 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.shadedFragments.swap(shadedFragments); 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.fragmentDepthBuffer = depthBufferPointer; 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // rasterize 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (typename ContainerType::const_iterator it = list.begin(); it != list.end(); ++it) 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterizePrimitive(state, renderTarget, program, *it, renderTargetRect, buffers); 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws transformed triangles, lines or points to render target 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerType> 13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawBasicPrimitives (const RenderState& state, const RenderTarget& renderTarget, const Program& program, ContainerType& primList, VertexPacketAllocator& vpalloc) 13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool clipZ = !state.fragOps.depthClampEnabled; 13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Transform feedback 13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Flatshading 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry flatshadeVertices(program, primList); 13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Clipping 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [jarkko] is creating & swapping std::vectors really a good solution? 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry clipPrimitives(primList, program, clipZ, vpalloc); 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Transform vertices to window coords 13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry transformClipCoordsToWindowCoords(state, primList); 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Rasterize and paint 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterize(state, renderTarget, program, primList); 13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyVertexPacketPointers(const VertexPacket** dst, const pa::Point& in) 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[0] = in.v0; 13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyVertexPacketPointers(const VertexPacket** dst, const pa::Line& in) 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[0] = in.v0; 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[1] = in.v1; 13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyVertexPacketPointers(const VertexPacket** dst, const pa::Triangle& in) 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[0] = in.v0; 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[1] = in.v1; 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[2] = in.v2; 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyVertexPacketPointers(const VertexPacket** dst, const pa::LineAdjacency& in) 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[0] = in.v0; 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[1] = in.v1; 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[2] = in.v2; 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[3] = in.v3; 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyVertexPacketPointers(const VertexPacket** dst, const pa::TriangleAdjacency& in) 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[0] = in.v0; 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[1] = in.v1; 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[2] = in.v2; 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[3] = in.v3; 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[4] = in.v4; 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[5] = in.v5; 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <PrimitiveType DrawPrimitiveType> // \note DrawPrimitiveType can only be Points, line_strip, or triangle_strip 13868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid drawGeometryShaderOutputAsPrimitives (const RenderState& state, const RenderTarget& renderTarget, const Program& program, VertexPacket* const* vertices, size_t numVertices, VertexPacketAllocator& vpalloc) 13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Run primitive assembly for generated stream 13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t assemblerPrimitiveCount = PrimitiveTypeTraits<DrawPrimitiveType>::Assembler::getPrimitiveCount(numVertices); 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<typename PrimitiveTypeTraits<DrawPrimitiveType>::BaseType> inputPrimitives (assemblerPrimitiveCount); 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PrimitiveTypeTraits<DrawPrimitiveType>::Assembler::exec(inputPrimitives.begin(), vertices, numVertices, state.provokingVertexConvention); // \note input Primitives are baseType_t => only basic primitives (non adjacency) will compile 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Make shared vertices distinct 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticesDistinct(inputPrimitives, vpalloc); 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Draw assembled primitives 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawBasicPrimitives(state, renderTarget, program, inputPrimitives, vpalloc); 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <PrimitiveType DrawPrimitiveType> 14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawWithGeometryShader(const RenderState& state, const RenderTarget& renderTarget, const Program& program, std::vector<typename PrimitiveTypeTraits<DrawPrimitiveType>::Type>& input, DrawContext& drawContext) 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Vertices outputted by geometry shader may have different number of output variables than the original, create new memory allocator 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexPacketAllocator vpalloc(program.geometryShader->getOutputs().size()); 14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Run geometry shader for all primitives 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GeometryEmitter emitter (vpalloc, program.geometryShader->getNumVerticesOut()); 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<PrimitivePacket> primitives (input.size()); 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInvocations = (int)program.geometryShader->getNumInvocations(); 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int verticesIn = PrimitiveTypeTraits<DrawPrimitiveType>::Type::NUM_VERTICES; 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t primitiveNdx = 0; primitiveNdx < input.size(); ++primitiveNdx) 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitives[primitiveNdx].primitiveIDIn = drawContext.primitiveID++; 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyVertexPacketPointers(primitives[primitiveNdx].vertices, input[primitiveNdx]); 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitives.empty()) 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int invocationNdx = 0; invocationNdx < numInvocations; ++invocationNdx) 14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shading invocation 14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry program.geometryShader->shadePrimitives(emitter, verticesIn, &primitives[0], (int)primitives.size(), invocationNdx); 14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find primitives in the emitted vertices 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexPacket*> emitted; 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry emitter.moveEmittedTo(emitted); 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t primitiveBegin = 0; primitiveBegin < emitted.size();) 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t primitiveEnd; 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find primitive begin 14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!emitted[primitiveBegin]) 14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++primitiveBegin; 14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find primitive end 14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveEnd = primitiveBegin + 1; 14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (; (primitiveEnd < emitted.size()) && emitted[primitiveEnd]; ++primitiveEnd); // find primitive end 14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Draw range [begin, end) 14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (program.geometryShader->getOutputType()) 14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case rr::GEOMETRYSHADEROUTPUTTYPE_POINTS: drawGeometryShaderOutputAsPrimitives<PRIMITIVETYPE_POINTS> (state, renderTarget, program, &emitted[primitiveBegin], primitiveEnd-primitiveBegin, vpalloc); break; 14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case rr::GEOMETRYSHADEROUTPUTTYPE_LINE_STRIP: drawGeometryShaderOutputAsPrimitives<PRIMITIVETYPE_LINE_STRIP> (state, renderTarget, program, &emitted[primitiveBegin], primitiveEnd-primitiveBegin, vpalloc); break; 14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP: drawGeometryShaderOutputAsPrimitives<PRIMITIVETYPE_TRIANGLE_STRIP> (state, renderTarget, program, &emitted[primitiveBegin], primitiveEnd-primitiveBegin, vpalloc); break; 14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Next primitive 14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveBegin = primitiveEnd + 1; 14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Assembles, tesselates, runs geometry shader and draws primitives of any type from vertex list. 14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <PrimitiveType DrawPrimitiveType> 14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawAsPrimitives (const RenderState& state, const RenderTarget& renderTarget, const Program& program, VertexPacket* const* vertices, int numVertices, DrawContext& drawContext, VertexPacketAllocator& vpalloc) 14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Assemble primitives (deconstruct stips & loops) 14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t assemblerPrimitiveCount = PrimitiveTypeTraits<DrawPrimitiveType>::Assembler::getPrimitiveCount(numVertices); 14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<typename PrimitiveTypeTraits<DrawPrimitiveType>::Type> inputPrimitives (assemblerPrimitiveCount); 14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PrimitiveTypeTraits<DrawPrimitiveType>::Assembler::exec(inputPrimitives.begin(), vertices, (size_t)numVertices, state.provokingVertexConvention); 14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Tesselate 14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry //if (state.tesselation) 14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // primList = state.tesselation.exec(primList); 14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Geometry shader 14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (program.geometryShader) 14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If there is an active geometry shader, it will convert any primitive type to basic types 14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawWithGeometryShader<DrawPrimitiveType>(state, renderTarget, program, inputPrimitives, drawContext); 14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<typename PrimitiveTypeTraits<DrawPrimitiveType>::BaseType> basePrimitives; 14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // convert types from X_adjacency to X 14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry convertPrimitiveToBaseType(basePrimitives, inputPrimitives); 14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Make shared vertices distinct. Needed for that the translation to screen space happens only once per vertex, and for flatshading 14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeSharedVerticesDistinct(basePrimitives, vpalloc); 15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // A primitive ID will be generated even if no geometry shader is active 15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generatePrimitiveIDs(basePrimitives, drawContext); 15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Draw as a basic type 15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawBasicPrimitives(state, renderTarget, program, basePrimitives, vpalloc); 15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isValidCommand (const DrawCommand& command, int numInstances) 15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // numInstances should be valid 15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numInstances < 1) 15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shaders should have the same varyings 15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader) 15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.vertexShader->getOutputs() != command.program.geometryShader->getInputs()) 15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getOutputs() != command.program.fragmentShader->getInputs()) 15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.vertexShader->getOutputs() != command.program.fragmentShader->getInputs()) 15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Shader input/output types are set 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.vertexShader->getInputs().size(); ++varyingNdx) 15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.vertexShader->getInputs()[varyingNdx].type != GENERICVECTYPE_FLOAT && 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.vertexShader->getInputs()[varyingNdx].type != GENERICVECTYPE_INT32 && 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.vertexShader->getInputs()[varyingNdx].type != GENERICVECTYPE_UINT32) 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.vertexShader->getOutputs().size(); ++varyingNdx) 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.vertexShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_FLOAT && 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.vertexShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_INT32 && 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.vertexShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_UINT32) 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.fragmentShader->getInputs().size(); ++varyingNdx) 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.fragmentShader->getInputs()[varyingNdx].type != GENERICVECTYPE_FLOAT && 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.fragmentShader->getInputs()[varyingNdx].type != GENERICVECTYPE_INT32 && 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.fragmentShader->getInputs()[varyingNdx].type != GENERICVECTYPE_UINT32) 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.fragmentShader->getOutputs().size(); ++varyingNdx) 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.fragmentShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_FLOAT && 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.fragmentShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_INT32 && 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.fragmentShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_UINT32) 15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader) 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.geometryShader->getInputs().size(); ++varyingNdx) 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getInputs()[varyingNdx].type != GENERICVECTYPE_FLOAT && 15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.geometryShader->getInputs()[varyingNdx].type != GENERICVECTYPE_INT32 && 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.geometryShader->getInputs()[varyingNdx].type != GENERICVECTYPE_UINT32) 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.geometryShader->getOutputs().size(); ++varyingNdx) 15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_FLOAT && 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.geometryShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_INT32 && 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.geometryShader->getOutputs()[varyingNdx].type != GENERICVECTYPE_UINT32) 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Enough vertex inputs? 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((size_t)command.numVertexAttribs < command.program.vertexShader->getInputs().size()) 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // There is a fragment output sink for each output? 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((size_t)command.renderTarget.numColorBuffers < command.program.fragmentShader->getOutputs().size()) 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // All destination buffers should have same number of samples and same size 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outputNdx = 0; outputNdx < command.renderTarget.numColorBuffers; ++outputNdx) 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getBufferSize(command.renderTarget.colorBuffers[0]) != getBufferSize(command.renderTarget.colorBuffers[outputNdx])) 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.renderTarget.colorBuffers[0].getNumSamples() != command.renderTarget.colorBuffers[outputNdx].getNumSamples()) 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // All destination buffers should have same basic type as matching fragment output 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t varyingNdx = 0; varyingNdx < command.program.fragmentShader->getOutputs().size(); ++varyingNdx) 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureChannelClass colorbufferClass = tcu::getTextureChannelClass(command.renderTarget.colorBuffers[varyingNdx].raw().getFormat().type); 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenericVecType colorType = (colorbufferClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? (rr::GENERICVECTYPE_INT32) : ((colorbufferClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (rr::GENERICVECTYPE_UINT32) : (rr::GENERICVECTYPE_FLOAT)); 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.fragmentShader->getOutputs()[varyingNdx].type != colorType) 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Integer values are flatshaded 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t outputNdx = 0; outputNdx < command.program.vertexShader->getOutputs().size(); ++outputNdx) 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!command.program.vertexShader->getOutputs()[outputNdx].flatshade && 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (command.program.vertexShader->getOutputs()[outputNdx].type == GENERICVECTYPE_INT32 || 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.vertexShader->getOutputs()[outputNdx].type == GENERICVECTYPE_UINT32)) 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader) 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t outputNdx = 0; outputNdx < command.program.geometryShader->getOutputs().size(); ++outputNdx) 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!command.program.geometryShader->getOutputs()[outputNdx].flatshade && 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (command.program.geometryShader->getOutputs()[outputNdx].type == GENERICVECTYPE_INT32 || 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.geometryShader->getOutputs()[outputNdx].type == GENERICVECTYPE_UINT32)) 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Draw primitive is valid for geometry shader 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader) 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getInputType() == rr::GEOMETRYSHADERINPUTTYPE_POINTS && command.primitives.getPrimitiveType() != PRIMITIVETYPE_POINTS) 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES && 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (command.primitives.getPrimitiveType() != PRIMITIVETYPE_LINES && 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.primitives.getPrimitiveType() != PRIMITIVETYPE_LINE_STRIP && 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.primitives.getPrimitiveType() != PRIMITIVETYPE_LINE_LOOP)) 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES && 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (command.primitives.getPrimitiveType() != PRIMITIVETYPE_TRIANGLES && 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.primitives.getPrimitiveType() != PRIMITIVETYPE_TRIANGLE_STRIP && 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.primitives.getPrimitiveType() != PRIMITIVETYPE_TRIANGLE_FAN)) 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY && 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (command.primitives.getPrimitiveType() != PRIMITIVETYPE_LINES_ADJACENCY && 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.primitives.getPrimitiveType() != PRIMITIVETYPE_LINE_STRIP_ADJACENCY)) 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.program.geometryShader->getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY && 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (command.primitives.getPrimitiveType() != PRIMITIVETYPE_TRIANGLES_ADJACENCY && 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.primitives.getPrimitiveType() != PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY)) 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDrawIndices::DrawIndices (const deUint32* ptr, int baseVertex_) 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : indices (ptr) 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , indexType (INDEXTYPE_UINT32) 16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , baseVertex(baseVertex_) 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDrawIndices::DrawIndices (const deUint16* ptr, int baseVertex_) 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : indices (ptr) 16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , indexType (INDEXTYPE_UINT16) 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , baseVertex(baseVertex_) 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDrawIndices::DrawIndices (const deUint8* ptr, int baseVertex_) 16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : indices (ptr) 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , indexType (INDEXTYPE_UINT8) 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , baseVertex(baseVertex_) 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDrawIndices::DrawIndices (const void* ptr, IndexType type, int baseVertex_) 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : indices (ptr) 16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , indexType (type) 16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , baseVertex(baseVertex_) 16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPrimitiveList::PrimitiveList (PrimitiveType primitiveType, int numElements, const int firstElement) 16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType (primitiveType) 16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numElements (numElements) 16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_indices (DE_NULL) 16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_indexType (INDEXTYPE_LAST) 16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_baseVertex (firstElement) 16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numElements >= 0 && "Invalid numElements"); 16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(firstElement >= 0 && "Invalid firstElement"); 16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPrimitiveList::PrimitiveList (PrimitiveType primitiveType, int numElements, const DrawIndices& indices) 16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType (primitiveType) 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numElements ((size_t)numElements) 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_indices (indices.indices) 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_indexType (indices.indexType) 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_baseVertex (indices.baseVertex) 16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numElements >= 0 && "Invalid numElements"); 16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrysize_t PrimitiveList::getIndex (size_t elementNdx) const 16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // indices == DE_NULL interpreted as command.indices = [first (=baseVertex) + 0, first + 1, first + 2...] 16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_indices) 16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int index = m_baseVertex + (int)readIndexArray(m_indexType, m_indices, elementNdx); 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(index >= 0); // do not access indices < 0 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (size_t)index; 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (size_t)(m_baseVertex) + elementNdx; 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool PrimitiveList::isRestartIndex (size_t elementNdx, deUint32 restartIndex) const 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // implicit index or explicit index (without base vertex) equals restart 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_indices) 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return readIndexArray(m_indexType, m_indices, elementNdx) == restartIndex; 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return elementNdx == (size_t)restartIndex; 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderer::Renderer (void) 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderer::~Renderer (void) 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Renderer::draw (const DrawCommand& command) const 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawInstanced(command, 1); 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Renderer::drawInstanced (const DrawCommand& command, int numInstances) const 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do not run bad commands 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool validCommand = isValidCommand(command, numInstances); 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!validCommand) 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do not draw if nothing to draw 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (command.primitives.getNumElements() == 0 || numInstances == 0) 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Prepare transformation 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t numVaryings = command.program.vertexShader->getOutputs().size(); 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexPacketAllocator vpalloc(numVaryings); 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexPacket*> vertexPackets = vpalloc.allocArray(command.primitives.getNumElements()); 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DrawContext drawContext; 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceID = 0; instanceID < numInstances; ++instanceID) 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Each instance has its own primitives 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawContext.primitiveID = 0; 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t elementNdx = 0; elementNdx < command.primitives.getNumElements(); ++elementNdx) 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVertexPackets = 0; 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // collect primitive vertices until restart 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (elementNdx < command.primitives.getNumElements() && 17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !(command.state.restart.enabled && command.primitives.isRestartIndex(elementNdx, command.state.restart.restartIndex))) 17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // input 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexPackets[numVertexPackets]->instanceNdx = instanceID; 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexPackets[numVertexPackets]->vertexNdx = (int)command.primitives.getIndex(elementNdx); 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // output 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexPackets[numVertexPackets]->pointSize = command.state.point.pointSize; // default value from the current state 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexPackets[numVertexPackets]->position = tcu::Vec4(0, 0, 0, 0); // no undefined values 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++numVertexPackets; 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++elementNdx; 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Duplicated restart shade 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numVertexPackets == 0) 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo Vertex cache? 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Transform vertices 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry command.program.vertexShader->shadeVertices(command.vertexAttribs, &vertexPackets[0], numVertexPackets); 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Draw primitives 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (command.primitives.getPrimitiveType()) 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLES: { drawAsPrimitives<PRIMITIVETYPE_TRIANGLES> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLE_STRIP: { drawAsPrimitives<PRIMITIVETYPE_TRIANGLE_STRIP> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLE_FAN: { drawAsPrimitives<PRIMITIVETYPE_TRIANGLE_FAN> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINES: { drawAsPrimitives<PRIMITIVETYPE_LINES> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINE_STRIP: { drawAsPrimitives<PRIMITIVETYPE_LINE_STRIP> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINE_LOOP: { drawAsPrimitives<PRIMITIVETYPE_LINE_LOOP> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_POINTS: { drawAsPrimitives<PRIMITIVETYPE_POINTS> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINES_ADJACENCY: { drawAsPrimitives<PRIMITIVETYPE_LINES_ADJACENCY> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINE_STRIP_ADJACENCY: { drawAsPrimitives<PRIMITIVETYPE_LINE_STRIP_ADJACENCY> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLES_ADJACENCY: { drawAsPrimitives<PRIMITIVETYPE_TRIANGLES_ADJACENCY> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY:{ drawAsPrimitives<PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY> (command.state, command.renderTarget, command.program, &vertexPackets[0], numVertexPackets, drawContext, vpalloc); break; } 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rr 1815