You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
296 lines
11 KiB
296 lines
11 KiB
#ifndef _RRRASTERIZER_HPP
|
|
#define _RRRASTERIZER_HPP
|
|
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program Reference Renderer
|
|
* -----------------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Reference rasterizer
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "rrDefs.hpp"
|
|
#include "tcuVector.hpp"
|
|
#include "rrRenderState.hpp"
|
|
#include "rrFragmentPacket.hpp"
|
|
|
|
|
|
namespace rr
|
|
{
|
|
|
|
//! Rasterizer configuration
|
|
enum
|
|
{
|
|
RASTERIZER_MAX_SAMPLES_PER_FRAGMENT = 16
|
|
};
|
|
|
|
//! Get coverage bit value.
|
|
inline deUint64 getCoverageBit (int numSamples, int x, int y, int sampleNdx)
|
|
{
|
|
const int numBits = (int)sizeof(deUint64)*8;
|
|
const int maxSamples = numBits/4;
|
|
DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT);
|
|
DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
|
|
return 1ull << ((x*2 + y)*numSamples + sampleNdx);
|
|
}
|
|
|
|
//! Get all sample bits for fragment
|
|
inline deUint64 getCoverageFragmentSampleBits (int numSamples, int x, int y)
|
|
{
|
|
DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
|
|
const deUint64 fragMask = (1ull << numSamples) - 1;
|
|
return fragMask << (x*2 + y)*numSamples;
|
|
}
|
|
|
|
//! Set bit in coverage mask.
|
|
inline deUint64 setCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx, bool val)
|
|
{
|
|
const deUint64 bit = getCoverageBit(numSamples, x, y, sampleNdx);
|
|
return val ? (mask | bit) : (mask & ~bit);
|
|
}
|
|
|
|
//! Get coverage bit value in mask.
|
|
inline bool getCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx)
|
|
{
|
|
return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0;
|
|
}
|
|
|
|
//! Test if any sample for fragment is live
|
|
inline bool getCoverageAnyFragmentSampleLive (deUint64 mask, int numSamples, int x, int y)
|
|
{
|
|
return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0;
|
|
}
|
|
|
|
//! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)).
|
|
inline int getCoverageOffset (int numSamples, int x, int y)
|
|
{
|
|
return (x*2 + y)*numSamples;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Edge function
|
|
*
|
|
* Edge function can be evaluated for point P (in fixed-point coordinates
|
|
* with SUBPIXEL_BITS fractional part) by computing
|
|
* D = a*Px + b*Py + c
|
|
*
|
|
* D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will
|
|
* be fractional part.
|
|
*
|
|
* a and b are stored with SUBPIXEL_BITS fractional part, while c is stored
|
|
* with SUBPIXEL_BITS*2 fractional bits.
|
|
*//*--------------------------------------------------------------------*/
|
|
struct EdgeFunction
|
|
{
|
|
inline EdgeFunction (void) : a(0), b(0), c(0), inclusive(false) {}
|
|
|
|
deInt64 a;
|
|
deInt64 b;
|
|
deInt64 c;
|
|
bool inclusive; //!< True if edge is inclusive according to fill rules.
|
|
};
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Triangle rasterizer
|
|
*
|
|
* Triangle rasterizer implements following features:
|
|
* - Rasterization using fixed-point coordinates
|
|
* - 1, 4, and 16 -sample rasterization
|
|
* - Depth interpolation
|
|
* - Perspective-correct barycentric computation for interpolation
|
|
* - Visible face determination
|
|
*
|
|
* It does not (and will not) implement following:
|
|
* - Triangle setup
|
|
* - Clipping
|
|
* - Degenerate elimination
|
|
* - Coordinate transformation (inputs are in screen-space)
|
|
* - Culling - logic can be implemented outside by querying visible face
|
|
* - Scissoring (this can be done by controlling viewport rectangle)
|
|
* - Any per-fragment operations
|
|
*//*--------------------------------------------------------------------*/
|
|
class TriangleRasterizer
|
|
{
|
|
public:
|
|
TriangleRasterizer (const tcu::IVec4& viewport, const int numSamples, const RasterizationState& state, const int suppixelBits);
|
|
|
|
void init (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2);
|
|
|
|
// Following functions are only available after init()
|
|
FaceType getVisibleFace (void) const { return m_face; }
|
|
void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
|
|
|
|
private:
|
|
void rasterizeSingleSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
|
|
|
|
template<int NumSamples>
|
|
void rasterizeMultiSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
|
|
|
|
// Constant rasterization state.
|
|
const tcu::IVec4 m_viewport;
|
|
const int m_numSamples;
|
|
const Winding m_winding;
|
|
const HorizontalFill m_horizontalFill;
|
|
const VerticalFill m_verticalFill;
|
|
const int m_subpixelBits;
|
|
|
|
// Per-triangle rasterization state.
|
|
tcu::Vec4 m_v0;
|
|
tcu::Vec4 m_v1;
|
|
tcu::Vec4 m_v2;
|
|
EdgeFunction m_edge01;
|
|
EdgeFunction m_edge12;
|
|
EdgeFunction m_edge20;
|
|
FaceType m_face; //!< Triangle orientation, eg. visible face.
|
|
tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
|
|
tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
|
|
tcu::IVec2 m_curPos; //!< Current rasterization position.
|
|
ViewportOrientation m_viewportOrientation; //!< Direction of +x+y axis
|
|
} DE_WARN_UNUSED_TYPE;
|
|
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Single sample line rasterizer
|
|
*
|
|
* Line rasterizer implements following features:
|
|
* - Rasterization using fixed-point coordinates
|
|
* - Depth interpolation
|
|
* - Perspective-correct interpolation
|
|
*
|
|
* It does not (and will not) implement following:
|
|
* - Clipping
|
|
* - Multisampled line rasterization
|
|
*//*--------------------------------------------------------------------*/
|
|
class SingleSampleLineRasterizer
|
|
{
|
|
public:
|
|
SingleSampleLineRasterizer (const tcu::IVec4& viewport, const int subpixelBits);
|
|
~SingleSampleLineRasterizer (void);
|
|
|
|
void init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth, deUint32 stippleFactor, deUint16 stipplePattern);
|
|
|
|
// only available after init()
|
|
void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
|
|
|
|
void resetStipple () { m_stippleCounter = 0; }
|
|
|
|
private:
|
|
SingleSampleLineRasterizer (const SingleSampleLineRasterizer&); // not allowed
|
|
SingleSampleLineRasterizer& operator= (const SingleSampleLineRasterizer&); // not allowed
|
|
|
|
// Constant rasterization state.
|
|
const tcu::IVec4 m_viewport;
|
|
const int m_subpixelBits;
|
|
|
|
// Per-line rasterization state.
|
|
tcu::Vec4 m_v0;
|
|
tcu::Vec4 m_v1;
|
|
tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
|
|
tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
|
|
tcu::IVec2 m_curPos; //!< Current rasterization position.
|
|
deInt32 m_curRowFragment; //!< Current rasterization position of one fragment in column of lineWidth fragments
|
|
float m_lineWidth;
|
|
deUint32 m_stippleFactor;
|
|
deUint16 m_stipplePattern;
|
|
deUint32 m_stippleCounter;
|
|
} DE_WARN_UNUSED_TYPE;
|
|
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Multisampled line rasterizer
|
|
*
|
|
* Line rasterizer implements following features:
|
|
* - Rasterization using fixed-point coordinates
|
|
* - Depth interpolation
|
|
* - Perspective-correct interpolation
|
|
*
|
|
* It does not (and will not) implement following:
|
|
* - Clipping
|
|
* - Aliased line rasterization
|
|
*//*--------------------------------------------------------------------*/
|
|
class MultiSampleLineRasterizer
|
|
{
|
|
public:
|
|
MultiSampleLineRasterizer (const int numSamples, const tcu::IVec4& viewport, const int subpixelBits);
|
|
~MultiSampleLineRasterizer ();
|
|
|
|
void init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
|
|
|
|
// only available after init()
|
|
void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
|
|
|
|
private:
|
|
MultiSampleLineRasterizer (const MultiSampleLineRasterizer&); // not allowed
|
|
MultiSampleLineRasterizer& operator= (const MultiSampleLineRasterizer&); // not allowed
|
|
|
|
// Constant rasterization state.
|
|
const int m_numSamples;
|
|
|
|
// Per-line rasterization state.
|
|
TriangleRasterizer m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
|
|
TriangleRasterizer m_triangleRasterizer1;
|
|
} DE_WARN_UNUSED_TYPE;
|
|
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Pixel diamond
|
|
*
|
|
* Structure representing a diamond a line exits.
|
|
*//*--------------------------------------------------------------------*/
|
|
struct LineExitDiamond
|
|
{
|
|
tcu::IVec2 position;
|
|
};
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Line exit diamond generator
|
|
*
|
|
* For a given line, generates list of diamonds the line exits using the
|
|
* line-exit rules of the line rasterization. Does not do scissoring.
|
|
*
|
|
* \note Not used by rr, but provided to prevent test cases requiring
|
|
* accurate diamonds from abusing SingleSampleLineRasterizer.
|
|
*//*--------------------------------------------------------------------*/
|
|
class LineExitDiamondGenerator
|
|
{
|
|
public:
|
|
LineExitDiamondGenerator (const int subpixelBits);
|
|
~LineExitDiamondGenerator (void);
|
|
|
|
void init (const tcu::Vec4& v0, const tcu::Vec4& v1);
|
|
|
|
// only available after init()
|
|
void rasterize (LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten);
|
|
|
|
private:
|
|
LineExitDiamondGenerator (const LineExitDiamondGenerator&); // not allowed
|
|
LineExitDiamondGenerator& operator= (const LineExitDiamondGenerator&); // not allowed
|
|
|
|
const int m_subpixelBits;
|
|
|
|
// Per-line rasterization state.
|
|
tcu::Vec4 m_v0;
|
|
tcu::Vec4 m_v1;
|
|
tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
|
|
tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
|
|
tcu::IVec2 m_curPos; //!< Current rasterization position.
|
|
};
|
|
|
|
} // rr
|
|
|
|
#endif // _RRRASTERIZER_HPP
|