Jump to content
  • Advertisement
Sign in to follow this  
MrNia

[Question]Multithread Loading in DirectX 11

This topic is 596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. 

 

 

I'm Just Studying With DirectX 11.

 

 

 

I Studying make Mulitithread Loading. but it has a problem.

 

 

 

 

it is Multithread Loading codes.

CLoading::CLoading(LOADINGID eLoadID)
	: m_eLoadID(eLoadID)
	, m_hThread(NULL)
	, m_bComplete(false)
{
	ZeroMemory(m_szLoadMessage, sizeof(TCHAR) * 128);
	ZeroMemory(&m_CSKey, sizeof(CRITICAL_SECTION));
}

CLoading::~CLoading(void)
{

}

bool CLoading::GetComplete(void)
{
	return m_bComplete;
}

const TCHAR* CLoading::GetLoadMessage(void)
{
	return m_szLoadMessage;
}

HRESULT CLoading::InitLoading(void)
{
	InitializeCriticalSection(&m_CSKey);

	m_hThread = (HANDLE)_beginthreadex(NULL, 0, LoadingFunction, this, 0, NULL);
	if (m_hThread == NULL)
		return E_FAIL;

	return S_OK;
}

void CLoading::StageLoading(void)
{
	HRESULT hr = NULL;

	//lstrcpy(m_szLoadMessage, L"Teature Loading...");
	cout << "TextureLoading" << endl;
	//Texture
	hr = CResourcesMgr::GetInstance()->AddTexture(
		RESOURCE_STAGE
		, L"Texture_Town"
		, L"../Resource/MeshImage/Town.png");
	FAILED_CHECK_RETURN(hr, );

	hr = CResourcesMgr::GetInstance()->AddTexture(
		RESOURCE_STAGE
		, L"Texture_Flower"
		, L"../Resource/Flower.png");
	FAILED_CHECK_RETURN(hr, );

	hr = CResourcesMgr::GetInstance()->AddTexture(
		RESOURCE_STAGE
		, L"Texture_Player"
		, L"../Resource/MeshImage/Player.png");


	//lstrcpy(m_szLoadMessage, L"Buffer Loading...");
	cout << "StaticBufferLoading" << endl;
	//Buffer
	hr = CResourcesMgr::GetInstance()->AddMesh(
		RESOURCE_STAGE,
		MESH_STATIC
		, L"Mesh_Town"
		, "../Resource/Mesh/"
		, "Town.FBX");
	FAILED_CHECK_RETURN(hr, );


	cout << "DynamicBufferLoading" << endl;
	vector<string> vecAni;

	

	vecAni.push_back("Player");

	hr = CResourcesMgr::GetInstance()->AddMesh(
		RESOURCE_STAGE,
		MESH_DYNAMIC,
		L"Player_IDLE",
		"../Resource/Mesh/",
		"",vecAni);
	FAILED_CHECK_RETURN(hr, );
	

	CAnimationMgr::GetInstance()->AddAnimation(L"Player", &vecAni);

	vecAni.clear();
	
	cout << "SceneLoading" << endl;

	CScene* pScene = NULL;
	
	pScene = CStage::Create();
	CSceneMgr::GetInstance()->AddScene(SCENE_STAGE, pScene);

	//lstrcpy(m_szLoadMessage, L"Loading End...");
	cout << "Loading End" << endl;
	m_bComplete = true;
}

CLoading* CLoading::Create(LOADINGID eLoadID)
{
	CLoading*	pLoading = new CLoading(eLoadID);
	if (FAILED(pLoading->InitLoading()))
		::Safe_Release(pLoading);

	return pLoading;
}

UINT WINAPI CLoading::LoadingFunction(void* pArg)
{
	CLoading*		pLoading = (CLoading*)pArg;

	switch (pLoading->m_eLoadID)
	{
	case CLoading::LOADING_STAGE:
		pLoading->StageLoading();
		break;

	case CLoading::LOADING_STAGE1:
		break;
	}
	return 0;
}

void CLoading::Release(void)
{
	DeleteCriticalSection(&m_CSKey);
	WaitForSingleObject(m_hThread, INFINITE);
	CloseHandle(m_hThread);
} 

it is Dynamic Mesh(Animation Mesh) Load codes.

