void TexRegionRender::Render( DeviceContextGLImpl *pCtxGL, ITextureView *pSrcSRV, RESOURCE_DIMENSION TexType, TEXTURE_FORMAT TexFormat, Int32 DstToSrcXOffset, Int32 DstToSrcYOffset, Int32 SrcZ, Int32 SrcMipLevel) { { MapHelper< int > pConstant( pCtxGL, m_pConstantBuffer, MAP_WRITE_DISCARD, 0 ); pConstant[0] = DstToSrcXOffset; pConstant[1] = DstToSrcYOffset; pConstant[2] = SrcZ; pConstant[3] = SrcMipLevel; } const auto &TexFmtAttribs = GetTextureFormatAttribs(TexFormat); Uint32 FSInd = TexType * 3; if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SINT ) FSInd += 1; else if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_UINT ) FSInd += 2; if( TexFmtAttribs.ComponentType == COMPONENT_TYPE_SNORM ) { LOG_WARNING_MESSAGE("CopyData() is performed by rendering to texture.\n" "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.") } pCtxGL->SetPipelineState(m_pPSO[FSInd]); auto SrcTexVar = m_pFragmentShaders[FSInd]->GetShaderVariable( "gSourceTex" ); SrcTexVar->Set( pSrcSRV ); DrawAttribs DrawAttrs; DrawAttrs.NumVertices = 4; DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; pCtxGL->Draw( DrawAttrs ); SrcTexVar->Set( nullptr ); }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement *pBsonElement, const intrusive_ptr<ExpressionContext> &pCtx) { uassert(15947, "a group's fields must be specified in an object", pBsonElement->type() == Object); intrusive_ptr<DocumentSourceGroup> pGroup( DocumentSourceGroup::create(pCtx)); bool idSet = false; BSONObj groupObj(pBsonElement->Obj()); BSONObjIterator groupIterator(groupObj); while(groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char *pFieldName = groupField.fieldName(); if (strcmp(pFieldName, Document::idName.c_str()) == 0) { uassert(15948, "a group's _id may only be specified once", !idSet); BSONType groupType = groupField.type(); if (groupType == Object) { /* Use the projection-like set of field paths to create the group-by key. */ Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); intrusive_ptr<Expression> pId( Expression::parseObject(&groupField, &oCtx)); pGroup->setIdExpression(pId); idSet = true; } else if (groupType == String) { string groupString(groupField.String()); const char *pGroupString = groupString.c_str(); if ((groupString.length() == 0) || (pGroupString[0] != '$')) goto StringConstantId; string pathString( Expression::removeFieldPrefix(groupString)); intrusive_ptr<ExpressionFieldPath> pFieldPath( ExpressionFieldPath::create(pathString)); pGroup->setIdExpression(pFieldPath); idSet = true; } else { /* pick out the constant types that are allowed */ switch(groupType) { case NumberDouble: case String: case Object: case Array: case jstOID: case Bool: case Date: case NumberInt: case Timestamp: case NumberLong: case jstNULL: StringConstantId: // from string case above { intrusive_ptr<const Value> pValue( Value::createFromBsonElement(&groupField)); intrusive_ptr<ExpressionConstant> pConstant( ExpressionConstant::create(pValue)); pGroup->setIdExpression(pConstant); idSet = true; break; } default: uassert(15949, str::stream() << "a group's _id may not include fields of BSON type " << groupType, false); } } } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ uassert(15950, str::stream() << "the group aggregate field name " << *pFieldName << " cannot be an operator name", *pFieldName != '$'); uassert(15951, str::stream() << "the group aggregate field " << *pFieldName << "must be defined as an expression inside an object", groupField.type() == Object); BSONObj subField(groupField.Obj()); BSONObjIterator subIterator(subField); size_t subCount = 0; for(; subIterator.more(); ++subCount) { BSONElement subElement(subIterator.next()); /* look for the specified operator */ GroupOpDesc key; key.pName = subElement.fieldName(); const GroupOpDesc *pOp = (const GroupOpDesc *)bsearch( &key, GroupOpTable, NGroupOp, sizeof(GroupOpDesc), GroupOpDescCmp); uassert(15952, str::stream() << "unknown group operator \"" << key.pName << "\"", pOp); intrusive_ptr<Expression> pGroupExpr; BSONType elementType = subElement.type(); if (elementType == Object) { Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); pGroupExpr = Expression::parseObject( &subElement, &oCtx); } else if (elementType == Array) { uassert(15953, str::stream() << "aggregating group operators are unary (" << key.pName << ")", false); } else { /* assume its an atomic single operand */ pGroupExpr = Expression::parseOperand(&subElement); } pGroup->addAccumulator( pFieldName, pOp->pFactory, pGroupExpr); } uassert(15954, str::stream() << "the computed aggregate \"" << pFieldName << "\" must specify exactly one operator", subCount == 1); } } uassert(15955, "a group specification must include an _id", idSet); return pGroup; }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement *pBsonElement, const intrusive_ptr<ExpressionContext> &pCtx) { assert(pBsonElement->type() == Object); // CW TODO must be an object intrusive_ptr<DocumentSourceGroup> pGroup( DocumentSourceGroup::create(pCtx)); bool idSet = false; BSONObj groupObj(pBsonElement->Obj()); BSONObjIterator groupIterator(groupObj); while(groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char *pFieldName = groupField.fieldName(); if (strcmp(pFieldName, Document::idName.c_str()) == 0) { assert(!idSet); // CW TODO _id specified multiple times BSONType groupType = groupField.type(); if (groupType == Object) { /* Use the projection-like set of field paths to create the group-by key. */ Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); intrusive_ptr<Expression> pId( Expression::parseObject(&groupField, &oCtx)); pGroup->setIdExpression(pId); idSet = true; } else if (groupType == String) { string groupString(groupField.String()); const char *pGroupString = groupString.c_str(); if ((groupString.length() == 0) || (pGroupString[0] != '$')) goto StringConstantId; string pathString( Expression::removeFieldPrefix(groupString)); intrusive_ptr<ExpressionFieldPath> pFieldPath( ExpressionFieldPath::create(pathString)); pGroup->setIdExpression(pFieldPath); idSet = true; } else { /* pick out the constant types that are allowed */ switch(groupType) { case NumberDouble: case String: case Object: case Array: case jstOID: case Bool: case Date: case NumberInt: case Timestamp: case NumberLong: case jstNULL: StringConstantId: // from string case above { intrusive_ptr<const Value> pValue( Value::createFromBsonElement(&groupField)); intrusive_ptr<ExpressionConstant> pConstant( ExpressionConstant::create(pValue)); pGroup->setIdExpression(pConstant); idSet = true; break; } default: assert(false); // CW TODO disallowed constant group key } } } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ assert(*pFieldName != '$'); // CW TODO error: field name can't be an operator assert(groupField.type() == Object); // CW TODO error: must be an operator expression BSONObj subField(groupField.Obj()); BSONObjIterator subIterator(subField); size_t subCount = 0; for(; subIterator.more(); ++subCount) { BSONElement subElement(subIterator.next()); /* look for the specified operator */ GroupOpDesc key; key.pName = subElement.fieldName(); const GroupOpDesc *pOp = (const GroupOpDesc *)bsearch( &key, GroupOpTable, NGroupOp, sizeof(GroupOpDesc), GroupOpDescCmp); assert(pOp); // CW TODO error: operator not found intrusive_ptr<Expression> pGroupExpr; BSONType elementType = subElement.type(); if (elementType == Object) { Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); pGroupExpr = Expression::parseObject( &subElement, &oCtx); } else if (elementType == Array) { assert(false); // CW TODO group operators are unary } else { /* assume its an atomic single operand */ pGroupExpr = Expression::parseOperand(&subElement); } pGroup->addAccumulator( pFieldName, pOp->pFactory, pGroupExpr); } assert(subCount == 1); // CW TODO error: only one operator allowed } } assert(idSet); // CW TODO error: missing _id specification return pGroup; }