Advertisement

How to Upload alpha texture to compute shader

Started by May 09, 2019 11:27 PM
3 comments, last by Esentiel 5 years, 8 months ago

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

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

Advertisement

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?

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

This topic is closed to new replies.

Advertisement