diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index d6d987b520..5500f20e06 100755 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -8,7 +8,6 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - #ifndef hifi_gpu_State_h #define hifi_gpu_State_h @@ -23,74 +22,45 @@ // Because some of the fields are bool packed tightly in the State::Cache class // and it s just not good anymore for template T& variable manipulation... #define SET_FIELD(field, defaultValue, value, dest) {\ -dest = value;\ -if (value == defaultValue) {\ - _signature.reset(field);\ -} else {\ - _signature. - // - // State - // libraries/gpu/src/gpu - // - // Created by Sam Gateau on 3/8/2015. - // Copyright 2014 High Fidelity, Inc. - // - // Distributed under the Apache License, Version 2.0. - // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - // -#ifndef hifi_gpu_State_h -#define hifi_gpu_State_h - -#include "Format.h" - -#include -#include -#include -#include - - // Why a macro and not a fancy template you will ask me ? - // Because some of the fields are bool packed tightly in the State::Cache class - // and it s just not good anymore for template T& variable manipulation... -#define SET_FIELD(field, defaultValue, value, dest) {\ -dest = value;\ -if (value == defaultValue) {\ -_signature.reset(field);\ -} else {\ -_signature.set(field);\ -}\ -_stamp++;\ + dest = value;\ + if (value == defaultValue) {\ + _signature.reset(field);\ + } else {\ + _signature.set(field);\ + }\ + _stamp++;\ }\ - + namespace gpu { - + class GPUObject; class State { public: State(); virtual ~State(); - + Stamp getStamp() const { return _stamp; } - + typedef ::gpu::ComparisonFunction ComparisonFunction; - + enum FillMode { FILL_POINT = 0, FILL_LINE, FILL_FACE, - + NUM_FILL_MODES, }; - + enum CullMode { CULL_NONE = 0, CULL_FRONT, CULL_BACK, - + NUM_CULL_MODES, }; - + enum StencilOp { STENCIL_OP_KEEP = 0, STENCIL_OP_ZERO, @@ -100,10 +70,10 @@ public: STENCIL_OP_INVERT, STENCIL_OP_INCR, STENCIL_OP_DECR, - + NUM_STENCIL_OPS, }; - + enum BlendArg { ZERO = 0, ONE, @@ -120,20 +90,20 @@ public: INV_FACTOR_COLOR, FACTOR_ALPHA, INV_FACTOR_ALPHA, - + NUM_BLEND_ARGS, }; - + enum BlendOp { BLEND_OP_ADD = 0, BLEND_OP_SUBTRACT, BLEND_OP_REV_SUBTRACT, BLEND_OP_MIN, BLEND_OP_MAX, - + NUM_BLEND_OPS, }; - + enum ColorMask { WRITE_NONE = 0, @@ -143,7 +113,7 @@ public: WRITE_ALPHA = 8, WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ), }; - + class DepthTest { uint8 _function = LESS; uint8 _writeMask = true; @@ -151,19 +121,19 @@ public: uint8 _spare = 0; public: DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) : - _function(func), _writeMask(writeMask), _enabled(enabled) {} - + _function(func), _writeMask(writeMask), _enabled(enabled) {} + bool isEnabled() const { return _enabled != 0; } ComparisonFunction getFunction() const { return ComparisonFunction(_function); } uint8 getWriteMask() const { return _writeMask; } - + int32 getRaw() const { return *(reinterpret_cast(this)); } DepthTest(int32 raw) { *(reinterpret_cast(this)) = raw; } bool operator== (const DepthTest& right) const { return getRaw() == right.getRaw(); } bool operator!= (const DepthTest& right) const { return getRaw() != right.getRaw(); } - }; - - class StencilTest { + }; + + class StencilTest { static const int FUNC_MASK = 0x000f; static const int FAIL_OP_MASK = 0x00f0; static const int DEPTH_FAIL_OP_MASK = 0x0f00; @@ -171,169 +141,169 @@ public: static const int FAIL_OP_OFFSET = 4; static const int DEPTH_FAIL_OP_OFFSET = 8; static const int PASS_OP_OFFSET = 12; - + uint16 _functionAndOperations; uint8 _reference = 0; uint8 _readMask = 0xff; - public: - + public: + StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : - _functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)), - _reference(reference), _readMask(readMask) - {} - + _functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)), + _reference(reference), _readMask(readMask) + {} + ComparisonFunction getFunction() const { return ComparisonFunction(_functionAndOperations & FUNC_MASK); } StencilOp getFailOp() const { return StencilOp((_functionAndOperations & FAIL_OP_MASK) >> FAIL_OP_OFFSET); } StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); } StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); } - + uint8 getReference() const { return _reference; } uint8 getReadMask() const { return _readMask; } - + int32 getRaw() const { return *(reinterpret_cast(this)); } StencilTest(int32 raw) { *(reinterpret_cast(this)) = raw; } bool operator== (const StencilTest& right) const { return getRaw() == right.getRaw(); } bool operator!= (const StencilTest& right) const { return getRaw() != right.getRaw(); } - }; - - class StencilActivation { + }; + + class StencilActivation { uint8 _frontWriteMask = 0xFF; uint8 _backWriteMask = 0xFF; uint16 _enabled = 0; - public: - + public: + StencilActivation(bool enabled, uint8 frontWriteMask = 0xFF, uint8 backWriteMask = 0xFF) : - _frontWriteMask(frontWriteMask), _backWriteMask(backWriteMask), _enabled(enabled) {} - + _frontWriteMask(frontWriteMask), _backWriteMask(backWriteMask), _enabled(enabled) {} + bool isEnabled() const { return (_enabled != 0); } uint8 getWriteMaskFront() const { return _frontWriteMask; } uint8 getWriteMaskBack() const { return _backWriteMask; } - + int32 getRaw() const { return *(reinterpret_cast(this)); } StencilActivation(int32 raw) { *(reinterpret_cast(this)) = raw; } bool operator== (const StencilActivation& right) const { return getRaw() == right.getRaw(); } bool operator!= (const StencilActivation& right) const { return getRaw() != right.getRaw(); } }; - + class BlendFunction { static const int COLOR_MASK = 0x0f; static const int ALPHA_MASK = 0xf0; static const int ALPHA_OFFSET = 4; - + uint8 _enabled; uint8 _source; uint8 _destination; uint8 _operation; public: - + BlendFunction(bool enabled, - BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, - BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) : - _enabled(enabled), - _source(sourceColor | (sourceAlpha << ALPHA_OFFSET)), - _destination(destinationColor | (destinationAlpha << ALPHA_OFFSET)), - _operation(operationColor | (operationAlpha << ALPHA_OFFSET)) {} - + BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, + BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) : + _enabled(enabled), + _source(sourceColor | (sourceAlpha << ALPHA_OFFSET)), + _destination(destinationColor | (destinationAlpha << ALPHA_OFFSET)), + _operation(operationColor | (operationAlpha << ALPHA_OFFSET)) {} + BlendFunction(bool enabled, BlendArg source = ONE, BlendOp operation = BLEND_OP_ADD, BlendArg destination = ZERO) : - _enabled(enabled), - _source(source | (source << ALPHA_OFFSET)), - _destination(destination | (destination << ALPHA_OFFSET)), - _operation(operation | (operation << ALPHA_OFFSET)) {} - + _enabled(enabled), + _source(source | (source << ALPHA_OFFSET)), + _destination(destination | (destination << ALPHA_OFFSET)), + _operation(operation | (operation << ALPHA_OFFSET)) {} + bool isEnabled() const { return (_enabled != 0); } - + BlendArg getSourceColor() const { return BlendArg(_source & COLOR_MASK); } BlendArg getDestinationColor() const { return BlendArg(_destination & COLOR_MASK); } BlendOp getOperationColor() const { return BlendOp(_operation & COLOR_MASK); } - + BlendArg getSourceAlpha() const { return BlendArg((_source & ALPHA_MASK) >> ALPHA_OFFSET); } BlendArg getDestinationAlpha() const { return BlendArg((_destination & ALPHA_MASK) >> ALPHA_OFFSET); } BlendOp getOperationAlpha() const { return BlendOp((_operation & ALPHA_MASK) >> ALPHA_OFFSET); } - + int32 getRaw() const { return *(reinterpret_cast(this)); } BlendFunction(int32 raw) { *(reinterpret_cast(this)) = raw; } bool operator== (const BlendFunction& right) const { return getRaw() == right.getRaw(); } bool operator!= (const BlendFunction& right) const { return getRaw() != right.getRaw(); } }; - + // The Data class is the full explicit description of the State class fields value. // Useful for having one const static called Default for reference or for the gpu::Backend to keep track of the current value class Data { public: float depthBias = 0.0f; float depthBiasSlopeScale = 0.0f; - + DepthTest depthTest = DepthTest(false, true, LESS); - + StencilActivation stencilActivation = StencilActivation(false); StencilTest stencilTestFront = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP); StencilTest stencilTestBack = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP); - + uint32 sampleMask = 0xFFFFFFFF; - + BlendFunction blendFunction = BlendFunction(false); - + uint8 fillMode = FILL_FACE; uint8 cullMode = CULL_NONE; - + uint8 colorWriteMask = WRITE_ALL; - + bool frontFaceClockwise : 1; bool depthClampEnable : 1; bool scissorEnable : 1; bool multisampleEnable : 1; bool antialisedLineEnable : 1; bool alphaToCoverageEnable : 1; - + Data() : - frontFaceClockwise(false), - depthClampEnable(false), - scissorEnable(false), - multisampleEnable(false), - antialisedLineEnable(true), - alphaToCoverageEnable(false) + frontFaceClockwise(false), + depthClampEnable(false), + scissorEnable(false), + multisampleEnable(false), + antialisedLineEnable(true), + alphaToCoverageEnable(false) {} }; - + // The unique default values for all the fields static const Data DEFAULT; void setFillMode(FillMode fill) { SET_FIELD(FILL_MODE, DEFAULT.fillMode, fill, _values.fillMode); } FillMode getFillMode() const { return FillMode(_values.fillMode); } - + void setCullMode(CullMode cull) { SET_FIELD(CULL_MODE, DEFAULT.cullMode, cull, _values.cullMode); } CullMode getCullMode() const { return CullMode(_values.cullMode); } - + void setFrontFaceClockwise(bool isClockwise) { SET_FIELD(FRONT_FACE_CLOCKWISE, DEFAULT.frontFaceClockwise, isClockwise, _values.frontFaceClockwise); } bool isFrontFaceClockwise() const { return _values.frontFaceClockwise; } - + void setDepthClampEnable(bool enable) { SET_FIELD(DEPTH_CLAMP_ENABLE, DEFAULT.depthClampEnable, enable, _values.depthClampEnable); } bool isDepthClampEnable() const { return _values.depthClampEnable; } - + void setScissorEnable(bool enable) { SET_FIELD(SCISSOR_ENABLE, DEFAULT.scissorEnable, enable, _values.scissorEnable); } bool isScissorEnable() const { return _values.scissorEnable; } - + void setMultisampleEnable(bool enable) { SET_FIELD(MULTISAMPLE_ENABLE, DEFAULT.multisampleEnable, enable, _values.multisampleEnable); } bool isMultisampleEnable() const { return _values.multisampleEnable; } - + void setAntialiasedLineEnable(bool enable) { SET_FIELD(ANTIALISED_LINE_ENABLE, DEFAULT.antialisedLineEnable, enable, _values.antialisedLineEnable); } bool isAntialiasedLineEnable() const { return _values.antialisedLineEnable; } - + // Depth Bias void setDepthBias(float bias) { SET_FIELD(DEPTH_BIAS, DEFAULT.depthBias, bias, _values.depthBias); } float getDepthBias() const { return _values.depthBias; } - + void setDepthBiasSlopeScale(float scale) { SET_FIELD(DEPTH_BIAS_SLOPE_SCALE, DEFAULT.depthBiasSlopeScale, scale, _values.depthBiasSlopeScale); } float getDepthBiasSlopeScale() const { return _values.depthBiasSlopeScale; } - + // Depth Test void setDepthTest(DepthTest depthTest) { SET_FIELD(DEPTH_TEST, DEFAULT.depthTest, depthTest, _values.depthTest); } void setDepthTest(bool enable, bool writeMask, ComparisonFunction func) { setDepthTest(DepthTest(enable, writeMask, func)); } DepthTest getDepthTest() const { return _values.depthTest; } - + bool isDepthTestEnabled() const { return getDepthTest().isEnabled(); } uint8 getDepthTestWriteMask() const { return getDepthTest().getWriteMask(); } ComparisonFunction getDepthTestFunc() const { return getDepthTest().getFunction(); } - + // Stencil test void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest, uint8 backWriteMask, StencilTest backTest) { SET_FIELD(STENCIL_ACTIVATION, DEFAULT.stencilActivation, StencilActivation(enabled, frontWriteMask, backWriteMask), _values.stencilActivation); @@ -341,39 +311,39 @@ public: SET_FIELD(STENCIL_TEST_BACK, DEFAULT.stencilTestBack, backTest, _values.stencilTestBack); } void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest) { setStencilTest(enabled, frontWriteMask, frontTest, frontWriteMask, frontTest); } - + StencilActivation getStencilActivation() const { return _values.stencilActivation; } StencilTest getStencilTestFront() const { return _values.stencilTestFront; } StencilTest getStencilTestBack() const { return _values.stencilTestBack; } - + bool isStencilEnabled() const { return getStencilActivation().isEnabled(); } uint8 getStencilWriteMaskFront() const { return getStencilActivation().getWriteMaskFront(); } uint8 getStencilWriteMaskBack() const { return getStencilActivation().getWriteMaskBack(); } - + // Alpha to coverage void setAlphaToCoverageEnable(bool enable) { SET_FIELD(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable, enable, _values.alphaToCoverageEnable); } bool isAlphaToCoverageEnabled() const { return _values.alphaToCoverageEnable; } - + // Sample mask void setSampleMask(uint32 mask) { SET_FIELD(SAMPLE_MASK, DEFAULT.sampleMask, mask, _values.sampleMask); } uint32 getSampleMask() const { return _values.sampleMask; } - + // Blend Function void setBlendFunction(BlendFunction function) { SET_FIELD(BLEND_FUNCTION, DEFAULT.blendFunction, function, _values.blendFunction); } BlendFunction getBlendFunction() const { return _values.blendFunction; } - + void setBlendFunction(bool enabled, BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) { setBlendFunction(BlendFunction(enabled, sourceColor, operationColor, destinationColor, sourceAlpha, operationAlpha, destinationAlpha)); } void setBlendFunction(bool enabled, BlendArg source, BlendOp operation, BlendArg destination) { setBlendFunction(BlendFunction(enabled, source, operation, destination)); } - + bool isBlendEnabled() const { return getBlendFunction().isEnabled(); } - + // Color write mask void setColorWriteMask(uint8 mask) { SET_FIELD(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, mask, _values.colorWriteMask); } void setColorWriteMask(bool red, bool green, bool blue, bool alpha) { uint32 value = ((WRITE_RED * red) | (WRITE_GREEN * green) | (WRITE_BLUE * blue) | (WRITE_ALPHA * alpha)); SET_FIELD(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, value, _values.colorWriteMask); } uint8 getColorWriteMask() const { return _values.colorWriteMask; } - + // All the possible fields enum Field { FILL_MODE, @@ -383,46 +353,46 @@ public: SCISSOR_ENABLE, MULTISAMPLE_ENABLE, ANTIALISED_LINE_ENABLE, - + DEPTH_BIAS, DEPTH_BIAS_SLOPE_SCALE, - + DEPTH_TEST, - + STENCIL_ACTIVATION, STENCIL_TEST_FRONT, STENCIL_TEST_BACK, - + SAMPLE_MASK, ALPHA_TO_COVERAGE_ENABLE, - + BLEND_FUNCTION, - + COLOR_WRITE_MASK, - + NUM_FIELDS, // not a valid field, just the count }; - + // The signature of the state tells which fields of the state are not default // this way during rendering the Backend can compare it's current state and try to minimize the job to do typedef std::bitset Signature; - + Signature getSignature() const { return _signature; } - + static Signature evalSignature(const Data& state); - + // For convenience, create a State from the values directly State(const Data& values); const Data& getValues() const { return _values; } - + protected: State(const State& state); State& operator=(const State& state); - + Data _values; Signature _signature{0}; Stamp _stamp{0}; - + // This shouldn't be used by anything else than the Backend class with the proper casting. mutable GPUObject* _gpuObject = nullptr; void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; } @@ -432,7 +402,7 @@ protected: typedef std::shared_ptr< State > StatePointer; typedef std::vector< StatePointer > States; - + }; - + #endif