CommandContext* RenderDeviceD3D12Impl::AllocateCommandContext(const Char *ID)
{
	std::lock_guard<std::mutex> LockGuard(m_ContextAllocationMutex);

	CommandContext* ret = nullptr;
	if (m_AvailableContexts.empty())
	{
        auto &CmdCtxAllocator = GetRawAllocator();
        auto *pRawMem = ALLOCATE(CmdCtxAllocator, "CommandContext instance", sizeof(CommandContext));
		ret = new (pRawMem) CommandContext( GetRawAllocator(), m_CmdListManager, m_GPUDescriptorHeaps, m_DynamicDescriptorAllocationChunkSize);
		m_ContextPool.emplace_back(ret, STDDeleterRawMem<CommandContext>(CmdCtxAllocator) );
	}
	else
	{
		ret = m_AvailableContexts.front();
		m_AvailableContexts.pop_front();
		ret->Reset(m_CmdListManager);
	}
	VERIFY_EXPR(ret != nullptr);
	ret->SetID(ID);
	//if ( ID != nullptr && *ID != 0 )
	//	EngineProfiling::BeginBlock(ID, NewContext);

	return ret;
}
void CommandListManager::RequestAllocator(ID3D12CommandAllocator** ppAllocator)
{
	std::lock_guard<std::mutex> LockGuard(m_AllocatorMutex);

    VERIFY( (*ppAllocator) == nullptr, "Allocator pointer is not null" );
    (*ppAllocator) = nullptr;

    if (!m_DiscardedAllocators.empty())
	{
		auto& AllocatorPair = m_DiscardedAllocators.front();

		if (m_pDeviceD3D12->IsFenceComplete(AllocatorPair.first))
		{
			*ppAllocator = AllocatorPair.second.Detach();
			auto hr = (*ppAllocator)->Reset();
            VERIFY_EXPR(SUCCEEDED(hr));
			m_DiscardedAllocators.pop_front();
		}
	}

	// If no allocators were ready to be reused, create a new one
	if ((*ppAllocator) == nullptr)
	{
        auto *pd3d12Device = m_pDeviceD3D12->GetD3D12Device();
		auto hr = pd3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(*ppAllocator), reinterpret_cast<void**>(ppAllocator));
        VERIFY(SUCCEEDED(hr), "Failed to create command allocator")
		//wchar_t AllocatorName[32];
		//swprintf(AllocatorName, 32, L"CommandAllocator %zu", m_AllocatorPool.size());
		//(*ppAllocator)->SetName(AllocatorName);
	}
    DynamicAllocation DynamicUploadHeap::Allocate(size_t SizeInBytes, size_t Alignment /*= DEFAULT_ALIGN*/)
    {
        // This is very expensive! Currently other threads cannot allocate dynamic 
        // data while frame is being finished.

        //std::lock_guard<std::mutex> Lock(m_Mutex);

	    const size_t AlignmentMask = Alignment - 1;
	    // Assert that it's a power of two.
	    VERIFY_EXPR((AlignmentMask & Alignment) == 0);
	    // Align the allocation
	    const size_t AlignedSize = (SizeInBytes + AlignmentMask) & ~AlignmentMask;
        auto DynAlloc = m_RingBuffers.back().Allocate(AlignedSize);
        if (!DynAlloc.pBuffer)
        {
            auto NewMaxSize = m_RingBuffers.back().GetMaxSize() * 2;
            while(NewMaxSize < SizeInBytes)NewMaxSize*=2;
            m_RingBuffers.emplace_back(NewMaxSize, m_Allocator, m_pDeviceD3D12->GetD3D12Device(), m_bIsCPUAccessible);
            DynAlloc = m_RingBuffers.back().Allocate(AlignedSize);
        }
#ifdef _DEBUG
        DynAlloc.FrameNum = m_pDeviceD3D12->GetCurrentFrame();
#endif
        return DynAlloc;
    }
