/****************************************************************************
|
* 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 <type_traits>
|
#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<uint32_t, ALL_EDGES_VALID> AllEdgesValidT;
|
typedef std::integral_constant<uint32_t, E0_E1_VALID> E0E1ValidT;
|
typedef std::integral_constant<uint32_t, E0_E2_VALID> E0E2ValidT;
|
typedef std::integral_constant<uint32_t, E1_E2_VALID> E1E2ValidT;
|
typedef std::integral_constant<uint32_t, NO_VALID_EDGES> NoEdgesValidT;
|
|
typedef std::integral_constant<uint32_t, STATE_ALL_EDGES_VALID> StateAllEdgesValidT;
|
typedef std::integral_constant<uint32_t, STATE_E0_E1_VALID> StateE0E1ValidT;
|
typedef std::integral_constant<uint32_t, STATE_E0_E2_VALID> StateE0E2ValidT;
|
typedef std::integral_constant<uint32_t, STATE_E1_E2_VALID> StateE1E2ValidT;
|
typedef std::integral_constant<uint32_t, STATE_NO_VALID_EDGES> StateNoEdgesValidT;
|
|
// some specializations to convert from edge state to edge bitmask values
|
template <typename EdgeMask>
|
struct EdgeMaskVal
|
{
|
static_assert(EdgeMask::value > STATE_ALL_EDGES_VALID, "Primary EdgeMaskVal shouldn't be instantiated");
|
};
|
|
template <>
|
struct EdgeMaskVal<StateAllEdgesValidT>
|
{
|
typedef AllEdgesValidT T;
|
};
|
|
template <>
|
struct EdgeMaskVal<StateE0E1ValidT>
|
{
|
typedef E0E1ValidT T;
|
};
|
|
template <>
|
struct EdgeMaskVal<StateE0E2ValidT>
|
{
|
typedef E0E2ValidT T;
|
};
|
|
template <>
|
struct EdgeMaskVal<StateE1E2ValidT>
|
{
|
typedef E1E2ValidT T;
|
};
|
|
template <>
|
struct EdgeMaskVal<StateNoEdgesValidT>
|
{
|
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 <typename RasterScissorEdgesT, typename ConservativeT, typename EdgeMaskT>
|
struct RasterEdgeTraits
|
{
|
typedef std::true_type RasterizeScissorEdgesT;
|
typedef std::integral_constant<uint32_t, 7> NumEdgesT;
|
//typedef std::integral_constant<uint32_t, EdgeMaskT::value> ValidEdgeMaskT;
|
typedef typename EdgeMaskVal<EdgeMaskT>::T ValidEdgeMaskT;
|
};
|
|
//////////////////////////////////////////////////////////////////////////
|
/// @brief specialization of RasterEdgeTraits. If neither scissor rect
|
/// nor conservative rast is enabled, only test 3 triangle edges
|
/// for coverage
|
template <typename EdgeMaskT>
|
struct RasterEdgeTraits<std::false_type, std::false_type, EdgeMaskT>
|
{
|
typedef std::false_type RasterizeScissorEdgesT;
|
typedef std::integral_constant<uint32_t, 3> NumEdgesT;
|
// no need for degenerate edge masking in non-conservative case; rasterize all triangle edges
|
typedef std::integral_constant<uint32_t, ALL_EDGES_VALID> 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 <typename NumSamplesT, typename CenterPatternT, typename ConservativeT, typename InputCoverageT, typename EdgeEnableT, typename RasterScissorEdgesT>
|
struct _RasterizerTraits : public ConservativeRastBETraits<ConservativeT, InputCoverageT>,
|
public RasterEdgeTraits<RasterScissorEdgesT, ConservativeT, EdgeEnableT>
|
{
|
typedef MultisampleTraits<static_cast<SWR_MULTISAMPLE_COUNT>(NumSamplesT::value), CenterPatternT::value> MT;
|
|
/// Fixed point precision the rasterizer is using
|
typedef FixedPointTraits<Fixed_16_8> PrecisionT;
|
/// Fixed point precision of the edge tests used during rasterization
|
typedef FixedPointTraits<Fixed_X_16> 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<int, ConservativeT::value ? 1 : MT::numCoverageSamples> NumCoverageSamplesT;
|
|
static_assert(EdgePrecisionT::BitsT::value >= ConservativeRastBETraits<ConservativeT, InputCoverageT>::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<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8)) * MT::numSamples};
|
static const int depthRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8)) * MT::numSamples};
|
static const int stencilRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::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 <uint32_t NumSamplesT, uint32_t CenterPatternT, uint32_t ConservativeT, uint32_t InputCoverageT, uint32_t EdgeEnableT, uint32_t RasterScissorEdgesT>
|
struct RasterizerTraits final : public _RasterizerTraits <
|
std::integral_constant<uint32_t, NumSamplesT>,
|
std::integral_constant<bool, CenterPatternT != 0>,
|
std::integral_constant<bool, ConservativeT != 0>,
|
std::integral_constant<uint32_t, InputCoverageT>,
|
std::integral_constant<uint32_t, EdgeEnableT>,
|
std::integral_constant<bool, RasterScissorEdgesT != 0> >
|
{};
|