Exemple #1
0
	void D3D12Texture3D::Map3D(uint32_t array_index, uint32_t level, TextureMapAccess tma,
			uint32_t x_offset, uint32_t y_offset, uint32_t z_offset,
			uint32_t width, uint32_t height, uint32_t depth,
			void*& data, uint32_t& row_pitch, uint32_t& slice_pitch)
	{
		uint32_t const subres = CalcSubresource(level, array_index, 0, num_mip_maps_, array_size_);
		this->DoMap(subres, tma, x_offset, y_offset, z_offset, width, height, depth, data, row_pitch, slice_pitch);
	}
	void D3D12TextureCube::MapCube(uint32_t array_index, CubeFaces face, uint32_t level, TextureMapAccess tma,
			uint32_t x_offset, uint32_t y_offset, uint32_t width, uint32_t height,
			void*& data, uint32_t& row_pitch)
	{
		uint32_t const subres = CalcSubresource(level, array_index * 6 + face - CF_Positive_X, 0, num_mip_maps_, array_size_);

		uint32_t slice_pitch;
		this->DoMap(subres, tma, x_offset, y_offset, 0, width, height, 1, data, row_pitch, slice_pitch);
	}
	void D3D12TextureCube::CopyToSubTextureCube(Texture& target,
			uint32_t dst_array_index, CubeFaces dst_face, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height,
			uint32_t src_array_index, CubeFaces src_face, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height)
	{
		BOOST_ASSERT(type_ == target.Type());

		if ((src_width == dst_width) && (src_height == dst_height) && (this->Format() == target.Format()))
		{
			uint32_t const src_subres = CalcSubresource(src_level, src_array_index * 6 + src_face - CF_Positive_X, 0,
				this->NumMipMaps(), this->ArraySize() * 6);
			uint32_t const dst_subres = CalcSubresource(dst_level, dst_array_index * 6 + dst_face - CF_Positive_X, 0,
				target.NumMipMaps(), target.ArraySize() * 6);

			this->DoHWCopyToSubTexture(target, dst_subres, dst_x_offset, dst_y_offset, 0,
				src_subres, src_x_offset, src_y_offset, 0,
				src_width, src_height, 1);
		}
		else
		{
			this->ResizeTextureCube(target, dst_array_index, dst_face, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height,
				src_array_index, src_face, src_level, src_x_offset, src_y_offset, src_width, src_height, true);
		}
	}
	void D3D12TextureCube::CopyToSubTexture2D(Texture& target,
			uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height,
			uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height)
	{
		BOOST_ASSERT((TT_2D == target.Type()) || (TT_Cube == target.Type()));

		if ((src_width == dst_width) && (src_height == dst_height) && (this->Format() == target.Format()))
		{
			uint32_t const src_subres = CalcSubresource(src_level, src_array_index, 0,
				this->NumMipMaps(), this->ArraySize() * 6);
			uint32_t const dst_subres = CalcSubresource(dst_level, dst_array_index, 0,
				target.NumMipMaps(), target.ArraySize() * 6);

			this->DoHWCopyToSubTexture(target, dst_subres, dst_x_offset, dst_y_offset, 0,
				src_subres, src_x_offset, src_y_offset, 0,
				src_width, src_height, 1);
		}
		else
		{
			this->ResizeTexture2D(target, dst_array_index, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height,
				src_array_index, src_level, src_x_offset, src_y_offset, src_width, src_height, true);
		}
	}
	void D3D12TextureCube::BuildMipSubLevels()
	{
		// TODO
		// Depth stencil formats
		// Compression formats
		if (IsDepthFormat(format_) || IsCompressedFormat(format_))
		{
			for (uint32_t index = 0; index < this->ArraySize(); ++ index)
			{
				for (int f = 0; f < 6; ++ f)
				{
					CubeFaces const face = static_cast<CubeFaces>(f);
					for (uint32_t level = 1; level < this->NumMipMaps(); ++ level)
					{
						this->ResizeTextureCube(*this, index, face, level, 0, 0, this->Width(level), this->Height(level),
							index, face, level - 1, 0, 0, this->Width(level - 1), this->Height(level - 1), true);
					}
				}
			}
		}
		else
		{
			D3D12RenderEngine& re = *checked_cast<D3D12RenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
			ID3D12Device*device = re.D3DDevice();
			ID3D12GraphicsCommandList* cmd_list = re.D3DRenderCmdList();

			auto const & effect = *re.BlitEffect();
			auto const & tech = *re.BilinearBlitTech();
			auto& pass = tech.Pass(0);
			pass.Bind(effect);
			D3D12ShaderObject& d3d12_so = *checked_cast<D3D12ShaderObject*>(pass.GetShaderObject(effect).get());

			D3D12RenderLayout& d3d12_rl = *checked_cast<D3D12RenderLayout*>(re.PostProcessRenderLayout().get());

			D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
			d3d12_so.UpdatePsoDesc(pso_desc);

			pso_desc.StreamOutput.pSODeclaration = nullptr;
			pso_desc.StreamOutput.NumEntries = 0;
			pso_desc.StreamOutput.pBufferStrides = nullptr;
			pso_desc.StreamOutput.NumStrides = 0;
			pso_desc.StreamOutput.RasterizedStream = 0;

			pso_desc.BlendState = checked_pointer_cast<D3D12RenderStateObject>(pass.GetRenderStateObject())->D3DBlendDesc();
			pso_desc.SampleMask = 0xFFFFFFFF;
			pso_desc.RasterizerState = checked_pointer_cast<D3D12RenderStateObject>(pass.GetRenderStateObject())->D3DRasterizerDesc();
			pso_desc.DepthStencilState = checked_pointer_cast<D3D12RenderStateObject>(pass.GetRenderStateObject())->D3DDepthStencilDesc();
			pso_desc.InputLayout.pInputElementDescs = &d3d12_rl.InputElementDesc()[0];
			pso_desc.InputLayout.NumElements = static_cast<UINT>(d3d12_rl.InputElementDesc().size());
			pso_desc.IBStripCutValue = (EF_R16UI == d3d12_rl.IndexStreamFormat())
				? D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF : D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF;

			RenderLayout::topology_type tt = d3d12_rl.TopologyType();
			pso_desc.PrimitiveTopologyType = D3D12Mapping::MappingPriTopoType(tt);

			pso_desc.NumRenderTargets = 1;
			pso_desc.RTVFormats[0] = dxgi_fmt_;
			for (uint32_t i = pso_desc.NumRenderTargets; i < std::size(pso_desc.RTVFormats); ++ i)
			{
				pso_desc.RTVFormats[i] = DXGI_FORMAT_UNKNOWN;
			}
			pso_desc.DSVFormat = DXGI_FORMAT_UNKNOWN;
			pso_desc.SampleDesc.Count = 1;
			pso_desc.SampleDesc.Quality = 0;
			pso_desc.NodeMask = 0;
			pso_desc.CachedPSO.pCachedBlob = nullptr;
			pso_desc.CachedPSO.CachedBlobSizeInBytes = 0;
			pso_desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;

			ID3D12PipelineStatePtr const & pso = re.CreateRenderPSO(pso_desc);

			re.SetPipelineState(pso.get());
			re.SetGraphicsRootSignature(d3d12_so.RootSignature());

			ID3D12DescriptorHeapPtr cbv_srv_uav_heap = re.CreateDynamicCBVSRVUAVDescriptorHeap(array_size_ * 6 * (num_mip_maps_ - 1));
			auto sampler_heap = d3d12_so.SamplerHeap();

			std::array<ID3D12DescriptorHeap*, 2> heaps;
			uint32_t num_heaps = 0;
			{
				heaps[num_heaps] = cbv_srv_uav_heap.get();
				++ num_heaps;
			}
			if (sampler_heap)
			{
				heaps[num_heaps] = sampler_heap;
				++ num_heaps;
			}
			re.SetDescriptorHeaps(ArrayRef<ID3D12DescriptorHeap*>(heaps.data(), num_heaps));

			if (sampler_heap)
			{
				D3D12_GPU_DESCRIPTOR_HANDLE gpu_sampler_handle = sampler_heap->GetGPUDescriptorHandleForHeapStart();
				cmd_list->SetGraphicsRootDescriptorTable(1, gpu_sampler_handle);
			}

			D3D12GraphicsBuffer& vb = *checked_cast<D3D12GraphicsBuffer*>(d3d12_rl.GetVertexStream(0).get());

			D3D12_VERTEX_BUFFER_VIEW vbv;
			vbv.BufferLocation = vb.GPUVirtualAddress();
			vbv.SizeInBytes = vb.Size();
			vbv.StrideInBytes = d3d12_rl.VertexSize(0);

			re.IASetVertexBuffers(0, vbv);

			re.IASetPrimitiveTopology(tt);

			D3D12_VIEWPORT vp;
			vp.TopLeftX = 0;
			vp.TopLeftY = 0;
			vp.MinDepth = 0;
			vp.MaxDepth = 1;

			D3D12_RECT scissor_rc;
			scissor_rc.left = 0;
			scissor_rc.top = 0;

			D3D12_RESOURCE_BARRIER barrier;
			barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
			barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;

			D3D12_CPU_DESCRIPTOR_HANDLE cpu_cbv_srv_uav_handle = cbv_srv_uav_heap->GetCPUDescriptorHandleForHeapStart();
			D3D12_GPU_DESCRIPTOR_HANDLE gpu_cbv_srv_uav_handle = cbv_srv_uav_heap->GetGPUDescriptorHandleForHeapStart();
			uint32_t const srv_desc_size = re.CBVSRVUAVDescSize();
			for (uint32_t index = 0; index < array_size_; ++ index)
			{
				for (int f = 0; f < 6; ++ f)
				{
					for (uint32_t level = 1; level < num_mip_maps_; ++ level)
					{
						cmd_list->SetGraphicsRootDescriptorTable(0, gpu_cbv_srv_uav_handle);

						UINT n = 0;
						D3D12_RESOURCE_BARRIER barriers[2];
						if (this->UpdateResourceBarrier(CalcSubresource(level - 1, index * 6 + f, 0, num_mip_maps_, array_size_),
							barrier, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE))
						{
							barriers[n] = barrier;
							++ n;
						}
						if (this->UpdateResourceBarrier(CalcSubresource(level, index * 6 + f, 0, num_mip_maps_, array_size_),
							barrier, D3D12_RESOURCE_STATE_RENDER_TARGET))
						{
							barriers[n] = barrier;
							++ n;
						}
						if (n > 0)
						{
							cmd_list->ResourceBarrier(n, barriers);
						}

						D3D12_CPU_DESCRIPTOR_HANDLE const & rt_handle = this->RetriveD3DRenderTargetView(index * 6 + f, 1, level)->Handle();

						D3D12_CPU_DESCRIPTOR_HANDLE const & sr_handle = this->RetriveD3DShaderResourceView(index * 6 + f, 1, level - 1, 1)->Handle();
						device->CopyDescriptorsSimple(1, cpu_cbv_srv_uav_handle, sr_handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

						cmd_list->OMSetRenderTargets(1, &rt_handle, false, nullptr);

						vp.Width = static_cast<float>(this->Width(level));
						vp.Height = static_cast<float>(this->Height(level));
						re.RSSetViewports(1, &vp);

						scissor_rc.right = this->Width(level);
						scissor_rc.bottom = this->Height(level);
						re.RSSetScissorRects(scissor_rc);

						cmd_list->DrawInstanced(4, 1, 0, 0);

						cpu_cbv_srv_uav_handle.ptr += srv_desc_size;
						gpu_cbv_srv_uav_handle.ptr += srv_desc_size;
					}
				}
			}

			pass.Unbind(effect);

			auto& fb = *checked_cast<D3D12FrameBuffer*>(re.CurFrameBuffer().get());
			fb.SetRenderTargets();
		}
	}
	void D3D12TextureCube::UnmapCube(uint32_t array_index, CubeFaces face, uint32_t level)
	{
		uint32_t const subres = CalcSubresource(level, array_index * 6 + face - CF_Positive_X, 0, num_mip_maps_, array_size_);
		this->DoUnmap(subres);
	}
Exemple #7
0
	void D3D12Texture3D::Unmap3D(uint32_t array_index, uint32_t level)
	{
		uint32_t const subres = CalcSubresource(level, array_index, 0, num_mip_maps_, array_size_);
		this->DoUnmap(subres);
	}