CommandQueueD3D12Impl::CommandQueueD3D12Impl(IReferenceCounters *pRefCounters, ID3D12CommandQueue *pd3d12NativeCmdQueue, ID3D12Fence *pd3d12Fence) :
        TBase(pRefCounters),
        m_pd3d12CmdQueue(pd3d12NativeCmdQueue), 
        m_d3d12Fence(pd3d12Fence),
        m_NextFenceValue(1),
        m_WaitForGPUEventHandle( CreateEvent(nullptr, false, false, nullptr) )
{
    VERIFY_EXPR(m_WaitForGPUEventHandle != INVALID_HANDLE_VALUE);
    m_d3d12Fence->Signal(0);
}
Exemplo n.º 5
0
static TextureDesc GetTextureDescFromGLHandle(DeviceContextGLImpl *pDeviceContextGL, TextureDesc TexDesc, GLuint GLHandle, GLenum BindTarget)
{
    auto &ContextState = pDeviceContextGL->GetContextState();
    
    VERIFY(BindTarget != GL_TEXTURE_CUBE_MAP_ARRAY, "Cubemap arrays are not currently supported")

    GLObjectWrappers::GLTextureObj TmpGLTexWrapper(true, GLObjectWrappers::GLTextureCreateReleaseHelper(GLHandle));
    ContextState.BindTexture(-1, BindTarget, TmpGLTexWrapper);

    GLenum QueryBindTarget = BindTarget;
    if (BindTarget == GL_TEXTURE_CUBE_MAP)
        QueryBindTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;

    GLint TexWidth = 0, TexHeight = 0, TexDepth = 0;
    glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_WIDTH, &TexWidth);
    if (TexDesc.Type >= RESOURCE_DIM_TEX_2D)
        glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_HEIGHT, &TexHeight);
    else
        TexHeight = 1;

    if (TexDesc.Type == RESOURCE_DIM_TEX_3D)
        glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_DEPTH, &TexDepth);
    else
        TexDepth = 1;
    
    GLint GlFormat = 0;
    glGetTexLevelParameteriv(QueryBindTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &GlFormat);
    CHECK_GL_ERROR( "Failed to get texture level 0 parameters through glGetTexLevelParameteriv()" );

    VERIFY(GlFormat != 0, "Unable to get texture format")
    if (TexDesc.Format != TEX_FORMAT_UNKNOWN)
        VERIFY(static_cast<GLenum>(GlFormat) == TexFormatToGLInternalTexFormat(TexDesc.Format), "Specified texture format (", GetTextureFormatAttribs(TexDesc.Format).Name,") does not match GL texture internal format (", GlFormat, ")")
    else
        TexDesc.Format = GLInternalTexFormatToTexFormat(GlFormat);

    VERIFY_EXPR(TexWidth > 0 && TexHeight > 0 && TexDepth > 0);
    VERIFY(TexDesc.Width == 0 || TexDesc.Width == static_cast<Uint32>(TexWidth), "Specified texture width (", TexDesc.Width, ") does not match the actual width (", TexWidth, ")");
    VERIFY(TexDesc.Height == 0 || TexDesc.Height == static_cast<Uint32>(TexHeight), "Specified texture height (", TexDesc.Height,") does not match the actual height (", TexHeight, ")");
    TexDesc.Width = static_cast<Uint32>(TexWidth);
    TexDesc.Height = static_cast<Uint32>(TexHeight);
    if (TexDesc.Type == RESOURCE_DIM_TEX_3D)
    {
        VERIFY(TexDesc.Depth == 0 || TexDesc.Depth == static_cast<Uint32>(TexDepth), "Specified texture depth (", TexDesc.Depth, ") does not match the actual depth (", TexDepth, ")");
        TexDesc.Depth = static_cast<Uint32>(TexDepth);
    }

    GLint MipLevels = 0;
    glGetTexParameteriv(BindTarget, GL_TEXTURE_IMMUTABLE_LEVELS, &MipLevels);
    CHECK_GL_ERROR( "Failed to get texture parameters through glGetTexParameteriv()" );
    VERIFY(TexDesc.MipLevels == 0 || TexDesc.MipLevels == static_cast<Uint32>(MipLevels), "Specified number of mip levels (", TexDesc.MipLevels, ") does not match the actual number of mip levels (", MipLevels, ")");
    TexDesc.MipLevels = static_cast<Uint32>(MipLevels);
    
    ContextState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false) );
    return TexDesc;
}
void CommandContext::FlushResourceBarriers()
{
	if (m_PendingResourceBarriers.empty())
    {
        VERIFY_EXPR(m_PendingBarrierObjects.empty());
		return;
    }

	m_pCommandList->ResourceBarrier(static_cast<UINT>(m_PendingResourceBarriers.size()), m_PendingResourceBarriers.data());
	m_PendingResourceBarriers.clear();
    m_PendingBarrierObjects.clear();
}
ID3D12GraphicsCommandList* CommandContext::Close(ID3D12CommandAllocator **ppAllocator)
{
	FlushResourceBarriers();

	//if (m_ID.length() > 0)
	//	EngineProfiling::EndBlock(this);

	VERIFY_EXPR(m_pCurrentAllocator != nullptr);
	auto hr = m_pCommandList->Close();
    VERIFY(SUCCEEDED(hr), "Failed to close the command list");

    *ppAllocator = m_pCurrentAllocator.Detach();
    return m_pCommandList;
}
void CreateImageFromFile( const Diligent::Char *FilePath, 
                          Image **ppImage,
                          IDataBlob **ppDDSData)
{
    auto *pDotPos = strrchr( FilePath, '.' );
    if( pDotPos == nullptr )
        LOG_ERROR_AND_THROW( "File path ", FilePath, " does not contain extension" );

    auto *pExtension = pDotPos + 1;
    if( *pExtension == 0 )
        LOG_ERROR_AND_THROW( "File path ", FilePath, " contains empty extension" );

    String Extension(pExtension);
    std::transform( Extension.begin(), Extension.end(), Extension.begin(), ::tolower );

    Diligent::RefCntAutoPtr<BasicFileStream> pFileStream( new BasicFileStream( FilePath, EFileAccessMode::Read ) );

    if( Extension == "dds" )
    {
        VERIFY_EXPR(ppDDSData != nullptr);
        *ppDDSData = new DataBlobImpl;
        pFileStream->Read(*ppDDSData);
        (*ppDDSData)->AddRef();
    }
    else
    {
        ImageLoadInfo ImgLoadInfo;
        if( Extension == "png" )
            ImgLoadInfo.Format = EImageFileFormat::png;
        else if( Extension == "jpeg" || Extension == "jpg" )
            ImgLoadInfo.Format = EImageFileFormat::jpeg;
        else if( Extension == "tiff" || Extension == "tif" )
            ImgLoadInfo.Format = EImageFileFormat::tiff;
        else
            LOG_ERROR_AND_THROW( "Unsupported file format ", Extension );

        *ppImage = new Image(pFileStream, ImgLoadInfo);
        (*ppImage)->AddRef();
    }
}
void CommandContext::TransitionResource(IBufferD3D12 *pBuffer, D3D12_RESOURCE_STATES NewState, bool FlushImmediate)
{
    VERIFY_EXPR( pBuffer != nullptr );
    auto *pBuffD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer);