HRESULT CDynamicMesh::Load_Model(const char* _pPath, vector<string> _vecAniName, FbxManager* _pFBXManager, FbxIOSettings* _pIOsettings,
									FbxScene* _pFBXScene, FbxImporter* _pImporter)
{
       {
	//Animation Mesh Create Codes.
        }

		//Animation Constant Buffer
		{
			
			D3D11_BUFFER_DESC BD;
			::ZeroMemory(&BD, sizeof(D3D11_BUFFER_DESC));
			BD.Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC;
			BD.ByteWidth = sizeof(VS_CB_BONE_MATRIX);
			BD.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
			BD.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE;

			m_pGrapicDevice->m_pDevice->CreateBuffer(&BD, NULL, &pAni->pBoneMatrixBuffer);

                        //Problem Part.
			m_pGrapicDevice->m_pDeviceContext->Map(pAni->pBoneMatrixBuffer,	NULL, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, NULL, &pAni->tMappedResource);

			pAni->pBoneMatrix = (VS_CB_BONE_MATRIX *)pAni->tMappedResource.pData;

			for (int i = 0; i < BONE_MATRIX_NUM; i++)
				pAni->pBoneMatrix->m_XMmtxBone[i] = XMMatrixIdentity();

			m_pGrapicDevice->m_pDeviceContext->Unmap(pAni->pBoneMatrixBuffer, NULL);
                        //Problem Part Ends.
		}

		CFbxParser::ParsingAnimation(pFbxRootNode, pAni, AnimStack);


		//XMMATRIX ResultMtx;
		for (long long i = 0; i < pAni->llAniMaxTime / 10; ++i)
		{
			for (unsigned int j = 0; j < pAni->nAniNodeIdxCnt; ++j)
			{
				XMMATRIX ResultMtx(pAni->pBaseBoneMatrix[j] * (XMMATRIX)(pAni->ppAniMatrix[i][j]));
				pAni->ppResultMatrix[i][j] = ResultMtx;
			}
		}

		m_vecAni.push_back(pAni);
	}

	return S_OK;
}

I was studied Multithread Loading in DirectX 9 

 

It didn't matter when it was written there.

 

 

but i put it in DirectX11, and there was a problem in that area.

 

 

I know what is problem. it is m_pGrapicDevice->m_pDeviceContext->Map().

 

That Funtion is dosn't support Multithread. 

 

 

so How to solve this problem....

 

I can't figure out how to solve the problem

 

 

I'd appreciate it if you could help me.

Edited by MrNia

Share this post


Link to post
Share on other sites
Advertisement
As Adam said, the new way of doing this in D3D11 is with the "initial data" parameter.

However, if you want to do it the old way (with Map), then you are able to create more than one context. The "main thread" owns the "immediate context", while your "loading thread" owns a "deferred context".
The loading thread can then use Map/Unmap on the deferred context.

Share this post


Link to post
Share on other sites

The D3D11 resource creation functions (CreateBuffer, CreateTexture[1|2|3]D) all have a second argument called "initialData". If you want to initialise a resource with data at the point that you create it then you should use this instead of trying to Map and Unmap the resource using a context. D3D device creation functions are thread-safe.

 

 

i tried like this

{
			
			D3D11_BUFFER_DESC BD;
			::ZeroMemory(&BD, sizeof(D3D11_BUFFER_DESC));
			BD.Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC;
			BD.ByteWidth = sizeof(VS_CB_BONE_MATRIX);
			BD.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
			BD.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE;

			
			pAni->tMappedResource.pSysMem = pAni->pAniBuffer->m_pVertex;
			pAni->tMappedResource.SysMemPitch = 0;
			pAni->tMappedResource.SysMemSlicePitch = 0;
			
			pAni->pBoneMatrix = (VS_CB_BONE_MATRIX *)pAni->tMappedResource.pSysMem;

			for (int i = 0; i < BONE_MATRIX_NUM; i++)
				pAni->pBoneMatrix->m_XMmtxBone[i] = XMMatrixIdentity();

			//D3D11_SUBRESOURCE_DATA InitData;
			//InitData.pSysMem = pAni->tMappedResource.pSysMem;
			

			m_pGrapicDevice->m_pDevice->CreateBuffer(&BD, &pAni->tMappedResource, &pAni->pBoneMatrixBuffer);

			//m_pGrapicDevice->m_pDeviceContext->Map(pAni->pBoneMatrixBuffer,	NULL, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, NULL, &pAni->tMappedResource);

			

			//m_pGrapicDevice->m_pDeviceContext->Unmap(pAni->pBoneMatrixBuffer, NULL);
		}

i changed D3D11_MAPPED_SUBRESOURCE tMappedResource to D3D11_SUBRESOURCE_DATA tMappedResource.

 

 

it works rendering mesh, but not work animation.

 

 

Is there something i missed???

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!