From cef006904e875b7424b7fa13ea3dc2f9762081d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Kera=CC=88nen?= Date: Fri, 12 Apr 2019 12:47:08 +0300 Subject: Flatten OpenGL source directory hierarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flatten Source,Include and PrivateInclude directories away. Replace camelcase directory names with lowercase names. Remove random Qt3DS prefixes from directory names. Task-number: QT3DS-16 Change-Id: I5b23349232c760afa9a8efcc5e8945ee19d2e31a Reviewed-by: Pasi Keränen --- src/Runtime/Source/render/Qt3DSRenderContext.cpp | 1107 ++++++++++++++++++++++ 1 file changed, 1107 insertions(+) create mode 100644 src/Runtime/Source/render/Qt3DSRenderContext.cpp (limited to 'src/Runtime/Source/render/Qt3DSRenderContext.cpp') diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.cpp b/src/Runtime/Source/render/Qt3DSRenderContext.cpp new file mode 100644 index 00000000..aa2cb30f --- /dev/null +++ b/src/Runtime/Source/render/Qt3DSRenderContext.cpp @@ -0,0 +1,1107 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSMat44.h" +#include "render/Qt3DSRenderContext.h" +#include "foundation/Utils.h" +#include "EASTL/set.h" +#include "EASTL/utility.h" +#include "render/Qt3DSRenderShaderProgram.h" + +using namespace qt3ds; +using namespace qt3ds::render; +using namespace eastl; + +namespace qt3ds { +namespace render { + + NVRenderContextImpl::NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend, + IStringTable &inStrTable) + : m_backend(inBackend) + , m_DirtyFlags(0) + , m_DefaultOffscreenRenderTarget((NVRenderBackend::NVRenderBackendRenderTargetObject)NULL) + , m_DephBits(16) + , m_StencilBits(8) + , mRefCount(0) + , m_Foundation(fnd) + , m_StringTable(inStrTable) + , m_VertToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_VertToImpMap") + , m_IndexToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_IndexToImpMap") + , m_ConstantToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ConstantToImpMap") + , m_StorageToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_StorageToImpMap") + , m_AtomicCounterToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_AtomicCounterToImpMap") + , m_DrawIndirectToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_DrawIndirectToImpMap") + , m_DepthStencilStateToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_DepthStencilStateToImpMap") + , m_RasterizerStateToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RasterizerStateToImpMap") + , m_PathFontSpecToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RasterizerStateToImpMap") + , m_Tex2DToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Tex2DToImpMap") + , m_Tex2DArrayToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_Tex2DArrayToImpMap") + , m_TexCubeToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_TexCubeToImpMap") + , m_Image2DtoImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Image2DtoImpMap") + , m_ShaderToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ShaderToImpMap") + , m_RenderBufferToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_RenderBufferToImpMap") + , m_FrameBufferToImpMap(m_Foundation.getAllocator(), + "NVRenderContextImpl::m_FrameBufferToImpMap") + , m_NextTextureUnit(1) + , m_NextConstantBufferUnit(1) + , m_PropertyStack(m_Foundation.getAllocator(), "NVRenderContextImpl::m_PropertyStack") + { + + m_StringTable.addRef(); + + m_MaxTextureUnits = m_backend->GetMaxCombinedTextureUnits(); + m_MaxConstantBufferUnits = 16; // need backend query + + // get initial state + memZero(&m_HardwarePropertyContext, sizeof(m_HardwarePropertyContext)); + + // get default blending functions + m_backend->GetBlendFunc(&m_HardwarePropertyContext.m_BlendFunction); + // set default blend euqation + m_HardwarePropertyContext.m_BlendEquation.m_RGBEquation = NVRenderBlendEquation::Add; + m_HardwarePropertyContext.m_BlendEquation.m_AlphaEquation = NVRenderBlendEquation::Add; + // default state + m_HardwarePropertyContext.m_CullingEnabled = + m_backend->GetRenderState(NVRenderState::CullFace); + m_HardwarePropertyContext.m_DepthFunction = m_backend->GetDepthFunc(); + m_HardwarePropertyContext.m_BlendingEnabled = + m_backend->GetRenderState(NVRenderState::Blend); + m_HardwarePropertyContext.m_DepthWriteEnabled = m_backend->GetDepthWrite(); + m_HardwarePropertyContext.m_DepthTestEnabled = + m_backend->GetRenderState(NVRenderState::DepthTest); + m_HardwarePropertyContext.m_ScissorTestEnabled = + m_backend->GetRenderState(NVRenderState::ScissorTest); + m_backend->GetScissorRect(&m_HardwarePropertyContext.m_ScissorRect); + m_backend->GetViewportRect(&m_HardwarePropertyContext.m_Viewport); + + DoSetClearColor(m_HardwarePropertyContext.m_ClearColor); + } + + NVRenderContextImpl::~NVRenderContextImpl() + { + m_StringTable.release(); + QT3DS_ASSERT(m_VertToImpMap.size() == 0); + m_VertToImpMap.clear(); + QT3DS_ASSERT(m_IndexToImpMap.size() == 0); + m_IndexToImpMap.clear(); + QT3DS_ASSERT(m_ConstantToImpMap.size() == 0); + m_ConstantToImpMap.clear(); + QT3DS_ASSERT(m_StorageToImpMap.size() == 0); + m_StorageToImpMap.clear(); + QT3DS_ASSERT(m_DepthStencilStateToImpMap.size() == 0); + m_DepthStencilStateToImpMap.clear(); + QT3DS_ASSERT(m_RasterizerStateToImpMap.size() == 0); + m_RasterizerStateToImpMap.clear(); + QT3DS_ASSERT(m_PathFontSpecToImpMap.size() == 0); + m_PathFontSpecToImpMap.clear(); + QT3DS_ASSERT(m_Tex2DToImpMap.size() == 0); + m_Tex2DToImpMap.clear(); + QT3DS_ASSERT(m_Tex2DArrayToImpMap.size() == 0); + m_Tex2DArrayToImpMap.clear(); + QT3DS_ASSERT(m_Image2DtoImpMap.size() == 0); + m_Image2DtoImpMap.clear(); + QT3DS_ASSERT(m_ShaderToImpMap.size() == 0); + m_ShaderToImpMap.clear(); + QT3DS_ASSERT(m_RenderBufferToImpMap.size() == 0); + m_RenderBufferToImpMap.clear(); + QT3DS_ASSERT(m_FrameBufferToImpMap.size() == 0); + m_FrameBufferToImpMap.clear(); + + m_backend = NULL; + } + + void NVRenderContextImpl::getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) + { + QT3DSI32 theMaxTextureSize = 0; + m_backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize, + &theMaxTextureSize); + + oWidth = (QT3DSU32)theMaxTextureSize; + oHeight = (QT3DSU32)theMaxTextureSize; + } + + NVRenderDepthStencilState *NVRenderContextImpl::CreateDepthStencilState( + bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil, + NVRenderStencilFunctionArgument &stencilFuncFront, + NVRenderStencilFunctionArgument &stencilFuncBack, + NVRenderStencilOperationArgument &depthStencilOpFront, + NVRenderStencilOperationArgument &depthStencilOpBack) + { + NVRenderDepthStencilState *state = NVRenderDepthStencilState::Create( + *this, enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, + stencilFuncBack, depthStencilOpFront, depthStencilOpBack); + if (state) + m_DepthStencilStateToImpMap.insert( + make_pair(state->GetDepthStencilObjectHandle(), state)); + + return state; + } + + void NVRenderContextImpl::SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) + { + if (inDepthStencilState) { + m_backend->SetDepthStencilState(inDepthStencilState->GetDepthStencilObjectHandle()); + // currently we have a mixture therefore we need to update the context state + SetDepthFunction(inDepthStencilState->GetDepthFunc()); + SetDepthWriteEnabled(inDepthStencilState->GetDepthMask()); + SetDepthTestEnabled(inDepthStencilState->GetDepthEnabled()); + SetStencilTestEnabled(inDepthStencilState->GetStencilEnabled()); + } + } + + void NVRenderContextImpl::StateDestroyed(NVRenderDepthStencilState &state) + { + m_DepthStencilStateToImpMap.erase(state.GetDepthStencilObjectHandle()); + } + + NVRenderRasterizerState * + NVRenderContextImpl::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, + NVRenderFaces::Enum cullFace) + { + NVRenderRasterizerState *state = + NVRenderRasterizerState::Create(*this, depthBias, depthScale, cullFace); + if (state) + m_RasterizerStateToImpMap.insert(make_pair(state->GetRasterizerObjectHandle(), state)); + + return state; + } + + void NVRenderContextImpl::SetRasterizerState(NVRenderRasterizerState *inRasterizerState) + { + if (inRasterizerState) + m_backend->SetRasterizerState(inRasterizerState->GetRasterizerObjectHandle()); + } + + void NVRenderContextImpl::StateDestroyed(NVRenderRasterizerState &state) + { + m_RasterizerStateToImpMap.erase(state.GetRasterizerObjectHandle()); + } + + NVRenderVertexBuffer * + NVRenderContextImpl::CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, + QT3DSU32 stride, NVConstDataRef bufferData) + { + NVRenderVertexBuffer *buffer = + NVRenderVertexBuffer::Create(*this, usageType, size, stride, bufferData); + if (buffer) + m_VertToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); + return buffer; + } + + NVRenderVertexBuffer *NVRenderContextImpl::GetVertexBuffer(const void *implementationHandle) + { + nvhash_map::const_iterator entry = + m_VertToImpMap.find(implementationHandle); + if (entry != m_VertToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderVertexBuffer &buffer) + { + m_VertToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderIndexBuffer * + NVRenderContextImpl::CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, + qt3ds::render::NVRenderComponentTypes::Enum componentType, + size_t size, NVConstDataRef bufferData) + { + NVRenderIndexBuffer *buffer = + NVRenderIndexBuffer::Create(*this, usageType, componentType, size, bufferData); + + if (buffer) { + m_IndexToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer)); + } + + return buffer; + } + + NVRenderIndexBuffer *NVRenderContextImpl::GetIndexBuffer(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_IndexToImpMap.find(implementationHandle); + if (entry != m_IndexToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderIndexBuffer &buffer) + { + m_IndexToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderConstantBuffer * + NVRenderContextImpl::CreateConstantBuffer(const char *bufferName, + qt3ds::render::NVRenderBufferUsageType::Enum usageType, + size_t size, NVConstDataRef bufferData) + { + NVRenderConstantBuffer *buffer = + NVRenderConstantBuffer::Create(*this, bufferName, usageType, size, bufferData); + + if (buffer) { + m_ConstantToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderConstantBuffer *NVRenderContextImpl::GetConstantBuffer(CRegisteredString bufferName) + { + TContextConstantBufferMap::iterator entry = m_ConstantToImpMap.find(bufferName); + if (entry != m_ConstantToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderConstantBuffer &buffer) + { + m_ConstantToImpMap.erase(buffer.GetBufferName()); + } + + QT3DSU32 NVRenderContextImpl::GetNextConstantBufferUnit() + { + QT3DSU32 retval = m_NextConstantBufferUnit; + ++m_NextConstantBufferUnit; + // Too many texture units for a single draw call. + if (retval >= m_MaxConstantBufferUnits) { + QT3DS_ASSERT(false); + retval = retval % m_MaxConstantBufferUnits; + } + return retval; + } + + NVRenderStorageBuffer *NVRenderContextImpl::CreateStorageBuffer( + const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData, NVRenderDataBuffer *pBuffer) + { + NVRenderStorageBuffer *buffer = + NVRenderStorageBuffer::Create(*this, bufferName, usageType, size, bufferData, pBuffer); + + if (buffer) { + m_StorageToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderStorageBuffer *NVRenderContextImpl::GetStorageBuffer(CRegisteredString bufferName) + { + TContextStorageBufferMap::iterator entry = m_StorageToImpMap.find(bufferName); + if (entry != m_StorageToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderStorageBuffer &buffer) + { + m_StorageToImpMap.erase(buffer.GetBufferName()); + } + + NVRenderAtomicCounterBuffer *NVRenderContextImpl::CreateAtomicCounterBuffer( + const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) + { + NVRenderAtomicCounterBuffer *buffer = + NVRenderAtomicCounterBuffer::Create(*this, bufferName, usageType, size, bufferData); + + if (buffer) { + m_AtomicCounterToImpMap.insert(make_pair(buffer->GetBufferName(), buffer)); + } + + return buffer; + } + + NVRenderAtomicCounterBuffer * + NVRenderContextImpl::GetAtomicCounterBuffer(CRegisteredString bufferName) + { + TContextAtomicCounterBufferMap::iterator entry = m_AtomicCounterToImpMap.find(bufferName); + if (entry != m_AtomicCounterToImpMap.end()) + return entry->second; + return NULL; + } + + NVRenderAtomicCounterBuffer * + NVRenderContextImpl::GetAtomicCounterBufferByParam(CRegisteredString paramName) + { + // iterate through all atomic counter buffers + for (TContextAtomicCounterBufferMap::iterator iter = m_AtomicCounterToImpMap.begin(), + end = m_AtomicCounterToImpMap.end(); + iter != end; ++iter) { + if (iter->second && iter->second->ContainsParam(paramName)) + return iter->second; + } + + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderAtomicCounterBuffer &buffer) + { + m_AtomicCounterToImpMap.erase(buffer.GetBufferName()); + } + + NVRenderDrawIndirectBuffer *NVRenderContextImpl::CreateDrawIndirectBuffer( + qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size, + NVConstDataRef bufferData) + { + NVRenderDrawIndirectBuffer *buffer = + NVRenderDrawIndirectBuffer::Create(*this, usageType, size, bufferData); + + if (buffer) { + m_DrawIndirectToImpMap.insert(make_pair(buffer->GetBuffertHandle(), buffer)); + } + + return buffer; + } + + NVRenderDrawIndirectBuffer *NVRenderContextImpl::GetDrawIndirectBuffer( + NVRenderBackend::NVRenderBackendBufferObject implementationHandle) + { + TContextDrawIndirectBufferMap::iterator entry = + m_DrawIndirectToImpMap.find(implementationHandle); + if (entry != m_DrawIndirectToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::BufferDestroyed(NVRenderDrawIndirectBuffer &buffer) + { + m_DrawIndirectToImpMap.erase(buffer.GetBuffertHandle()); + } + + void NVRenderContextImpl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) + { + m_backend->SetMemoryBarrier(barriers); + } + + NVRenderOcclusionQuery *NVRenderContextImpl::CreateOcclusionQuery() + { + NVRenderOcclusionQuery *theQuery = NVRenderOcclusionQuery::Create(*this); + + return theQuery; + } + + NVRenderTimerQuery *NVRenderContextImpl::CreateTimerQuery() + { + NVRenderTimerQuery *theQuery = NVRenderTimerQuery::Create(*this); + + return theQuery; + } + + NVRenderSync *NVRenderContextImpl::CreateSync() + { + NVRenderSync *theSync = NVRenderSync::Create(*this); + + return theSync; + } + + NVRenderTexture2D *NVRenderContextImpl::CreateTexture2D() + { + NVRenderTexture2D *retval = NVRenderTexture2D::Create(*this); + if (retval) + m_Tex2DToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderTexture2DArray *NVRenderContextImpl::CreateTexture2DArray() + { + NVRenderTexture2DArray *retval = NVRenderTexture2DArray::Create(*this); + if (retval) + m_Tex2DArrayToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + NVRenderTextureCube *NVRenderContextImpl::CreateTextureCube() + { + NVRenderTextureCube *retval = NVRenderTextureCube::Create(*this); + if (retval) + m_TexCubeToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + NVRenderTexture2D *NVRenderContextImpl::GetTexture2D(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_Tex2DToImpMap.find(implementationHandle); + if (entry != m_Tex2DToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2D &buffer) + { + m_Tex2DToImpMap.erase(buffer.GetImplementationHandle()); + // We would like to find and catch any situations where this texture is being used + // but that would require some real work that we don't want to do right now. + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2DArray &buffer) + { + m_Tex2DArrayToImpMap.erase(buffer.GetTextureObjectHandle()); + } + + void NVRenderContextImpl::TextureDestroyed(NVRenderTextureCube &buffer) + { + m_TexCubeToImpMap.erase(buffer.GetTextureObjectHandle()); + } + + NVRenderImage2D *NVRenderContextImpl::CreateImage2D(NVRenderTexture2D *inTexture, + NVRenderImageAccessType::Enum inAccess) + { + NVRenderImage2D *retval = NVRenderImage2D::Create(*this, inTexture, inAccess); + if (retval) + m_Image2DtoImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval)); + + return retval; + } + + void NVRenderContextImpl::ImageDestroyed(NVRenderImage2D &image) + { + m_Image2DtoImpMap.erase(image.GetTextureObjectHandle()); + } + + // IF this texture isn't on a texture unit, put it on one. + // If it is on a texture unit, mark it as the most recently used texture. + QT3DSU32 NVRenderContextImpl::GetNextTextureUnit() + { + QT3DSU32 retval = m_NextTextureUnit; + ++m_NextTextureUnit; + // Too many texture units for a single draw call. + if (retval >= m_MaxTextureUnits) { + QT3DS_ASSERT(false); + retval = retval % m_MaxTextureUnits; + } + return retval; + } + + NVRenderRenderBuffer * + NVRenderContextImpl::CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, + QT3DSU32 width, QT3DSU32 height) + { + NVRenderRenderBuffer *retval = + NVRenderRenderBuffer::Create(*this, bufferFormat, width, height); + if (retval != NULL) + m_RenderBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderRenderBuffer *NVRenderContextImpl::GetRenderBuffer(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_RenderBufferToImpMap.find(implementationHandle); + if (entry != m_RenderBufferToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::RenderBufferDestroyed(NVRenderRenderBuffer &buffer) + { + m_RenderBufferToImpMap.erase(buffer.GetImplementationHandle()); + } + + NVRenderFrameBuffer *NVRenderContextImpl::CreateFrameBuffer() + { + NVRenderFrameBuffer *retval = NVRenderFrameBuffer::Create(*this); + if (retval != NULL) + m_FrameBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval)); + return retval; + } + + NVRenderFrameBuffer *NVRenderContextImpl::GetFrameBuffer(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_FrameBufferToImpMap.find(implementationHandle); + if (entry != m_FrameBufferToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::FrameBufferDestroyed(NVRenderFrameBuffer &fb) + { + m_FrameBufferToImpMap.erase(fb.GetImplementationHandle()); + if (m_HardwarePropertyContext.m_FrameBuffer == &fb) + m_HardwarePropertyContext.m_FrameBuffer = NULL; + } + + NVRenderAttribLayout * + NVRenderContextImpl::CreateAttributeLayout(NVConstDataRef attribs) + { + return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderAttribLayout)(*this, attribs); + } + + NVRenderInputAssembler *NVRenderContextImpl::CreateInputAssembler( + NVRenderAttribLayout *attribLayout, NVConstDataRef buffers, + const NVRenderIndexBuffer *indexBuffer, NVConstDataRef strides, + NVConstDataRef offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) + { + return QT3DS_NEW(GetFoundation().getAllocator(), + NVRenderInputAssembler)(*this, attribLayout, buffers, indexBuffer, strides, + offsets, primType, patchVertexCount); + } + + void NVRenderContextImpl::SetInputAssembler(NVRenderInputAssembler *inputAssembler) + { + if (m_HardwarePropertyContext.m_InputAssembler != inputAssembler) { + DoSetInputAssembler(inputAssembler); + } + } + + NVRenderVertFragCompilationResult NVRenderContextImpl::CompileSource( + const char *shaderName, NVConstDataRef vertShader, NVConstDataRef fragShader, + NVConstDataRef tessControlShaderSource, + NVConstDataRef tessEvaluationShaderSource, NVConstDataRef geometryShaderSource, + bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram) + { + NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( + *this, shaderName, vertShader, fragShader, tessControlShaderSource, + tessEvaluationShaderSource, geometryShaderSource, separateProgram, type, binaryProgram); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; + } + + NVRenderVertFragCompilationResult NVRenderContextImpl::CompileBinary( + const char *shaderName, NVRenderShaderProgramBinaryType::Enum type, + NVDataRef vertShader, NVDataRef fragShader, + NVDataRef tessControlShaderSource, NVDataRef tessEvaluationShaderSource, + NVConstDataRef geometryShaderSource) + { +#ifndef _MACOSX + NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create( + *this, shaderName, vertShader, fragShader, tessControlShaderSource, + tessEvaluationShaderSource, geometryShaderSource, false, type, true); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; +#else + QT3DS_ASSERT(false); + return NVRenderVertFragCompilationResult(); +#endif + } + + NVRenderVertFragCompilationResult + NVRenderContextImpl::CompileComputeSource(const char *shaderName, + NVConstDataRef computeShaderSource) + { + NVRenderVertFragCompilationResult result = + NVRenderShaderProgram::CreateCompute(*this, shaderName, computeShaderSource); + + if (result.mShader != NULL) + m_ShaderToImpMap.insert( + make_pair(result.mShader->GetShaderProgramHandle(), result.mShader)); + + return result; + } + + NVRenderShaderProgram *NVRenderContextImpl::GetShaderProgram(const void *implementationHandle) + { + const nvhash_map::iterator entry = + m_ShaderToImpMap.find(implementationHandle); + if (entry != m_ShaderToImpMap.end()) + return entry->second; + return NULL; + } + + void NVRenderContextImpl::ShaderDestroyed(NVRenderShaderProgram &shader) + { + m_ShaderToImpMap.erase(shader.GetShaderProgramHandle()); + if (m_HardwarePropertyContext.m_ActiveShader == &shader) + SetActiveShader(NULL); + } + + NVRenderProgramPipeline *NVRenderContextImpl::CreateProgramPipeline() + { + return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderProgramPipeline)(*this, + GetFoundation()); + } + + NVRenderPathSpecification *NVRenderContextImpl::CreatePathSpecification() + { + return NVRenderPathSpecification::CreatePathSpecification(*this); + } + + NVRenderPathRender *NVRenderContextImpl::CreatePathRender(size_t range) + { + return NVRenderPathRender::Create(*this, range); + } + + void NVRenderContextImpl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) + { + m_backend->SetPathProjectionMatrix(inPathProjection); + } + + void NVRenderContextImpl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) + { + m_backend->SetPathModelViewMatrix(inPathModelview); + } + + void NVRenderContextImpl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) + { + m_backend->SetPathStencilDepthOffset(inSlope, inBias); + } + void NVRenderContextImpl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) + { + m_backend->SetPathCoverDepthFunc(inFunc); + } + + NVRenderPathFontSpecification * + NVRenderContextImpl::CreatePathFontSpecification(CRegisteredString fontName) + { + // first check if it already exists + nvhash_map::const_iterator entry = + m_PathFontSpecToImpMap.find(fontName); + if (entry != m_PathFontSpecToImpMap.end()) + return entry->second; + + // if not create new one + NVRenderPathFontSpecification *pPathFontSpec = + NVRenderPathFontSpecification::CreatePathFontSpecification(*this, fontName); + + if (pPathFontSpec) + m_PathFontSpecToImpMap.insert(make_pair(fontName, pPathFontSpec)); + + return pPathFontSpec; + } + + void + NVRenderContextImpl::ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec) + { + m_PathFontSpecToImpMap.erase(inPathSpec.GetFontName()); + } + + NVRenderPathFontItem *NVRenderContextImpl::CreatePathFontItem() + { + // if not create new one + return NVRenderPathFontItem::CreatePathFontItem(*this); + } + + void NVRenderContextImpl::SetClearColor(QT3DSVec4 inClearColor) + { + if (m_HardwarePropertyContext.m_ClearColor != inClearColor) + DoSetClearColor(inClearColor); + } + + void NVRenderContextImpl::SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) + { + if (memcmp(&inFunctions, &m_HardwarePropertyContext.m_BlendFunction, + sizeof(NVRenderBlendFunctionArgument))) { + DoSetBlendFunction(inFunctions); + } + } + + void NVRenderContextImpl::SetBlendEquation(NVRenderBlendEquationArgument inEquations) + { + if (memcmp(&inEquations, &m_HardwarePropertyContext.m_BlendEquation, + sizeof(NVRenderBlendEquationArgument))) { + DoSetBlendEquation(inEquations); + } + } + + void NVRenderContextImpl::SetCullingEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_CullingEnabled) { + DoSetCullingEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) + { + if (inFunction != m_HardwarePropertyContext.m_DepthFunction) { + DoSetDepthFunction(inFunction); + } + } + + void NVRenderContextImpl::SetBlendingEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_BlendingEnabled) { + DoSetBlendingEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetColorWritesEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_ColorWritesEnabled) { + DoSetColorWritesEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetDepthWriteEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_DepthWriteEnabled) { + m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled; + m_backend->SetRenderState(inEnabled, NVRenderState::DepthWrite); + } + } + + void NVRenderContextImpl::SetDepthTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_DepthTestEnabled) { + DoSetDepthTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetMultisampleEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_MultisampleEnabled) { + DoSetMultisampleEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetStencilTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_StencilTestEnabled) { + DoSetStencilTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetScissorTestEnabled(bool inEnabled) + { + if (inEnabled != m_HardwarePropertyContext.m_ScissorTestEnabled) { + DoSetScissorTestEnabled(inEnabled); + } + } + + void NVRenderContextImpl::SetScissorRect(NVRenderRect inRect) + { + if (memcmp(&inRect, &m_HardwarePropertyContext.m_ScissorRect, sizeof(NVRenderRect))) { + DoSetScissorRect(inRect); + } + } + + void NVRenderContextImpl::SetViewport(NVRenderRect inViewport) + { + if (memcmp(&inViewport, &m_HardwarePropertyContext.m_Viewport, sizeof(NVRenderRect))) { + DoSetViewport(inViewport); + } + } + + void NVRenderContextImpl::SetActiveShader(NVRenderShaderProgram *inShader) + { + if (inShader != m_HardwarePropertyContext.m_ActiveShader) + DoSetActiveShader(inShader); + } + + void NVRenderContextImpl::SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) + { + if (inProgramPipeline != m_HardwarePropertyContext.m_ActiveProgramPipeline) + DoSetActiveProgramPipeline(inProgramPipeline); + } + + void NVRenderContextImpl::DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX, + QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) + { + QT3DS_ASSERT(inShader); + + if (inShader != m_HardwarePropertyContext.m_ActiveShader) + DoSetActiveShader(inShader); + + m_backend->DispatchCompute(inShader->GetShaderProgramHandle(), numGroupsX, numGroupsY, + numGroupsZ); + + OnPostDraw(); + } + + void NVRenderContextImpl::SetDrawBuffers(NVConstDataRef inDrawBufferSet) + { + m_backend->SetDrawBuffers( + (m_HardwarePropertyContext.m_FrameBuffer) + ? m_HardwarePropertyContext.m_FrameBuffer->GetFrameBuffertHandle() + : NULL, + inDrawBufferSet); + } + + void NVRenderContextImpl::SetReadBuffer(NVReadFaces::Enum inReadFace) + { + // currently NULL which means the read target must be set with setReadTarget + m_backend->SetReadBuffer(NULL, inReadFace); + } + + void NVRenderContextImpl::ReadPixels(NVRenderRect inRect, + NVRenderReadPixelFormats::Enum inFormat, + NVDataRef inWriteBuffer) + { + // NULL means read from current render target + m_backend->ReadPixel(NULL, inRect.m_X, inRect.m_Y, inRect.m_Width, inRect.m_Height, + inFormat, (void *)inWriteBuffer.begin()); + } + + void NVRenderContextImpl::SetRenderTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { + DoSetRenderTarget(inBuffer); + } + } + + void NVRenderContextImpl::SetReadTarget(NVRenderFrameBuffer *inBuffer) + { + if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) { + DoSetReadTarget(inBuffer); + } + } + + void NVRenderContextImpl::ResetBlendState() + { + QT3DSI32_4 values; + + m_backend->SetRenderState(m_HardwarePropertyContext.m_BlendingEnabled, + NVRenderState::Blend); + const NVRenderBlendFunctionArgument &theBlendArg(m_HardwarePropertyContext.m_BlendFunction); + m_backend->SetBlendFunc(theBlendArg); + } + + // Pop the entire set of properties, potentially forcing the values + // to opengl. + void NVRenderContextImpl::PopPropertySet(bool inForceSetProperties) + { + if (!m_PropertyStack.empty()) { + SNVGLHardPropertyContext &theTopContext(m_PropertyStack.back()); + if (inForceSetProperties) { +#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ + DoSet##setterName(theTopContext.m_##propName); + + ITERATE_HARDWARE_CONTEXT_PROPERTIES + +#undef HANDLE_CONTEXT_HARDWARE_PROPERTY + } else { +#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \ + Set##setterName(theTopContext.m_##propName); + + ITERATE_HARDWARE_CONTEXT_PROPERTIES + +#undef HANDLE_CONTEXT_HARDWARE_PROPERTY + } + m_PropertyStack.pop_back(); + } + } + + void NVRenderContextImpl::Clear(NVRenderClearFlags flags) + { + if ((flags & NVRenderClearValues::Depth) + && m_HardwarePropertyContext.m_DepthWriteEnabled == false) { + QT3DS_ASSERT(false); + SetDepthWriteEnabled(true); + } + m_backend->Clear(flags); + } + + void NVRenderContextImpl::Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) + { + NVRenderFrameBuffer *previous = m_HardwarePropertyContext.m_FrameBuffer; + if (previous != &fb) + SetRenderTarget(&fb); + + Clear(flags); + + if (previous != &fb) + SetRenderTarget(previous); + } + + void NVRenderContextImpl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1, + QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1, + NVRenderClearFlags flags, + NVRenderTextureMagnifyingOp::Enum filter) + { + m_backend->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, flags, + filter); + } + + bool + NVRenderContextImpl::BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler, + NVRenderShaderProgram *shader) + { + // setup the input assembler object + return m_backend->SetInputAssembler(inputAssembler->GetInputAssemblerHandle(), + shader->GetShaderProgramHandle()); + } + + bool NVRenderContextImpl::ApplyPreDrawProperties() + { + // Get the currently bound vertex and shader + NVRenderInputAssembler *inputAssembler = this->m_HardwarePropertyContext.m_InputAssembler; + NVRenderShaderProgram *shader = this->m_HardwarePropertyContext.m_ActiveShader; + + // we could render through a program pipline + if (shader == NULL && this->m_HardwarePropertyContext.m_ActiveProgramPipeline) + shader = this->m_HardwarePropertyContext.m_ActiveProgramPipeline->GetVertexStage(); + + if (inputAssembler == NULL || shader == NULL) { + qCCritical(INVALID_OPERATION, + "Attempting to render no valid shader or input assembler setup"); + QT3DS_ASSERT(false); + return false; + } + + return BindShaderToInputAssembler(inputAssembler, shader); + } + + void NVRenderContextImpl::OnPostDraw() + { + // reset input assembler binding + m_backend->SetInputAssembler(NULL, 0); + // Texture unit 0 is used for setting up and loading textures. + // Bugs happen if we load a texture then setup the sampler. + // Then we load another texture. Because when loading we use texture unit 0, + // the render bindings for the first texture are blown away. + // Again, for this reason, texture unit 0 is reserved for loading textures. + m_NextTextureUnit = 1; + m_NextConstantBufferUnit = 0; + } + + void NVRenderContextImpl::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) + { + if (!ApplyPreDrawProperties()) + return; + + NVRenderIndexBuffer *theIndexBuffer = const_cast( + m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); + if (theIndexBuffer == NULL) + m_backend->Draw(drawMode, offset, count); + else + theIndexBuffer->Draw(drawMode, count, offset); + + OnPostDraw(); + } + + void NVRenderContextImpl::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) + { + if (!ApplyPreDrawProperties()) + return; + + NVRenderIndexBuffer *theIndexBuffer = const_cast( + m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer()); + if (theIndexBuffer == NULL) + m_backend->DrawIndirect(drawMode, (const void *)offset); + else + theIndexBuffer->DrawIndirect(drawMode, offset); + + OnPostDraw(); + } + + QT3DSMat44 + NVRenderContext::ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection, + const NVRenderRectF &inViewport, + const NVRenderRectF &inVirtualViewport) + { + if (inVirtualViewport == inViewport) + return inProjection; + // Run conversion to floating point once. + NVRenderRectF theVirtualViewport(inVirtualViewport); + NVRenderRectF theViewport(inViewport); + if (theVirtualViewport.m_Width == 0 || theVirtualViewport.m_Height == 0 + || theViewport.m_Width == 0 || theViewport.m_Height == 0) { + QT3DS_ASSERT(false); + return inProjection; + } + QT3DSMat44 theScaleTransMat(QT3DSMat44::createIdentity()); + QT3DSF32 theHeightDiff = theViewport.m_Height - theVirtualViewport.m_Height; + QT3DSF32 theViewportOffY = theVirtualViewport.m_Y - theViewport.m_Y; + QT3DSVec2 theCameraOffsets = QT3DSVec2(theVirtualViewport.m_Width - theViewport.m_Width + + (theVirtualViewport.m_X - theViewport.m_X) * 2.0f, + theHeightDiff + (theViewportOffY - theHeightDiff) * 2.0f); + QT3DSVec2 theCameraScale = QT3DSVec2(theVirtualViewport.m_Width / theViewport.m_Width, + theVirtualViewport.m_Height / theViewport.m_Height); + + QT3DSVec3 theTranslation(theCameraOffsets.x / theViewport.m_Width, + theCameraOffsets.y / theViewport.m_Height, 0); + theScaleTransMat.column3[0] = theTranslation.x; + theScaleTransMat.column3[1] = theTranslation.y; + theScaleTransMat.column0[0] = theCameraScale.x; + theScaleTransMat.column1[1] = theCameraScale.y; + + return theScaleTransMat * inProjection; + } + + NVRenderVertFragCompilationResult NVRenderContext::CompileSource( + const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, const char *fragShader, + QT3DSU32 inFragLen, const char *tessControlShaderSource, QT3DSU32 inTCLen, + const char *tessEvaluationShaderSource, QT3DSU32 inTELen, const char *geometryShaderSource, + QT3DSU32 inGSLen, bool separableProgram) + { + return CompileSource( + shaderName, NVConstDataRef((const QT3DSI8 *)vertShader, inVertLen), + NVConstDataRef((const QT3DSI8 *)fragShader, inFragLen), + NVConstDataRef((const QT3DSI8 *)tessControlShaderSource, inTCLen), + NVConstDataRef((const QT3DSI8 *)tessEvaluationShaderSource, inTELen), + NVConstDataRef((const QT3DSI8 *)geometryShaderSource, inGSLen), separableProgram); + } + + void NVRenderContextImpl::DoSetActiveShader(NVRenderShaderProgram *inShader) + { + m_HardwarePropertyContext.m_ActiveShader = NULL; + if (inShader) + m_backend->SetActiveProgram(inShader->GetShaderProgramHandle()); + else { + m_backend->SetActiveProgram(NULL); + } + m_HardwarePropertyContext.m_ActiveShader = inShader; + } + + void NVRenderContextImpl::DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) + { + if (inProgramPipeline) { + // invalid any bound shader + DoSetActiveShader(NULL); + inProgramPipeline->Bind(); + } else + m_backend->SetActiveProgramPipeline(NULL); + + m_HardwarePropertyContext.m_ActiveProgramPipeline = inProgramPipeline; + } + + NVRenderContext &NVRenderContext::CreateNULL(NVFoundationBase &foundation, + IStringTable &inStringTable) + { + NVRenderContext *retval = NULL; + + // create backend + NVScopedRefCounted theStringTable(inStringTable); + NVScopedRefCounted theBackend = + NVRenderBackendNULL::CreateBackend(foundation); + retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend, + *theStringTable); + return *retval; + } +} +} // end namespace -- cgit v1.2.3