#ifdef _DEBUG
    // Dynamic buffers are suballocated in the upload heap when Map() is called 
    // and must always be in D3D12_RESOURCE_STATE_GENERIC_READ state
    if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC)
    {
        VERIFY(pBuffD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state")
        VERIFY( (NewState & D3D12_RESOURCE_STATE_GENERIC_READ) == NewState, "Dynamic buffers can only transition to one of D3D12_RESOURCE_STATE_GENERIC_READ states")
    }
#endif

    TransitionResource(*pBuffD3D12, *pBuffD3D12, NewState, FlushImmediate);

#ifdef _DEBUG
    if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC)
        VERIFY(pBuffD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to never transition from D3D12_RESOURCE_STATE_GENERIC_READ state")
#endif
}
Exemplo n.º 10
0
static BufferDesc GetBufferDescFromGLHandle(BufferDesc BuffDesc, GLuint BufferHandle)
{
    // NOTE: the operations in this function are merely for debug purposes.
    // If binding a buffer to a target does not work, these operations can be skipped
    GLenum BindTarget = GetBufferBindTarget(BuffDesc);

    glBindBuffer(BindTarget, BufferHandle);
    CHECK_GL_ERROR("Failed to bind GL buffer to ", BindTarget, " target");

    GLint BufferSize = 0;
    glGetBufferParameteriv(BindTarget, GL_BUFFER_SIZE, &BufferSize);
    CHECK_GL_ERROR("glGetBufferParameteriv() failed");
    VERIFY_EXPR(BufferSize > 0);

    VERIFY(BuffDesc.uiSizeInBytes == 0 || BuffDesc.uiSizeInBytes == static_cast<Uint32>(BufferSize), "Buffer size specified by the BufferDesc (", BuffDesc.uiSizeInBytes, ") does not match the size recovered from gl buffer object (", BufferSize, ")");
    if(BufferSize > 0)
        BuffDesc.uiSizeInBytes = static_cast<Uint32>( BufferSize );

    glBindBuffer(BindTarget, 0);
    CHECK_GL_ERROR("Failed to unbind GL buffer");

    return BuffDesc;
}
void CommandContext::TransitionResource(ITextureD3D12 *pTexture, D3D12_RESOURCE_STATES NewState, bool FlushImmediate)
{
    VERIFY_EXPR( pTexture != nullptr );
    auto *pTexD3D12 = ValidatedCast<TextureD3D12Impl>(pTexture);
    TransitionResource(*pTexD3D12, *pTexD3D12, NewState, FlushImmediate);
}