Jump to content
  • Advertisement
Esentiel

DX12 How to Upload alpha texture to compute shader

Recommended Posts

Posted (edited)

Hello!

What am I trying to do is blur mask. Say I would like to have everything blurred EXCEPT circle in the middle(you can observe such in shooter games, while aiming).

In my vision, to support masked blurring, I have to have such mask as a 2d texture with alpha channel values indicating whether we blur pixel or not.

The problem here, I can't upload alpha texture(only alpha channel exists(DXGI_FORMAT_A8_UNORM)) to shader. For every pixel I checked alpha in shader, I got 0.

I attached code of creation and using shader resource.

Here is how I use this texture in shader:

Spoiler

Texture2D gMask            : register(t1);

if (gMask[int2(0,0)].a > 0)
{
  // simple check that there is no 0 at 0,0 
}

 

Code where I create descriptors:

Spoiler

	const int textureDescriptorCount = 1;
	const int blurDescriptorCount = 4;
	THROW_IF_NOK(m_cmdAllocator->Reset());
	THROW_IF_NOK(m_cmdList->Reset(m_cmdAllocator.Get(), nullptr));

	m_srvHeap = CreateDescHeap(EDescHeapType::DHT_SRV, textureDescriptorCount + blurDescriptorCount + 1/*blurmask*/);
	m_cbvSrvUavDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
	CD3DX12_CPU_DESCRIPTOR_HANDLE hDescriptor(m_srvHeap->GetCPUDescriptorHandleForHeapStart());
	
	DirectX::CreateDDSTextureFromFile12(m_device.Get(), m_cmdList.Get(), L"../Bin/Debug/Arissa_DIFF_diffuse_PNG_BC7_1.DDS", m_textureRes, m_texUplHeap);

	D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
	srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
	srvDesc.Format = m_textureRes->GetDesc().Format;
	srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
	srvDesc.Texture2D.MostDetailedMip = 0;
	srvDesc.Texture2D.MipLevels = m_textureRes->GetDesc().MipLevels;
	srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;

	m_device->CreateShaderResourceView(m_textureRes.Get(), &srvDesc, hDescriptor);	

	// Blur
	m_blurFilter->BuildDescriptors(
		CD3DX12_CPU_DESCRIPTOR_HANDLE(m_srvHeap->GetCPUDescriptorHandleForHeapStart(), 1, m_cbvSrvUavDescriptorSize), 
		CD3DX12_GPU_DESCRIPTOR_HANDLE(m_srvHeap->GetGPUDescriptorHandleForHeapStart(), 1, m_cbvSrvUavDescriptorSize), 
		m_cbvSrvUavDescriptorSize);
	//

 

Root Signature:

Spoiler

void RenderEngine::CreateRootDescriptionForBlur()
{
	CD3DX12_DESCRIPTOR_RANGE srvTable;
	srvTable.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);

	CD3DX12_DESCRIPTOR_RANGE uavTable;
	uavTable.Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0);

	CD3DX12_DESCRIPTOR_RANGE srvTable2;
	srvTable2.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1);

	CD3DX12_ROOT_PARAMETER slotRootParameter[4];

	slotRootParameter[0].InitAsConstants(14, 0);
	slotRootParameter[1].InitAsDescriptorTable(1, &srvTable);
	slotRootParameter[2].InitAsDescriptorTable(1, &uavTable);
	slotRootParameter[3].InitAsDescriptorTable(1, &srvTable2);

	CD3DX12_ROOT_SIGNATURE_DESC rootSigDesc(4, slotRootParameter,
		0, nullptr,
		D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

	ComPtr<ID3DBlob> serializedRootSig = nullptr;
	ComPtr<ID3DBlob> errorBlob = nullptr;
	HRESULT hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1,
		serializedRootSig.GetAddressOf(), errorBlob.GetAddressOf());

	if (errorBlob != nullptr)
	{
		::OutputDebugStringA((char*)errorBlob->GetBufferPointer());
	}
	THROW_IF_NOK(hr);

	THROW_IF_NOK(m_device->CreateRootSignature(
		0,
		serializedRootSig->GetBufferPointer(),
		serializedRootSig->GetBufferSize(),
		IID_PPV_ARGS(m_rootSignatures["blur"].GetAddressOf())));
}

 

 

