/**************************************************************************** * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * @file rasterizer.h * * @brief Definitions for the rasterizer. * ******************************************************************************/ #pragma once #include "context.h" #include #include "conservativeRast.h" #include "multisample.h" void RasterizeLine(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, void* pData); void RasterizeSimplePoint(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, void* pData); void RasterizeTriPoint(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, void* pData); void InitRasterizerFunctions(); INLINE __m128i fpToFixedPoint(const __m128 vIn) { __m128 vFixed = _mm_mul_ps(vIn, _mm_set1_ps(FIXED_POINT_SCALE)); return _mm_cvtps_epi32(vFixed); } enum TriEdgesStates { STATE_NO_VALID_EDGES = 0, STATE_E0_E1_VALID, STATE_E0_E2_VALID, STATE_E1_E2_VALID, STATE_ALL_EDGES_VALID, STATE_VALID_TRI_EDGE_COUNT, }; enum TriEdgesValues { NO_VALID_EDGES = 0, E0_E1_VALID = 0x3, E0_E2_VALID = 0x5, E1_E2_VALID = 0x6, ALL_EDGES_VALID = 0x7, VALID_TRI_EDGE_COUNT, }; // Selector for correct templated RasterizeTriangle function PFN_WORK_FUNC GetRasterizerFunc(SWR_MULTISAMPLE_COUNT numSamples, bool IsCenter, bool IsConservative, SWR_INPUT_COVERAGE InputCoverage, uint32_t EdgeEnable, bool RasterizeScissorEdges); ////////////////////////////////////////////////////////////////////////// /// @brief ValidTriEdges convenience typedefs used for templated function /// specialization supported Fixed Point precisions typedef std::integral_constant AllEdgesValidT; typedef std::integral_constant E0E1ValidT; typedef std::integral_constant E0E2ValidT; typedef std::integral_constant E1E2ValidT; typedef std::integral_constant NoEdgesValidT; typedef std::integral_constant StateAllEdgesValidT; typedef std::integral_constant StateE0E1ValidT; typedef std::integral_constant StateE0E2ValidT; typedef std::integral_constant StateE1E2ValidT; typedef std::integral_constant StateNoEdgesValidT; // some specializations to convert from edge state to edge bitmask values template struct EdgeMaskVal { static_assert(EdgeMask::value > STATE_ALL_EDGES_VALID, "Primary EdgeMaskVal shouldn't be instantiated"); }; template <> struct EdgeMaskVal { typedef AllEdgesValidT T; }; template <> struct EdgeMaskVal { typedef E0E1ValidT T; }; template <> struct EdgeMaskVal { typedef E0E2ValidT T; }; template <> struct EdgeMaskVal { typedef E1E2ValidT T; }; template <> struct EdgeMaskVal { typedef NoEdgesValidT T; }; INLINE uint32_t EdgeValToEdgeState(uint32_t val) { SWR_ASSERT(val < VALID_TRI_EDGE_COUNT, "Unexpected tri edge mask"); static const uint32_t edgeValToEdgeState[VALID_TRI_EDGE_COUNT] = {0, 0, 0, 1, 0, 2, 3, 4}; return edgeValToEdgeState[val]; } ////////////////////////////////////////////////////////////////////////// /// @struct RasterScissorEdgesT /// @brief Primary RasterScissorEdgesT templated struct that holds compile /// time information about the number of edges needed to be rasterized, /// If either the scissor rect or conservative rast is enabled, /// the scissor test is enabled and the rasterizer will test /// 3 triangle edges + 4 scissor edges for coverage. /// @tparam RasterScissorEdgesT: number of multisamples /// @tparam ConservativeT: is this a conservative rasterization /// @tparam EdgeMaskT: Which edges are valid(not degenerate) template struct RasterEdgeTraits { typedef std::true_type RasterizeScissorEdgesT; typedef std::integral_constant NumEdgesT; // typedef std::integral_constant ValidEdgeMaskT; typedef typename EdgeMaskVal::T ValidEdgeMaskT; }; ////////////////////////////////////////////////////////////////////////// /// @brief specialization of RasterEdgeTraits. If neither scissor rect /// nor conservative rast is enabled, only test 3 triangle edges /// for coverage template struct RasterEdgeTraits { typedef std::false_type RasterizeScissorEdgesT; typedef std::integral_constant NumEdgesT; // no need for degenerate edge masking in non-conservative case; rasterize all triangle edges typedef std::integral_constant ValidEdgeMaskT; }; ////////////////////////////////////////////////////////////////////////// /// @struct RasterizerTraits /// @brief templated struct that holds compile time information used /// during rasterization. Inherits EdgeTraits and ConservativeRastBETraits. /// @tparam NumSamplesT: number of multisamples /// @tparam ConservativeT: is this a conservative rasterization /// @tparam InputCoverageT: what type of input coverage is the PS expecting? /// (only used with conservative rasterization) /// @tparam RasterScissorEdgesT: do we need to rasterize with a scissor? template struct _RasterizerTraits : public ConservativeRastBETraits, public RasterEdgeTraits { typedef MultisampleTraits(NumSamplesT::value), CenterPatternT::value> MT; /// Fixed point precision the rasterizer is using typedef FixedPointTraits PrecisionT; /// Fixed point precision of the edge tests used during rasterization typedef FixedPointTraits EdgePrecisionT; // If conservative rast or MSAA center pattern is enabled, only need a single sample coverage // test, with the result copied to all samples typedef std::integral_constant NumCoverageSamplesT; static_assert( EdgePrecisionT::BitsT::value >= ConservativeRastBETraits::ConservativePrecisionT::BitsT::value, "Rasterizer edge fixed point precision < required conservative rast precision"); /// constants used to offset between different types of raster tiles static const int colorRasterTileStep{ (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits::bpp / 8)) * MT::numSamples}; static const int depthRasterTileStep{ (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits::bpp / 8)) * MT::numSamples}; static const int stencilRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits::bpp / 8)) * MT::numSamples}; static const int colorRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) * colorRasterTileStep}; static const int depthRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) * depthRasterTileStep}; static const int stencilRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) * stencilRasterTileStep}; }; template struct RasterizerTraits final : public _RasterizerTraits, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant, std::integral_constant> { };