GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout) { ASSERT(mFence->isSet()); bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); if (mFence->test(flushCommandBuffer)) { return GL_ALREADY_SIGNALED; } if (mFence->hasError()) { return GL_WAIT_FAILED; } if (timeout == 0) { return GL_TIMEOUT_EXPIRED; } LARGE_INTEGER currentCounter = { 0 }; BOOL success = QueryPerformanceCounter(¤tCounter); UNUSED_ASSERTION_VARIABLE(success); ASSERT(success); LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll); LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer)) { Sleep(0); BOOL success = QueryPerformanceCounter(¤tCounter); UNUSED_ASSERTION_VARIABLE(success); ASSERT(success); } if (mFence->hasError()) { return GL_WAIT_FAILED; } if (currentCounter.QuadPart >= endCounter) { return GL_TIMEOUT_EXPIRED; } return GL_CONDITION_SATISFIED; }
// Increments refcount on surface. // caller must Release() the returned surface gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) { ASSERT(target == GL_TEXTURE_2D); UNUSED_ASSERTION_VARIABLE(target); IDirect3DBaseTexture9 *baseTexture = NULL; gl::Error error = getBaseTexture(&baseTexture); if (error.isError()) { return error; } IDirect3DTexture9 *texture = static_cast<IDirect3DTexture9*>(baseTexture); HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); } // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level + mTopLevel != 0 && isManaged() && dirty) { texture->AddDirtyRect(NULL); } return gl::Error(GL_NO_ERROR); }
TCache::TypeKey::TypeKey(TBasicType basicType, TPrecision precision, TQualifier qualifier, unsigned char primarySize, unsigned char secondarySize) { static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small"); const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max(); UNUSED_ASSERTION_VARIABLE(MaxEnumValue); // TODO: change to static_assert() once we deprecate MSVC 2013 support ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast && "TypeKey::EnumComponentType is too small"); value = 0; components.basicType = static_cast<EnumComponentType>(basicType); components.precision = static_cast<EnumComponentType>(precision); components.qualifier = static_cast<EnumComponentType>(qualifier); components.primarySize = primarySize; components.secondarySize = secondarySize; }
void SurfaceD3D::unsubclassWindow() { if (!mWindowSubclassed) { return; } #if !defined(ANGLE_ENABLE_WINDOWS_STORE) HWND window = mNativeWindow.getNativeWindow(); if (!window) { return; } // un-subclass LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc)); // Check the windowproc is still SurfaceWindowProc. // If this assert fails, then it is likely the application has subclassed the // hwnd as well and did not unsubclass before destroying its EGL context. The // application should be modified to either subclass before initializing the // EGL context, or to unsubclass before destroying the EGL context. if(parentWndFunc) { LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc); UNUSED_ASSERTION_VARIABLE(prevWndFunc); ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); } RemoveProp(window, kSurfaceProperty); RemoveProp(window, kParentWndProc); #endif mWindowSubclassed = false; }
// Returns true if it recreates the direct buffer bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset, size_t size, size_t destOffset) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); size_t requiredSize = sourceOffset + size; bool createBuffer = !mNativeStorage || mBufferSize < requiredSize; // (Re)initialize D3D buffer if needed if (createBuffer) { bool preserveData = (destOffset > 0); resize(source->getSize(), preserveData); } if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK || source->getUsage() == BUFFER_USAGE_SYSTEM_MEMORY) { ASSERT(source->isMappable()); uint8_t *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT); D3D11_MAPPED_SUBRESOURCE mappedResource; HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource); UNUSED_ASSERTION_VARIABLE(hr); ASSERT(SUCCEEDED(hr)); uint8_t *destPointer = static_cast<uint8_t *>(mappedResource.pData) + destOffset; // Offset bounds are validated at the API layer ASSERT(sourceOffset + size <= destOffset + mBufferSize); memcpy(destPointer, sourcePointer, size); context->Unmap(mNativeStorage, 0); source->unmap(); } else { ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, source)); D3D11_BOX srcBox; srcBox.left = sourceOffset; srcBox.right = sourceOffset + size; srcBox.top = 0; srcBox.bottom = 1; srcBox.front = 0; srcBox.back = 1; ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, source)); ID3D11Buffer *sourceBuffer = static_cast<NativeStorage*>(source)->getNativeStorage(); context->CopySubresourceRegion(mNativeStorage, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox); } return createBuffer; }
void Query9::end() { ASSERT(mQuery); HRESULT result = mQuery->Issue(D3DISSUE_END); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mStatus = GL_FALSE; mResult = GL_FALSE; }
FenceSync::FenceSync(rx::Renderer *renderer, GLuint id) : RefCountObject(id) { mFence = renderer->createFence(); LARGE_INTEGER counterFreqency = { 0 }; BOOL success = QueryPerformanceFrequency(&counterFreqency); UNUSED_ASSERTION_VARIABLE(success); ASSERT(success); mCounterFrequency = counterFreqency.QuadPart; }
void Query9::begin() { if (mQuery == NULL) { if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) { return gl::error(GL_OUT_OF_MEMORY); } } HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); }
void *BufferStorage11::NativeBuffer11::map(GLbitfield access) { ASSERT(mUsage == BUFFER_USAGE_STAGING); D3D11_MAPPED_SUBRESOURCE mappedResource; ID3D11DeviceContext *context = mRenderer->getDeviceContext(); D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access); UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); HRESULT result = context->Map(mNativeBuffer, 0, d3dMapType, d3dMapFlag, &mappedResource); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); return mappedResource.pData; }
ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) { BufferStorage *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK); if (!storage) { // Storage out-of-memory return NULL; } ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, storage)); ID3D11Buffer *buffer = static_cast<NativeStorage*>(storage)->getNativeStorage(); auto bufferSRVIt = mBufferResourceViews.find(srvFormat); if (bufferSRVIt != mBufferResourceViews.end()) { if (bufferSRVIt->second.first == buffer) { return bufferSRVIt->second.second; } else { // The underlying buffer has changed since the SRV was created: recreate the SRV. SafeRelease(bufferSRVIt->second.second); } } ID3D11Device *device = mRenderer->getDevice(); ID3D11ShaderResourceView *bufferSRV = NULL; const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat); D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; bufferSRVDesc.Buffer.ElementOffset = 0; bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes; bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; bufferSRVDesc.Format = srvFormat; HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV); return bufferSRV; }
bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) { // TODO(jmadill): We shouldn't need to cache this. mCompilerOutputType = compiler->getShaderOutputType(); const std::string &translatedSource = mData.getTranslatedSource(); mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos; mUsesFragColor = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos; mUsesFragData = translatedSource.find("GL_USES_FRAG_DATA") != std::string::npos; mUsesFragCoord = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos; mUsesFrontFacing = translatedSource.find("GL_USES_FRONT_FACING") != std::string::npos; mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos; mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos; mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos; mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; mUsesDiscardRewriting = translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; mRequiresIEEEStrictCompiling = translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos; ShHandle compilerHandle = compiler->getCompilerHandle(mData.getShaderType()); mUniformRegisterMap = GetUniformRegisterMap(ShGetUniformRegisterMap(compilerHandle)); for (const sh::InterfaceBlock &interfaceBlock : mData.getInterfaceBlocks()) { if (interfaceBlock.staticUse) { unsigned int index = static_cast<unsigned int>(-1); bool blockRegisterResult = ShGetInterfaceBlockRegister(compilerHandle, interfaceBlock.name, &index); UNUSED_ASSERTION_VARIABLE(blockRegisterResult); ASSERT(blockRegisterResult); mInterfaceBlockRegisterMap[interfaceBlock.name] = index; } } mDebugInfo += std::string("// ") + GetShaderTypeString(mData.getShaderType()) + " SHADER BEGIN\n"; mDebugInfo += "\n// GLSL BEGIN\n\n" + mData.getSource() + "\n\n// GLSL END\n\n\n"; mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + translatedSource + "\n// INITIAL HLSL END\n\n\n"; // Successive steps will append more info return true; }
size_t CallDAG::findIndex(const TIntermAggregate *function) const { TOperator op = function->getOp(); ASSERT(op == EOpPrototype || op == EOpFunction || op == EOpFunctionCall); UNUSED_ASSERTION_VARIABLE(op); auto it = mFunctionIdToIndex.find(function->getFunctionId()); if (it == mFunctionIdToIndex.end()) { return InvalidIndex; } else { return it->second; } }
// Increments refcount on surface. // caller must Release() the returned surface IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) { IDirect3DSurface9 *surface = NULL; if (mTexture) { HRESULT result = mTexture->GetSurfaceLevel(level + mTopLevel, &surface); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level + mTopLevel != 0 && isManaged() && dirty) { mTexture->AddDirtyRect(NULL); } } return surface; }
gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib, GLsizei count, GLsizei instances) const { const gl::VertexAttribute &attrib = *translatedAttrib.attribute; ASSERT(!DirectStoragePossible(attrib)); gl::Buffer *buffer = attrib.buffer.get(); BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr; ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib) == nullptr); UNUSED_ASSERTION_VARIABLE(bufferD3D); size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); ASSERT(!bufferD3D || ElementsInBuffer(attrib, static_cast<unsigned int>(bufferD3D->getSize())) >= static_cast<int>(totalCount)); return mStreamingBuffer->reserveVertexSpace(attrib, static_cast<GLsizei>(totalCount), instances); }
// Increments refcount on surface. // caller must Release() the returned surface IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty) { IDirect3DSurface9 *surface = NULL; if (mTexture) { D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); HRESULT result = mTexture->GetCubeMapSurface(face, level + mTopLevel, &surface); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level != 0 && isManaged() && dirty) { mTexture->AddDirtyRect(face, NULL); } } return surface; }
void VertexDataManager::prepareStaticBufferForAttribute(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue) const { gl::Buffer *buffer = attrib.buffer.get(); if (buffer) { BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer); // This will create the static buffer in the right circumstances StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBufferForAttribute(attrib); UNUSED_ASSERTION_VARIABLE(staticBuffer); // This check validates that a valid static vertex buffer was returned above ASSERT(!(staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attrib, NULL) && !staticBuffer->directStoragePossible(attrib, currentValue))); } }
UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize) : UniformStorage(initialSize), mConstantBuffer(NULL) { ID3D11Device *d3d11Device = renderer->getDevice(); if (initialSize > 0) { D3D11_BUFFER_DESC constantBufferDescription = {0}; constantBufferDescription.ByteWidth = initialSize; constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC; constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; constantBufferDescription.MiscFlags = 0; constantBufferDescription.StructureByteStride = 0; HRESULT result = d3d11Device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } }
void Display::destroySurface(Surface *surface) { if (surface->getType() == EGL_WINDOW_BIT) { WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); ASSERT(windowSurfaces); bool surfaceRemoved = false; for (WindowSurfaceMap::iterator iter = windowSurfaces->begin(); iter != windowSurfaces->end(); iter++) { if (iter->second == surface) { windowSurfaces->erase(iter); surfaceRemoved = true; break; } } ASSERT(surfaceRemoved); UNUSED_ASSERTION_VARIABLE(surfaceRemoved); } mImplementation->destroySurface(surface); }
void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) { // ensure the compiler is loaded initializeCompiler(); int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); std::string sourcePath; #if !defined (ANGLE_ENABLE_WINDOWS_STORE) if (gl::perfActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), source.c_str(), source.length()); compileOptions |= SH_LINE_DIRECTIVES; } #endif int result; if (sourcePath.empty()) { const char* sourceStrings[] = { source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); } else { const char* sourceStrings[] = { sourcePath.c_str(), source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } mShaderVersion = ShGetShaderVersion(compiler); if (mShaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3) { mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts"; TRACE("\n%s", mInfoLog.c_str()); } else if (result) { mHlsl = ShGetObjectCode(compiler); #ifdef _DEBUG // Prefix hlsl shader with commented out glsl shader // Useful in diagnostics tools like pix which capture the hlsl shaders std::ostringstream hlslStream; hlslStream << "// GLSL\n"; hlslStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = source.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); hlslStream << "// " << source.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } hlslStream << "\n\n"; hlslStream << mHlsl; mHlsl = hlslStream.str(); #endif mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { const sh::Uniform &uniform = mUniforms[uniformIndex]; if (uniform.staticUse) { unsigned int index = -1; bool result = ShGetUniformRegister(compiler, uniform.name, &index); UNUSED_ASSERTION_VARIABLE(result); ASSERT(result); mUniformRegisterMap[uniform.name] = index; } } mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler)); for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++) { const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex]; if (interfaceBlock.staticUse) { unsigned int index = -1; bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index); UNUSED_ASSERTION_VARIABLE(result); ASSERT(result); mInterfaceBlockRegisterMap[interfaceBlock.name] = index; } } } else { mInfoLog = ShGetInfoLog(compiler); TRACE("\n%s", mInfoLog.c_str()); } }
void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source) { int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); // D3D11 Feature Level 9_3 and below do not support non-constant loop indexers in fragment // shaders. // Shader compilation will fail. To provide a better error message we can instruct the // compiler to pre-validate. if (mRenderer->getRendererLimitations().shadersRequireIndexedLoopValidation) { compileOptions |= SH_VALIDATE_LOOP_INDEXING; } std::string sourcePath; #if !defined (ANGLE_ENABLE_WINDOWS_STORE) if (gl::DebugAnnotationsActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), source.c_str(), source.length()); compileOptions |= SH_LINE_DIRECTIVES; } #endif int result; if (sourcePath.empty()) { const char* sourceStrings[] = { source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); } else { const char* sourceStrings[] = { sourcePath.c_str(), source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } mShaderVersion = ShGetShaderVersion(compiler); if (result) { mTranslatedSource = ShGetObjectCode(compiler); #ifdef _DEBUG // Prefix hlsl shader with commented out glsl shader // Useful in diagnostics tools like pix which capture the hlsl shaders std::ostringstream hlslStream; hlslStream << "// GLSL\n"; hlslStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = source.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); hlslStream << "// " << source.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } hlslStream << "\n\n"; hlslStream << mTranslatedSource; mTranslatedSource = hlslStream.str(); #endif mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { const sh::Uniform &uniform = mUniforms[uniformIndex]; if (uniform.staticUse && !uniform.isBuiltIn()) { unsigned int index = static_cast<unsigned int>(-1); bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index); UNUSED_ASSERTION_VARIABLE(getUniformRegisterResult); ASSERT(getUniformRegisterResult); mUniformRegisterMap[uniform.name] = index; } } mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler)); for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++) { const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex]; if (interfaceBlock.staticUse) { unsigned int index = static_cast<unsigned int>(-1); bool blockRegisterResult = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index); UNUSED_ASSERTION_VARIABLE(blockRegisterResult); ASSERT(blockRegisterResult); mInterfaceBlockRegisterMap[interfaceBlock.name] = index; } } } else { mInfoLog = ShGetInfoLog(compiler); TRACE("\n%s", mInfoLog.c_str()); } }