And lastly part of code in Render() method related to Blur:

Spoiler

// Blur here
	auto blurMsk = renderScene->GetBlurMask();
	m_blurFilter->SetBlurMask(blurMsk.c_str(), m_cmdList.Get());
	m_blurFilter->Execute(m_cmdList.Get(), m_rootSignatures["blur"].Get(),
		m_PSOs["horzBlur"].Get(), m_PSOs["vertBlur"].Get(), backBuffer.Get(), 4, blurMsk);

	// Prepare to copy blurred output to the back buffer.
	m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(backBuffer.Get(),
		D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST));

	m_cmdList->CopyResource(backBuffer.Get(), m_blurFilter->Output());

	m_blurFilter->ResetResources(m_cmdList.Get());
	//

	/// present
	TransitionResource(m_cmdList, backBuffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PRESENT);

 

I assume I failed somewhere in code of creation\uploading texture. That code I took partially from here - https://github.com/microsoft/DirectXTex/blob/master/DDSTextureLoader/DDSTextureLoader12.cpp

I can't sleep and hardly eat, because of this issue, will appreciate any help.

 

Thanks

BlurFilter.h

BlurFilter.cpp

Edited by Esentiel

Share this post


Link to post
Share on other sites
Advertisement

UPDATE:

instead of loading picture(TIF) using freeImage and then from memory to Resource, I used DDSLoader from MS GitHub.

Now it works! Seems like LoadWICTextureFromFile() doesn't work either. Will check TGA later.

 

Thanks

Share this post


Link to post
Share on other sites

I don't know for sure but DXGI_FORMAT_A8_UNORM doesn't that mean one byte per texel so, wont it be .r/.x not .a/.w? Did the fix make a 32 bit texture?

Share this post


Link to post
Share on other sites
Posted (edited)

I've tried 3 approaches:

1. Load image(tif) data using FreeImage, and store only alpha channels data in an array. Then tried to pass it to Resource (code is in attached file BlurFilter.cpp -> SetBlurMask() method). here I used DXGI_FORMAT_A8_UNORM.

RESULT: I could get proper values in shader from GetDimensions(), but (.a > 0) always returns false.

2. Load image using DirectX::LoadWICTextureFromFile() . There were 32 bits per texel.

Spoiler

	std::unique_ptr<uint8_t[]> wicData;
	D3D12_SUBRESOURCE_DATA subresource;
	HRESULT hr = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
	auto resss = DirectX::LoadWICTextureFromFile(md3dDevice, L"../Resources/textures/blurmap_.tif", mBlurMask.GetAddressOf(), wicData, subresource);

THROW_IF_NOK(md3dDevice->CreateCommittedResource(
		&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
		D3D12_HEAP_FLAG_NONE,
		&CD3DX12_RESOURCE_DESC::Buffer(subresource.SlicePitch),
		D3D12_RESOURCE_STATE_GENERIC_READ,
		nullptr,
		IID_PPV_ARGS(mBlurMaskUpl.GetAddressOf())));

	UpdateSubresources(cmdList,
		mBlurMask.Get(), mBlurMaskUpl.Get(),
		0, 0, 1, &subresource);

cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mBlurMask.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON));

 

RESULT: Same as above, nor (.a >0) nor (.r > 0) always returns false.

3. Load texture using DirectX::CreateDDSTextureFromFile12(). There were 32 bits as well.

Spoiler

DirectX::CreateDDSTextureFromFile12(md3dDevice, cmdList, L"../Bin/Debug/1111_TGA_BC7_1.DDS", mBlurMask, mBlurMaskUpl);

cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mBlurMask.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON));

 

RESULT: (.a >0) always returns true, (.a > 0.1) returns true only when it was expected)

 

LoadWICTextureFromFile() and CreateDDSTextureFromFile12() I copied from https://github.com/microsoft/DirectXTex

 

Thanks

Edited by Esentiel

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!