void ExternalInputSource::insertChar(Char ch) { if (start() > buf_) { if (cur() > start()) memmove((Char *)start() - 1, start(), (cur() - start())*sizeof(Char)); moveLeft(); *(Char *)cur() = ch; } else { // must have start == buf if (buf_ + (bufSize_ - (nLeftOver_ + sizeof(Char) - 1)/sizeof(Char)) == bufLim_) { if (bufSize_ == size_t(-1)) abort(); // FIXME throw an exception reallocateBuffer(bufSize_ + 1); } else if (nLeftOver_ > 0 && ((char *)(bufLim_ + 1) > leftOver_)) { char *s = (char *)(buf_ + bufSize_) - nLeftOver_; memmove(s, leftOver_, nLeftOver_); leftOver_ = s; } if (cur() < bufLim_) memmove((Char *)cur() + 1, cur(), (bufLim_ - cur())*sizeof(Char)); *(Char *)cur() = ch; advanceEnd(end() + 1); bufLim_ += 1; } }
void ChainResampler::adjustRate(const long inRate, const long outRate) { unsigned long mul, div; exactRatio(mul, div); bigSinc->adjustDiv(static_cast<int>(static_cast<double>(inRate) * mul / (static_cast<double>(div / bigSinc->div()) * outRate) + 0.5)); reallocateBuffer(); setRate(inRate, outRate); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void GLRenderToVertexBuffer::update(SceneManager* sceneMgr) { checkGLError(true, false, "start of GLRenderToVertexBuffer::update"); size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) { //Buffers don't match. Need to reallocate. mResetRequested = true; } //Single pass only for now Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); //Set pass before binding buffers to activate the GPU programs sceneMgr->_setPass(r2vbPass); checkGLError(true, false); bindVerticesOutput(r2vbPass); RenderOperation renderOp; size_t targetBufferIndex; if (mResetRequested || mResetsEveryUpdate) { //Use source data to render to first buffer mSourceRenderable->getRenderOperation(renderOp); targetBufferIndex = 0; } else { //Use current front buffer to render to back buffer this->getRenderOperation(renderOp); targetBufferIndex = 1 - mFrontBufferIndex; } if (mVertexBuffers[targetBufferIndex].isNull() || mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) { reallocateBuffer(targetBufferIndex); } GLHardwareVertexBuffer* vertexBuffer = static_cast<GLHardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].getPointer()); GLuint bufferId = vertexBuffer->getGLBufferId(); //Bind the target buffer glBindBufferOffsetNV(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 0, bufferId, 0); glBeginTransformFeedbackNV(getR2VBPrimitiveType(mOperationType)); glEnable(GL_RASTERIZER_DISCARD_NV); // disable rasterization glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV, mPrimitivesDrawnQuery); RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); //Draw the object targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } targetRenderSystem->_render(renderOp); //Finish the query glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV); glDisable(GL_RASTERIZER_DISCARD_NV); glEndTransformFeedbackNV(); //read back query results GLuint primitivesWritten; glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten); mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); checkGLError(true, true, "GLRenderToVertexBuffer::update"); //Switch the vertex binding if neccesary if (targetBufferIndex != mFrontBufferIndex) { mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); mFrontBufferIndex = targetBufferIndex; } glDisable(GL_RASTERIZER_DISCARD_NV); // enable rasterization //Clear the reset flag mResetRequested = false; }
Xchar ExternalInputSource::fill(Messenger &mgr) { ASSERT(cur() == end()); while (end() >= bufLim_) { // need more data while (so_ == 0) { if (soIndex_ >= sov_.size()) return eE; if (soIndex_ > 0) info_->noteStorageObjectEnd(bufLimOffset_ - (bufLim_ - end())); const StorageObjectSpec &spec = info_->spec(soIndex_); if (mayNotExist_) { NullMessenger nullMgr; sov_[soIndex_] = spec.storageManager->makeStorageObject(spec.specId, spec.baseId, spec.search, mayRewind_, nullMgr, info_->id(soIndex_)); } else sov_[soIndex_] = spec.storageManager->makeStorageObject(spec.specId, spec.baseId, spec.search, mayRewind_, mgr, info_->id(soIndex_)); so_ = sov_[soIndex_].pointer(); if (so_) { decoder_ = spec.codingSystem->makeDecoder(); info_->setDecoder(soIndex_, decoder_); zapEof_ = spec.zapEof; switch (spec.records) { case StorageObjectSpec::asis: recordType_ = asis; insertRS_ = false; break; case StorageObjectSpec::cr: recordType_ = cr; break; case StorageObjectSpec::lf: recordType_ = lf; break; case StorageObjectSpec::crlf: recordType_ = crlf; break; case StorageObjectSpec::find: recordType_ = unknown; break; default: CANNOT_HAPPEN(); } soIndex_++; readSize_ = so_->getBlockSize(); nLeftOver_ = 0; break; } else setAccessError(); soIndex_++; } size_t keepSize = end() - start(); const size_t align = sizeof(int)/sizeof(Char); size_t readSizeChars = (readSize_ + (sizeof(Char) - 1))/sizeof(Char); readSizeChars = roundUp(readSizeChars, align); size_t neededSize; // in Chars size_t startOffset; // compute neededSize and readSize unsigned minBytesPerChar = decoder_->minBytesPerChar(); if (nLeftOver_ == 0 && minBytesPerChar >= sizeof(Char)) { // In this case we want to do decoding in place. // FIXME It might be a win on some systems (Irix?) to arrange that the // read buffer is on a page boundary. if (keepSize >= size_t(-1)/sizeof(Char) - (align - 1) - insertRS_) abort(); // FIXME throw an exception // Now size_t(-1)/sizeof(Char) - (align - 1) - insertRS_ - keepSize > 0 if (readSizeChars > size_t(-1)/sizeof(Char) - (align - 1) - insertRS_ - keepSize) abort(); neededSize = roundUp(readSizeChars + keepSize + insertRS_, align); startOffset = ((neededSize > bufSize_ ? neededSize : bufSize_) - readSizeChars - insertRS_ - keepSize); } else { // Needs to be room for everything before decoding. neededSize = (keepSize + insertRS_ + readSizeChars + (nLeftOver_ + sizeof(Char) - 1)/sizeof(Char)); // Also must be room for everything after decoding. size_t neededSize2 = (keepSize + insertRS_ // all the converted characters + (nLeftOver_ + readSize_)/minBytesPerChar // enough Chars to contain left over bytes + ((readSize_ % minBytesPerChar + sizeof(Char) - 1) / sizeof(Char))); if (neededSize2 > neededSize) neededSize = neededSize2; neededSize = roundUp(neededSize, align); if (neededSize > size_t(-1)/sizeof(Char)) abort(); startOffset = 0; } if (bufSize_ < neededSize) reallocateBuffer(neededSize); Char *newStart = buf_ + startOffset; if (newStart != start() && keepSize > 0) memmove(newStart, start(), keepSize*sizeof(Char)); char *bytesStart = (char *)(buf_ + bufSize_ - readSizeChars) - nLeftOver_; if (nLeftOver_ > 0 && leftOver_ != bytesStart) memmove(bytesStart, leftOver_, nLeftOver_); moveStart(newStart); bufLim_ = end(); size_t nread; if (so_->read((char *)(buf_ + bufSize_ - readSizeChars), readSize_, mgr, nread)) { if (nread > 0) { const char *bytesEnd = bytesStart + nLeftOver_ + nread; size_t nChars = decoder_->decode((Char *)end() + insertRS_, bytesStart, nLeftOver_ + nread - (zapEof_ && bytesEnd[-1] == EOFCHAR), &leftOver_); nLeftOver_ = bytesEnd - leftOver_; if (nChars > 0) { if (insertRS_) { noteRS(); *(Char *)end() = RS; advanceEnd(end() + 1); insertRS_ = false; bufLim_ += 1; bufLimOffset_ += 1; } bufLim_ += nChars; bufLimOffset_ += nChars; break; } } } else so_ = 0; } ASSERT(end() < bufLim_); if (insertRS_) { noteRS(); insertChar(RS); insertRS_ = false; bufLimOffset_ += 1; } switch (recordType_) { case unknown: { const Char *e = findNextCrOrLf(end(), bufLim_); if (e) { if (*e == '\n') { recordType_ = lf; info_->noteInsertedRSs(); *(Char *)e = RE; advanceEnd(e + 1); insertRS_ = true; } else { if (e + 1 < bufLim_) { if (e[1] == '\n') { recordType_ = crlf; advanceEnd(e + 1); if (e + 2 == bufLim_) { bufLim_--; bufLimOffset_--; insertRS_ = true; } } else { advanceEnd(e + 1); recordType_ = cr; info_->noteInsertedRSs(); insertRS_ = true; } } else { recordType_ = crUnknown; advanceEnd(e + 1); } } } else advanceEnd(bufLim_); } break; case crUnknown: { if (*cur() == '\n') { noteRS(); advanceEnd(cur() + 1); recordType_ = crlf; } else { advanceEnd(cur() + 1); insertRS_ = true; recordType_ = cr; info_->noteInsertedRSs(); } } break; case lf: { Char *e = (Char *)findNextLf(end(), bufLim_); if (e) { advanceEnd(e + 1); *e = RE; insertRS_ = true; } else advanceEnd(bufLim_); } break; case cr: { const Char *e = findNextCr(end(), bufLim_); if (e) { advanceEnd(e + 1); insertRS_ = true; } else advanceEnd(bufLim_); } break; case crlf: { const Char *e = end(); for (;;) { e = findNextLf(e, bufLim_); if (!e) { advanceEnd(bufLim_); break; } // Need to delete final RS if not followed by anything. if (e + 1 == bufLim_) { bufLim_--; bufLimOffset_--; advanceEnd(e); insertRS_ = true; break; } noteRSAt(e); e++; } } break; case asis: advanceEnd(bufLim_); break; default: CANNOT_HAPPEN(); } return nextChar(); }
void D3D11RenderToVertexBuffer::update(SceneManager* sceneMgr) { //Single pass only for now Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); setupGeometryShaderLinkageToStreamOut(r2vbPass); size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) { //Buffers don't match. Need to reallocate. mResetRequested = true; } //Set pass before binding buffers to activate the GPU programs sceneMgr->_setPass(r2vbPass); RenderOperation renderOp; size_t targetBufferIndex; if (mResetRequested || mResetsEveryUpdate) { //Use source data to render to first buffer mSourceRenderable->getRenderOperation(renderOp); targetBufferIndex = 0; } else { //Use current front buffer to render to back buffer renderOp.operationType = mOperationType; renderOp.useIndexes = false; renderOp.vertexData = mVertexData; targetBufferIndex = 1 - mFrontBufferIndex; } if (mVertexBuffers[targetBufferIndex].isNull() || mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) { reallocateBuffer(targetBufferIndex); } RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); //Draw the object targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); D3D11HardwareVertexBuffer* vertexBuffer = static_cast<D3D11HardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].getPointer()); UINT offset[1] = { 0 }; ID3D11Buffer* iBuffer[1]; iBuffer[0] = vertexBuffer->getD3DVertexBuffer(); mDevice.GetImmediateContext()->SOSetTargets( 1, iBuffer, offset ); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } mDevice.GetImmediateContext()->Begin(mDeviceStatsQuery); targetRenderSystem->_render(renderOp); //Switch the vertex binding if necessary if (targetBufferIndex != mFrontBufferIndex) { mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); mFrontBufferIndex = targetBufferIndex; } ID3D11Buffer* nullBuffer[1]; nullBuffer[0]=NULL; mDevice.GetImmediateContext()->SOSetTargets( 1, nullBuffer, offset ); //Clear the reset flag mResetRequested = false; mDevice.GetImmediateContext()->End(mDeviceStatsQuery); D3D11_QUERY_DATA_PIPELINE_STATISTICS stats; while( S_OK != mDevice.GetImmediateContext()->GetData(mDeviceStatsQuery, &stats, mDeviceStatsQuery->GetDataSize(), 0 ) ){} }
void GL3PlusRenderToVertexBuffer::bindVerticesOutput(Pass* pass) { VertexDeclaration* declaration = mVertexData->vertexDeclaration; size_t elemCount = declaration->getElementCount(); if (elemCount == 0) return; // Get program object ID. GLuint programId = 0; if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLSeparableProgram* separableProgram = GLSLSeparableProgramManager::getSingleton().getCurrentSeparableProgram(); GLSLShader* glslGpuProgram = 0; if ((glslGpuProgram = separableProgram->getGeometryShader())) programId = glslGpuProgram->getGLProgramHandle(); //TODO include tessellation stages else // vertex program programId = separableProgram->getVertexShader()->getGLProgramHandle(); } else { GLSLMonolithicProgram* monolithicProgram = GLSLMonolithicProgramManager::getSingleton().getActiveMonolithicProgram(); programId = monolithicProgram->getGLProgramHandle(); } // Store the output in a buffer. The buffer has the same // structure as the shader output vertex data. // Note: 64 is the minimum number of interleaved // attributes allowed by GL_EXT_transform_feedback so we // are using it. Otherwise we could query during // rendersystem initialisation and use a dynamic sized // array. But that would require C99. size_t sourceBufferIndex = mTargetBufferIndex == 0 ? 1 : 0; // Bind and fill vertex arrays + buffers. reallocateBuffer(sourceBufferIndex); reallocateBuffer(mTargetBufferIndex); // GL3PlusHardwareVertexBuffer* sourceVertexBuffer = static_cast<GL3PlusHardwareVertexBuffer*>(mVertexBuffers[mSourceBufferIndex].getPointer()); // GL3PlusHardwareVertexBuffer* targetVertexBuffer = static_cast<GL3PlusHardwareVertexBuffer*>(mVertexBuffers[mTargetBufferIndex].getPointer()); //TODO GL4+ glBindTransformFeedback // Dynamically determine shader output variable names. std::vector<String> nameStrings; std::vector<const GLchar*> names; for (uint e = 0; e < elemCount; e++) { const VertexElement* element = declaration->getElement(e); String name = getSemanticVaryingName(element->getSemantic(), element->getIndex()); nameStrings.push_back(name); } // Convert to const char * for GL for (uint e = 0; e < elemCount; e++) { names.push_back(nameStrings[e].c_str()); } //TODO replace glTransformFeedbackVaryings with in-shader specification (GL 4.4) OGRE_CHECK_GL_ERROR(glTransformFeedbackVaryings(programId, elemCount, &names[0], GL_INTERLEAVED_ATTRIBS)); if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLSeparableProgram* separableProgram = GLSLSeparableProgramManager::getSingleton().getCurrentSeparableProgram(); separableProgram->activate(); } else { OGRE_CHECK_GL_ERROR(glLinkProgram(programId)); } #if OGRE_DEBUG_MODE // Check if program linking was successful. GLint didLink = 0; OGRE_CHECK_GL_ERROR(glGetProgramiv(programId, GL_LINK_STATUS, &didLink)); logObjectInfo(String("RVB GLSL link result : "), programId); if (glIsProgram(programId)) { glValidateProgram(programId); } logObjectInfo(String("RVB GLSL validation result : "), programId); // Check if varyings were successfully set. GLchar Name[64]; GLsizei Length(0); GLsizei Size(0); GLenum Type(0); // bool Validated = false; for (size_t i = 0; i < elemCount; i++) { OGRE_CHECK_GL_ERROR(glGetTransformFeedbackVarying( programId, i, 64, &Length, &Size, &Type, Name )); std::cout << "Varying " << i << ": " << Name <<" "<< Length <<" "<< Size <<" "<< Type << std::endl; // Validated = (Size == 1) && (Type == GL_FLOAT_VEC3); // std::cout << Validated << " " << GL_FLOAT_VEC3 << std::endl; } #endif }
//----------------------------------------------------------------------------- void GLES2RenderToVertexBuffer::update(SceneManager* sceneMgr) { size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; if (!mVertexBuffers[0] || mVertexBuffers[0]->getSizeInBytes() != bufSize) { // Buffers don't match. Need to reallocate. mResetRequested = true; } // Single pass only for now Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); // Set pass before binding buffers to activate the GPU programs sceneMgr->_setPass(r2vbPass); bindVerticesOutput(r2vbPass); RenderOperation renderOp; size_t targetBufferIndex; if (mResetRequested || mResetsEveryUpdate) { // Use source data to render to first buffer mSourceRenderable->getRenderOperation(renderOp); targetBufferIndex = 0; } else { // Use current front buffer to render to back buffer this->getRenderOperation(renderOp); targetBufferIndex = 1 - mFrontBufferIndex; } if (!mVertexBuffers[targetBufferIndex] || mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) { reallocateBuffer(targetBufferIndex); } GLES2HardwareVertexBuffer* vertexBuffer = static_cast<GLES2HardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].get()); /* if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLESProgramPipeline* programPipeline = GLSLESProgramPipelineManager::getSingleton().getActiveProgramPipeline(); programPipeline->getVertexArrayObject()->bind(); } else { GLSLESLinkProgram* linkProgram = GLSLESLinkProgramManager::getSingleton().getActiveLinkProgram(); linkProgram->getVertexArrayObject()->bind(); } */ // Bind the target buffer OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffer->getGLBufferId())); // Disable rasterization OGRE_CHECK_GL_ERROR(glEnable(GL_RASTERIZER_DISCARD)); RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); // Draw the object targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasFragmentProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, r2vbPass->getFragmentProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } OGRE_CHECK_GL_ERROR(glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mPrimitivesDrawnQuery)); OGRE_CHECK_GL_ERROR(glBeginTransformFeedback(getR2VBPrimitiveType(mOperationType))); targetRenderSystem->_render(renderOp); OGRE_CHECK_GL_ERROR(glEndTransformFeedback()); // Finish the query OGRE_CHECK_GL_ERROR(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)); OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); // Read back query results GLuint primitivesWritten; OGRE_CHECK_GL_ERROR(glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten)); mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); // Switch the vertex binding if necessary if (targetBufferIndex != mFrontBufferIndex) { mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); mFrontBufferIndex = targetBufferIndex; } // Enable rasterization OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); // Clear the reset flag mResetRequested = false; }