diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp | 703 |
1 files changed, 130 insertions, 573 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp index 105587f62c..2167200a91 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp @@ -8,43 +8,39 @@ #include "libANGLE/renderer/d3d/RendererD3D.h" -#include "common/debug.h" #include "common/MemoryBuffer.h" +#include "common/debug.h" #include "common/utilities.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/TextureImpl.h" #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/DeviceD3D.h" #include "libANGLE/renderer/d3d/DisplayD3D.h" #include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/SamplerD3D.h" -#include "libANGLE/ResourceManager.h" -#include "libANGLE/State.h" -#include "libANGLE/VertexArray.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" namespace rx { -namespace -{ -// If we request a scratch buffer requesting a smaller size this many times, -// release and recreate the scratch buffer. This ensures we don't have a -// degenerate case where we are stuck hogging memory. -const int ScratchMemoryBufferLifetime = 1000; - -} // anonymous namespace - RendererD3D::RendererD3D(egl::Display *display) : mDisplay(display), - mDeviceLost(false), - mAnnotator(nullptr), mPresentPathFastEnabled(false), - mScratchMemoryBufferResetCounter(0), + mCapsInitialized(false), mWorkaroundsInitialized(false), - mDisjoint(false) + mDisjoint(false), + mDeviceLost(false), + mWorkerThreadPool(4) { } @@ -55,451 +51,29 @@ RendererD3D::~RendererD3D() void RendererD3D::cleanup() { - mScratchMemoryBuffer.resize(0); - for (auto &incompleteTexture : mIncompleteTextures) - { - incompleteTexture.second.set(NULL); - } - mIncompleteTextures.clear(); - - if (mAnnotator != nullptr) - { - gl::UninitializeDebugAnnotations(); - SafeDelete(mAnnotator); - } -} - -SamplerImpl *RendererD3D::createSampler() -{ - return new SamplerD3D(); -} - -gl::Error RendererD3D::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) -{ - return genericDrawArrays(data, mode, first, count, 0); -} - -gl::Error RendererD3D::drawArraysInstanced(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instanceCount) -{ - return genericDrawArrays(data, mode, first, count, instanceCount); -} - -gl::Error RendererD3D::drawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) -{ - return genericDrawElements(data, mode, count, type, indices, 0, indexRange); -} - -gl::Error RendererD3D::drawElementsInstanced(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange) -{ - return genericDrawElements(data, mode, count, type, indices, instances, indexRange); -} - -gl::Error RendererD3D::drawRangeElements(const gl::Data &data, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) -{ - return genericDrawElements(data, mode, count, type, indices, 0, indexRange); -} - -gl::Error RendererD3D::genericDrawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange) -{ - gl::Program *program = data.state->getProgram(); - ASSERT(program != nullptr); - ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); - bool usesPointSize = programD3D->usesPointSize(); - - programD3D->updateSamplerMapping(); - - gl::Error error = generateSwizzles(data); - if (error.isError()) - { - return error; - } - - if (!applyPrimitiveType(mode, count, usesPointSize)) - { - return gl::Error(GL_NO_ERROR); - } - - error = updateState(data, mode); - if (error.isError()) - { - return error; - } - - TranslatedIndexData indexInfo; - indexInfo.indexRange = indexRange; - - error = applyIndexBuffer(data, indices, count, mode, type, &indexInfo); - if (error.isError()) - { - return error; - } - - applyTransformFeedbackBuffers(*data.state); - // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation - // layer. - ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); - - size_t vertexCount = indexInfo.indexRange.vertexCount(); - error = applyVertexBuffer(*data.state, mode, static_cast<GLsizei>(indexInfo.indexRange.start), - static_cast<GLsizei>(vertexCount), instances, &indexInfo); - if (error.isError()) - { - return error; - } - - error = applyTextures(data); - if (error.isError()) - { - return error; - } - - error = applyShaders(data, mode); - if (error.isError()) - { - return error; - } - - error = programD3D->applyUniformBuffers(data); - if (error.isError()) - { - return error; - } - - if (!skipDraw(data, mode)) - { - error = drawElementsImpl(data, indexInfo, mode, count, type, indices, instances); - if (error.isError()) - { - return error; - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::genericDrawArrays(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances) -{ - gl::Program *program = data.state->getProgram(); - ASSERT(program != nullptr); - ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); - bool usesPointSize = programD3D->usesPointSize(); - - programD3D->updateSamplerMapping(); - - gl::Error error = generateSwizzles(data); - if (error.isError()) - { - return error; - } - - if (!applyPrimitiveType(mode, count, usesPointSize)) - { - return gl::Error(GL_NO_ERROR); - } - - error = updateState(data, mode); - if (error.isError()) - { - return error; - } - - applyTransformFeedbackBuffers(*data.state); - - error = applyVertexBuffer(*data.state, mode, first, count, instances, nullptr); - if (error.isError()) - { - return error; - } - - error = applyTextures(data); - if (error.isError()) - { - return error; - } - - error = applyShaders(data, mode); - if (error.isError()) - { - return error; - } - - error = programD3D->applyUniformBuffers(data); - if (error.isError()) - { - return error; - } - - if (!skipDraw(data, mode)) - { - error = drawArraysImpl(data, mode, count, instances); - if (error.isError()) - { - return error; - } - - if (data.state->isTransformFeedbackActiveUnpaused()) - { - markTransformFeedbackUsage(data); - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type) -{ - ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); - - unsigned int samplerRange = static_cast<unsigned int>(programD3D->getUsedSamplerRange(type)); - - for (unsigned int i = 0; i < samplerRange; i++) - { - GLenum textureType = programD3D->getSamplerTextureType(type, i); - GLint textureUnit = programD3D->getSamplerMapping(type, i, *data.caps); - if (textureUnit != -1) - { - gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); - ASSERT(texture); - if (texture->getTextureState().swizzleRequired()) - { - gl::Error error = generateSwizzle(texture); - if (error.isError()) - { - return error; - } - } - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::generateSwizzles(const gl::Data &data) -{ - gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX); - if (error.isError()) - { - return error; - } - - error = generateSwizzles(data, gl::SAMPLER_PIXEL); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); -} - -unsigned int RendererD3D::GetBlendSampleMask(const gl::Data &data, int samples) -{ - unsigned int mask = 0; - if (data.state->isSampleCoverageEnabled()) - { - GLclampf coverageValue = data.state->getSampleCoverageValue(); - if (coverageValue != 0) - { - float threshold = 0.5f; - - for (int i = 0; i < samples; ++i) - { - mask <<= 1; - - if ((i + 1) * coverageValue >= threshold) - { - threshold += 1.0f; - mask |= 1; - } - } - } - - bool coverageInvert = data.state->getSampleCoverageInvert(); - if (coverageInvert) - { - mask = ~mask; - } - } - else - { - mask = 0xFFFFFFFF; - } - - return mask; -} - -// Applies the shaders and shader constants to the Direct3D device -gl::Error RendererD3D::applyShaders(const gl::Data &data, GLenum drawMode) -{ - gl::Program *program = data.state->getProgram(); - ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); - programD3D->updateCachedInputLayout(*data.state); - - gl::Error error = applyShadersImpl(data, drawMode); - if (error.isError()) - { - return error; - } - - return programD3D->applyUniforms(drawMode); -} - -// For each Direct3D sampler of either the pixel or vertex stage, -// looks up the corresponding OpenGL texture image unit and texture type, -// and sets the texture and its addressing/filtering state (or NULL when inactive). -// Sampler mapping needs to be up-to-date on the program object before this is called. -gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType, - const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount) -{ - ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); - - ASSERT(!programD3D->isSamplerMappingDirty()); - - unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); - for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) - { - GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); - GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, *data.caps); - if (textureUnit != -1) - { - gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); - ASSERT(texture); - - gl::Sampler *samplerObject = data.state->getSampler(textureUnit); - - const gl::SamplerState &samplerState = - samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); - - // TODO: std::binary_search may become unavailable using older versions of GCC - if (texture->isSamplerComplete(samplerState, data) && - !std::binary_search(framebufferTextures.begin(), - framebufferTextures.begin() + framebufferTextureCount, texture)) - { - gl::Error error = setSamplerState(shaderType, samplerIndex, texture, samplerState); - if (error.isError()) - { - return error; - } - - error = setTexture(shaderType, samplerIndex, texture); - if (error.isError()) - { - return error; - } - } - else - { - // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. - gl::Texture *incompleteTexture = getIncompleteTexture(textureType); - - gl::Error error = setSamplerState(shaderType, samplerIndex, incompleteTexture, - incompleteTexture->getSamplerState()); - if (error.isError()) - { - return error; - } - - error = setTexture(shaderType, samplerIndex, incompleteTexture); - if (error.isError()) - { - return error; - } - } - } - else - { - // No texture bound to this slot even though it is used by the shader, bind a NULL texture - gl::Error error = setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } - } - - // Set all the remaining textures to NULL - size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits - : data.caps->maxVertexTextureImageUnits; - clearTextures(shaderType, samplerRange, samplerCount); - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::applyTextures(const gl::Data &data) -{ - FramebufferTextureArray framebufferTextures; - size_t framebufferSerialCount = getBoundFramebufferTextures(data, &framebufferTextures); - - gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); + mIncompleteTextures.onDestroy(mDisplay->getProxyContext()); } -bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) +bool RendererD3D::skipDraw(const gl::State &glState, GLenum drawMode) { - const gl::State &state = *data.state; - if (drawMode == GL_POINTS) { - bool usesPointSize = GetImplAs<ProgramD3D>(state.getProgram())->usesPointSize(); + bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize(); // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, // which affects varying interpolation. Since the value of gl_PointSize is // undefined when not written, just skip drawing to avoid unexpected results. - if (!usesPointSize && !state.isTransformFeedbackActiveUnpaused()) + if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused()) { - // This is stictly speaking not an error, but developers should be - // notified of risking undefined behavior. - ERR("Point rendering without writing to gl_PointSize."); - + // Notify developers of risking undefined behavior. + WARN() << "Point rendering without writing to gl_PointSize."; return true; } } else if (gl::IsTriangleMode(drawMode)) { - if (state.getRasterizerState().cullFace && - state.getRasterizerState().cullMode == GL_FRONT_AND_BACK) + if (glState.getRasterizerState().cullFace && + glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack) { return true; } @@ -508,196 +82,179 @@ bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) return false; } -void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) +gl::Error RendererD3D::getIncompleteTexture(const gl::Context *context, + GLenum type, + gl::Texture **textureOut) { - const gl::TransformFeedback *transformFeedback = data.state->getCurrentTransformFeedback(); - for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) - { - const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i); - if (binding.get() != nullptr) - { - BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get()); - bufferD3D->markTransformFeedbackUsage(); - } - } + return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut); } -size_t RendererD3D::getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray) +GLenum RendererD3D::getResetStatus() { - size_t textureCount = 0; - - const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); - for (size_t i = 0; i < drawFramebuffer->getNumColorBuffers(); i++) + if (!mDeviceLost) { - const gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); - if (attachment && attachment->type() == GL_TEXTURE) + if (testDeviceLost()) { - (*outTextureArray)[textureCount++] = attachment->getTexture(); + mDeviceLost = true; + notifyDeviceLost(); + return GL_UNKNOWN_CONTEXT_RESET_EXT; } + return GL_NO_ERROR; } - const gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); - if (depthStencilAttachment && depthStencilAttachment->type() == GL_TEXTURE) + if (testDeviceResettable()) { - (*outTextureArray)[textureCount++] = depthStencilAttachment->getTexture(); + return GL_NO_ERROR; } - std::sort(outTextureArray->begin(), outTextureArray->begin() + textureCount); - - return textureCount; -} - -gl::Texture *RendererD3D::getIncompleteTexture(GLenum type) -{ - if (mIncompleteTextures.find(type) == mIncompleteTextures.end()) - { - const GLubyte color[] = { 0, 0, 0, 255 }; - const gl::Extents colorSize(1, 1, 1); - const gl::PixelUnpackState unpack(1, 0); - const gl::Box area(0, 0, 0, 1, 1, 1); - - // Skip the API layer to avoid needing to pass the Context and mess with dirty bits. - gl::Texture *t = - new gl::Texture(createTexture(type), std::numeric_limits<GLuint>::max(), type); - t->setStorage(type, 1, GL_RGBA8, colorSize); - - if (type == GL_TEXTURE_CUBE_MAP) - { - for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++) - { - t->getImplementation()->setSubImage(face, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, - unpack, color); - } - } - else - { - t->getImplementation()->setSubImage(type, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, unpack, - color); - } - - mIncompleteTextures[type].set(t); - } - - return mIncompleteTextures[type].get(); -} - -bool RendererD3D::isDeviceLost() const -{ - return mDeviceLost; + return GL_UNKNOWN_CONTEXT_RESET_EXT; } void RendererD3D::notifyDeviceLost() { - mDeviceLost = true; mDisplay->notifyDeviceLost(); } std::string RendererD3D::getVendorString() const { - LUID adapterLuid = { 0 }; + LUID adapterLuid = {0}; if (getLUID(&adapterLuid)) { char adapterLuidString[64]; - sprintf_s(adapterLuidString, sizeof(adapterLuidString), "(adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart); + sprintf_s(adapterLuidString, sizeof(adapterLuidString), "(adapter LUID: %08x%08x)", + adapterLuid.HighPart, adapterLuid.LowPart); return std::string(adapterLuidString); } return std::string(""); } -gl::Error RendererD3D::getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut) +void RendererD3D::setGPUDisjoint() { - if (mScratchMemoryBuffer.size() == requestedSize) - { - mScratchMemoryBufferResetCounter = ScratchMemoryBufferLifetime; - *bufferOut = &mScratchMemoryBuffer; - return gl::Error(GL_NO_ERROR); - } - - if (mScratchMemoryBuffer.size() > requestedSize) - { - mScratchMemoryBufferResetCounter--; - } + mDisjoint = true; +} - if (mScratchMemoryBufferResetCounter <= 0 || mScratchMemoryBuffer.size() < requestedSize) - { - mScratchMemoryBuffer.resize(0); - if (!mScratchMemoryBuffer.resize(requestedSize)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); - } - mScratchMemoryBufferResetCounter = ScratchMemoryBufferLifetime; - } +GLint RendererD3D::getGPUDisjoint() +{ + bool disjoint = mDisjoint; - ASSERT(mScratchMemoryBuffer.size() >= requestedSize); + // Disjoint flag is cleared when read + mDisjoint = false; - *bufferOut = &mScratchMemoryBuffer; - return gl::Error(GL_NO_ERROR); + return disjoint; } -void RendererD3D::insertEventMarker(GLsizei length, const char *marker) +GLint64 RendererD3D::getTimestamp() { - std::vector<wchar_t> wcstring (length + 1); - size_t convertedChars = 0; - errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, marker, _TRUNCATE); - if (err == 0) - { - getAnnotator()->setMarker(wcstring.data()); - } + // D3D has no way to get an actual timestamp reliably so 0 is returned + return 0; } -void RendererD3D::pushGroupMarker(GLsizei length, const char *marker) +void RendererD3D::ensureCapsInitialized() const { - std::vector<wchar_t> wcstring(length + 1); - size_t convertedChars = 0; - errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, marker, _TRUNCATE); - if (err == 0) + if (!mCapsInitialized) { - getAnnotator()->beginEvent(wcstring.data()); + generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations); + mCapsInitialized = true; } } -void RendererD3D::popGroupMarker() +const gl::Caps &RendererD3D::getNativeCaps() const { - getAnnotator()->endEvent(); + ensureCapsInitialized(); + return mNativeCaps; } -void RendererD3D::setGPUDisjoint() +const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const { - mDisjoint = true; + ensureCapsInitialized(); + return mNativeTextureCaps; } -GLint RendererD3D::getGPUDisjoint() +const gl::Extensions &RendererD3D::getNativeExtensions() const { - bool disjoint = mDisjoint; + ensureCapsInitialized(); + return mNativeExtensions; +} - // Disjoint flag is cleared when read - mDisjoint = false; +const gl::Limitations &RendererD3D::getNativeLimitations() const +{ + ensureCapsInitialized(); + return mNativeLimitations; +} - return disjoint; +angle::WorkerThreadPool *RendererD3D::getWorkerThreadPool() +{ + return &mWorkerThreadPool; } -GLint64 RendererD3D::getTimestamp() +Serial RendererD3D::generateSerial() { - // D3D has no way to get an actual timestamp reliably so 0 is returned - return 0; + return mSerialFactory.generate(); } -void RendererD3D::onMakeCurrent(const gl::Data &data) +bool InstancedPointSpritesActive(ProgramD3D *programD3D, GLenum mode) { + return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() && + mode == GL_POINTS; } -void RendererD3D::initializeDebugAnnotator() +gl::Error RendererD3D::initRenderTarget(RenderTargetD3D *renderTarget) { - createAnnotator(); - ASSERT(mAnnotator); - gl::InitializeDebugAnnotations(mAnnotator); + return clearRenderTarget(renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0); } -gl::DebugAnnotator *RendererD3D::getAnnotator() +gl::Error RendererD3D::initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) { - ASSERT(mAnnotator); - return mAnnotator; + ASSERT(glTexture->getTarget() == GL_TEXTURE_2D_MULTISAMPLE); + TextureD3D *textureD3D = GetImplAs<TextureD3D>(glTexture); + gl::ImageIndex index = gl::ImageIndex::Make2DMultisample(); + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(textureD3D->getRenderTarget(context, index, &renderTarget)); + return clearRenderTarget(renderTarget, gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, 0); } + +unsigned int GetBlendSampleMask(const gl::State &glState, int samples) +{ + unsigned int mask = 0; + if (glState.isSampleCoverageEnabled()) + { + GLfloat coverageValue = glState.getSampleCoverageValue(); + if (coverageValue != 0) + { + float threshold = 0.5f; + + for (int i = 0; i < samples; ++i) + { + mask <<= 1; + + if ((i + 1) * coverageValue >= threshold) + { + threshold += 1.0f; + mask |= 1; + } + } + } + + bool coverageInvert = glState.getSampleCoverageInvert(); + if (coverageInvert) + { + mask = ~mask; + } + } + else + { + mask = 0xFFFFFFFF; + } + + if (glState.isSampleMaskEnabled()) + { + mask &= glState.getSampleMaskWord(0); + } + + return mask; } + +} // namespace rx |