Hash :
a6a7842f
Author :
Date :
2018-06-28T08:32:54
ES31: Support atomic functions on D3D11 - Part I
This patch is the first one of the implementation of atomic
functions in D3D11.
There are mainly two differences in the usage of GLSL and HLSL
atomic functions:
1. All GLSL atomic functions have return values, which all
represent the original value of the shared or ssbo variable;
while all HLSL atomic functions don't, and the original value
can be stored in the last parameter of the function call.
2. For HLSL atomic functions, the last parameter that stores the
original value is optional except for InterlockedExchange and
InterlockedCompareExchange. Missing original_value in the call
of InterlockedExchange and InterlockedCompareExchange results
in a compile error from HLSL compiler.
To handle these differences, we plan to implement the translation
in two steps:
1. Support direct translations from GLSL atomic functions to HLSL
ones.
Direct translation can only handle the following two situations:
(1) The sentence is a GLSL atomic function call without requesting
a return value and it is not atomicExchange or atomicCompSwap:
e.g.
GLSL: atomicAdd(mem, value);
-> HLSL: InterlockedAdd(mem, value);
(2) The sentence is a simple assignment expression: its right is
a GLSL atomic function call and its left is a declared variable.
e.g.
GLSL: oldValue = atomicAdd(mem, value);
-> HLSL: InterlockedAdd(mem, value, oldValue);
2. Support atomic functions in the situations that don't support
direct translations.
We will modify the intermediate tree to make direct translation work
on all these situations.
e.g.
atomicExchange(mem, value);
-> int oldValue;
oldValue = atomicExchange(mem, value);
int oldValue = atomicAdd(mem, value);
-> int oldValue;
oldValue = atomicAdd(mem, value);
return atomicAdd(mem, value);
-> int temp;
temp = atomicAdd(mem, value);
return temp;
for (i = 0; i < atomicAdd(mem, value); ++i)
-> int temp;
temp = atomicAdd(mem, value);
for (i = 0; i < temp; ++i)
{
...
temp = atomicAdd(mem, value);
}
int result = isTrue ? atomicAdd(mem, value) : 0;
-> int result;
if (isTrue)
{
result = atomicAdd(mem, value);
}
else
{
result = 0;
}
This patch completes Step 1 which mainly focus on the translation
from GLSL atomic functions to HLSL ones.
BUG=angleproject:2682
TEST=angle_end2end_tests
Change-Id: I3b655b6e286dad4fd97f255f7fe87521c94db30c
Reviewed-on: https://chromium-review.googlesource.com/1121835
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
//
// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_TRANSLATOR_OPERATOR_H_
#define COMPILER_TRANSLATOR_OPERATOR_H_
//
// Operators used by the high-level (parse tree) representation.
//
enum TOperator
{
EOpNull, // if in a node, should only mean a node is still being built
// Call a function defined in the AST. This might be a user-defined function or a function
// inserted by an AST transformation.
EOpCallFunctionInAST,
// Call an internal helper function with a raw implementation - the implementation can't be
// subject to AST transformations. Raw functions have a few constraints to keep them compatible
// with AST traversers:
// * They should not return arrays.
// * They should not have out parameters.
EOpCallInternalRawFunction,
// Call a built-in function like a texture or image function.
EOpCallBuiltInFunction,
//
// Unary operators
//
EOpNegative,
EOpPositive,
EOpLogicalNot,
EOpBitwiseNot,
EOpPostIncrement,
EOpPostDecrement,
EOpPreIncrement,
EOpPreDecrement,
EOpArrayLength,
//
// binary operations (ones with special GLSL syntax are used in TIntermBinary nodes, others in
// TIntermAggregate nodes)
//
EOpAdd,
EOpSub,
EOpMul,
EOpDiv,
EOpIMod,
EOpEqual,
EOpNotEqual,
EOpLessThan,
EOpGreaterThan,
EOpLessThanEqual,
EOpGreaterThanEqual,
EOpEqualComponentWise,
EOpNotEqualComponentWise,
EOpLessThanComponentWise,
EOpLessThanEqualComponentWise,
EOpGreaterThanComponentWise,
EOpGreaterThanEqualComponentWise,
EOpComma,
EOpVectorTimesScalar,
EOpVectorTimesMatrix,
EOpMatrixTimesVector,
EOpMatrixTimesScalar,
EOpMatrixTimesMatrix,
EOpLogicalOr,
EOpLogicalXor,
EOpLogicalAnd,
EOpBitShiftLeft,
EOpBitShiftRight,
EOpBitwiseAnd,
EOpBitwiseXor,
EOpBitwiseOr,
EOpIndexDirect,
EOpIndexIndirect,
EOpIndexDirectStruct,
EOpIndexDirectInterfaceBlock,
//
// Built-in functions mapped to operators (either unary or with multiple parameters)
//
EOpRadians,
EOpDegrees,
EOpSin,
EOpCos,
EOpTan,
EOpAsin,
EOpAcos,
EOpAtan,
EOpSinh,
EOpCosh,
EOpTanh,
EOpAsinh,
EOpAcosh,
EOpAtanh,
EOpPow,
EOpExp,
EOpLog,
EOpExp2,
EOpLog2,
EOpSqrt,
EOpInversesqrt,
EOpAbs,
EOpSign,
EOpFloor,
EOpTrunc,
EOpRound,
EOpRoundEven,
EOpCeil,
EOpFract,
EOpMod,
EOpModf,
EOpMin,
EOpMax,
EOpClamp,
EOpMix,
EOpStep,
EOpSmoothstep,
EOpIsnan,
EOpIsinf,
EOpFloatBitsToInt,
EOpFloatBitsToUint,
EOpIntBitsToFloat,
EOpUintBitsToFloat,
EOpFrexp,
EOpLdexp,
EOpPackSnorm2x16,
EOpPackUnorm2x16,
EOpPackHalf2x16,
EOpUnpackSnorm2x16,
EOpUnpackUnorm2x16,
EOpUnpackHalf2x16,
EOpPackUnorm4x8,
EOpPackSnorm4x8,
EOpUnpackUnorm4x8,
EOpUnpackSnorm4x8,
EOpLength,
EOpDistance,
EOpDot,
EOpCross,
EOpNormalize,
EOpFaceforward,
EOpReflect,
EOpRefract,
EOpDFdx, // Fragment only, OES_standard_derivatives extension
EOpDFdy, // Fragment only, OES_standard_derivatives extension
EOpFwidth, // Fragment only, OES_standard_derivatives extension
EOpMulMatrixComponentWise,
EOpOuterProduct,
EOpTranspose,
EOpDeterminant,
EOpInverse,
EOpAny,
EOpAll,
EOpLogicalNotComponentWise,
EOpBitfieldExtract,
EOpBitfieldInsert,
EOpBitfieldReverse,
EOpBitCount,
EOpFindLSB,
EOpFindMSB,
EOpUaddCarry,
EOpUsubBorrow,
EOpUmulExtended,
EOpImulExtended,
//
// Branch
//
EOpKill, // Fragment only
EOpReturn,
EOpBreak,
EOpContinue,
//
// Constructor
//
EOpConstruct,
//
// moves
//
EOpAssign,
EOpInitialize,
EOpAddAssign,
EOpSubAssign,
EOpMulAssign,
EOpVectorTimesMatrixAssign,
EOpVectorTimesScalarAssign,
EOpMatrixTimesScalarAssign,
EOpMatrixTimesMatrixAssign,
EOpDivAssign,
EOpIModAssign,
EOpBitShiftLeftAssign,
EOpBitShiftRightAssign,
EOpBitwiseAndAssign,
EOpBitwiseXorAssign,
EOpBitwiseOrAssign,
// barriers
EOpBarrier,
EOpMemoryBarrier,
EOpMemoryBarrierAtomicCounter,
EOpMemoryBarrierBuffer,
EOpMemoryBarrierImage,
EOpMemoryBarrierShared,
EOpGroupMemoryBarrier,
// Atomic functions
EOpAtomicAdd,
EOpAtomicMin,
EOpAtomicMax,
EOpAtomicAnd,
EOpAtomicOr,
EOpAtomicXor,
EOpAtomicExchange,
EOpAtomicCompSwap,
// Geometry only
EOpEmitVertex,
EOpEndPrimitive
};
// Returns the string corresponding to the operator in GLSL
const char *GetOperatorString(TOperator op);
// Say whether or not a binary or unary operation changes the value of a variable.
bool IsAssignment(TOperator op);
// Say whether or not an operator represents an atomic function.
bool IsAtomicFunction(TOperator op);
#endif // COMPILER_TRANSLATOR_OPERATOR_H_