Exemplo n.º 1
0
	void OGLTexture1D::Map1D(uint32_t array_index, uint32_t level, TextureMapAccess tma, uint32_t x_offset, uint32_t /*width*/, void*& data)
	{
		last_tma_ = tma;

		uint32_t const texel_size = NumFormatBytes(format_);

		uint8_t* p;
		OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		switch (tma)
		{
		case TMA_Read_Only:
		case TMA_Read_Write:
			{
				GLint gl_internalFormat;
				GLenum gl_format;
				GLenum gl_type;
				OGLMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
				re.BindBuffer(GL_PIXEL_PACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]);

				re.BindTexture(0, target_type_, texture_);
				if (IsCompressedFormat(format_))
				{
					glGetCompressedTexImage(target_type_, level, nullptr);
					p = static_cast<uint8_t*>(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY));
				}
				else
				{
					glGetTexImage(target_type_, level, gl_format, gl_type, nullptr);
					p = static_cast<uint8_t*>(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY));
				}
			}
			break;

		case TMA_Write_Only:
			re.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
			re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]);
			p = static_cast<uint8_t*>(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
			break;

		default:
			BOOST_ASSERT(false);
			p = nullptr;
			break;
		}

		if (IsCompressedFormat(format_))
		{
			uint32_t const block_size = NumFormatBytes(format_) * 4;
			data = p + (x_offset / 4 * block_size);
		}
		else
		{
			data = p + x_offset * texel_size;
		}
	}
Exemplo n.º 2
0
	OGLTexture1D::OGLTexture1D(uint32_t width, uint32_t numMipMaps, uint32_t array_size, ElementFormat format,
							uint32_t sample_count, uint32_t sample_quality, uint32_t access_hint)
					: OGLTexture(TT_1D, array_size, sample_count, sample_quality, access_hint)
	{
		format_ = format;

		if (0 == numMipMaps)
		{
			num_mip_maps_ = 1;
			uint32_t w = width;
			while (w != 1)
			{
				++ num_mip_maps_;

				w = std::max<uint32_t>(1U, w / 2);
			}
		}
		else
		{
			num_mip_maps_ = numMipMaps;
		}

		width_ = width;

		if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
		{
			glCreateBuffers(1, &pbo_);
		}
		else
		{
			glGenBuffers(1, &pbo_);
		}

		mipmap_start_offset_.resize(num_mip_maps_ + 1);
		mipmap_start_offset_[0] = 0;
		for (uint32_t level = 0; level < num_mip_maps_; ++ level)
		{
			uint32_t const w = this->Width(level);

			GLsizei image_size;
			if (IsCompressedFormat(format_))
			{
				uint32_t const block_size = NumFormatBytes(format_) * 4;
				image_size = ((w + 3) / 4) * block_size;
			}
			else
			{
				uint32_t const texel_size = NumFormatBytes(format_);
				image_size = w * texel_size;
			}

			mipmap_start_offset_[level + 1] = mipmap_start_offset_[level] + image_size;
		}
	}
Exemplo n.º 3
0
	void OGLESTexture2D::Unmap2D(uint32_t array_index, uint32_t level)
	{
		switch (last_tma_)
		{
		case TMA_Read_Only:
			break;

		case TMA_Write_Only:
		case TMA_Read_Write:
			{
				GLint gl_internalFormat;
				GLenum gl_format;
				GLenum gl_type;
				OGLESMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

				uint32_t const w = this->Width(level);
				uint32_t const h = this->Height(level);

				OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
				re.BindTexture(0, target_type_, texture_);

				if (IsCompressedFormat(format_))
				{
					uint32_t const block_size = NumFormatBytes(format_) * 4;
					GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * block_size;

					if (array_size_ > 1)
					{
						glCompressedTexSubImage3D(target_type_, level, 0, 0, array_index,
							w, h, 1, gl_format, image_size, &tex_data_[array_index * num_mip_maps_ + level][0]);
					}
					else
					{
						glCompressedTexSubImage2D(target_type_, level, 0, 0,
							w, h, gl_format, image_size, &tex_data_[array_index * num_mip_maps_ + level][0]);
					}
				}
				else
				{
					if (array_size_ > 1)
					{
						glTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1,
							gl_format, gl_type, &tex_data_[array_index * num_mip_maps_ + level][0]);
					}
					else
					{
						glTexSubImage2D(target_type_, level, 0, 0, w, h,
							gl_format, gl_type, &tex_data_[array_index * num_mip_maps_ + level][0]);
					}
				}
			}
			break;

		default:
			BOOST_ASSERT(false);
			break;
		}
	}
Exemplo n.º 4
0
	TexturePtr DShowVMR9Allocator::PresentTexture()
	{
		unique_lock<mutex> lock(mutex_);

		if (FAILED(d3d_device_->TestCooperativeLevel()))
		{
			return TexturePtr();
		}

		if (cur_surf_index_ < surfaces_.size())
		{
			TIF(d3d_device_->GetRenderTargetData(surfaces_[cur_surf_index_], cache_surf_.get()));

			D3DLOCKED_RECT d3dlocked_rc;
			TIF(cache_surf_->LockRect(&d3dlocked_rc, nullptr, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY));

			uint32_t const width = present_tex_->Width(0);
			uint32_t const height = present_tex_->Height(0);
			uint32_t const texel_size = NumFormatBytes(present_tex_->Format());

			uint8_t const * src = static_cast<uint8_t const *>(d3dlocked_rc.pBits);
			{
				ElementFormat fmt = present_tex_->Format();
				Texture::Mapper mapper(*present_tex_, 0, 0, TMA_Write_Only, 0, 0, width, height);
				uint8_t* dst = mapper.Pointer<uint8_t>();
				if ((EF_ARGB8 == fmt) || (EF_ARGB8_SRGB == fmt))
				{
					for (uint32_t y = 0; y < height; ++ y)
					{
						std::memcpy(dst, src, width * texel_size);
						dst += mapper.RowPitch();
						src += d3dlocked_rc.Pitch;
					}
				}
				else
				{
					BOOST_ASSERT((EF_ABGR8 == fmt) || (EF_ABGR8_SRGB == fmt));

					for (uint32_t y = 0; y < height; ++ y)
					{
						for (uint32_t x = 0; x < width; ++ x)
						{
							dst[x * 4 + 0] = src[x * 4 + 2];
							dst[x * 4 + 1] = src[x * 4 + 1];
							dst[x * 4 + 2] = src[x * 4 + 0];
							dst[x * 4 + 3] = src[x * 4 + 3];
						}
						dst += mapper.RowPitch();
						src += d3dlocked_rc.Pitch;
					}
				}
			}

			TIF(cache_surf_->UnlockRect());
		}

		return present_tex_;
	}
Exemplo n.º 5
0
			Mapper(Texture& tex, uint32_t array_index, uint32_t level, TextureMapAccess tma,
						uint32_t x_offset, uint32_t width)
				: tex_(tex),
					mapped_array_index_(array_index),
					mapped_level_(level)
			{
				tex_.Map1D(array_index, level, tma, x_offset, width, data_);
				row_pitch_ = slice_pitch_ = width * NumFormatBytes(tex.Format());
			}
Exemplo n.º 6
0
	void D3D11GraphBuffer::DoResize()
	{
		BOOST_ASSERT(m_uByteSize != 0);

		if (this->GetSize() > m_uBufSize)
		{
			D3D11_BUFFER_DESC desc;
			this->GetD3DFlags(desc.Usage, desc.CPUAccessFlags, desc.BindFlags, desc.MiscFlags);
			desc.ByteWidth = m_uByteSize;
			desc.StructureByteStride = NumFormatBytes(m_FmtShader);

			ID3D11Buffer* buffer;
			ErO(m_pDevice->CreateBuffer(&desc, NULL, &buffer));
			m_pBuf = MakeCOMPtr(buffer);
			m_uBufSize = this->GetSize();

			if ((m_uAcces & EAH_GPU_Read) && (m_FmtShader != EF_Unknown))
			{
				D3D11_SHADER_RESOURCE_VIEW_DESC sr_desc;
				sr_desc.Format = (m_uAcces & EAH_GPU_Structured) ? DXGI_FORMAT_UNKNOWN : D3D11Mapping::MappingFormat(m_FmtShader);
				sr_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
				sr_desc.Buffer.ElementOffset = 0;
				sr_desc.Buffer.ElementWidth = m_uByteSize / NumFormatBytes(m_FmtShader);

				ID3D11ShaderResourceView* d3d_sr_view;
				ErO(m_pDevice->CreateShaderResourceView(m_pBuf.get(), &sr_desc, &d3d_sr_view));
				m_pShaderRes = MakeCOMPtr(d3d_sr_view);
			}

			if ((m_uAcces & EAH_GPU_Unordered) && (m_FmtShader != EF_Unknown))
			{
				D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
				uav_desc.Format = DXGI_FORMAT_UNKNOWN;
				uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
				uav_desc.Buffer.FirstElement = 0;
				uav_desc.Buffer.NumElements = this->GetSize() / desc.StructureByteStride;
				uav_desc.Buffer.Flags = 0;

				ID3D11UnorderedAccessView* d3d_ua_view;
				ErO(m_pDevice->CreateUnorderedAccessView(m_pBuf.get(), &uav_desc, &d3d_ua_view));
				m_pUnorderAcces = MakeCOMPtr(d3d_ua_view);
			}
		}
	}
Exemplo n.º 7
0
	void D3D11TextureCube::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)
	{
		D3D11_MAPPED_SUBRESOURCE mapped;
		TIF(d3d_imm_ctx_->Map(d3dTextureCube_.get(), D3D11CalcSubresource(level, array_index * 6 + face - CF_Positive_X, num_mip_maps_),
			D3D11Mapping::Mapping(tma, type_, access_hint_, num_mip_maps_), 0, &mapped));
		uint8_t* p = static_cast<uint8_t*>(mapped.pData);
		data = p + y_offset * mapped.RowPitch + x_offset * NumFormatBytes(format_);
		row_pitch = mapped.RowPitch;
	}
Exemplo n.º 8
0
	void D3D11Texture3D::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)
	{
		D3D11_MAPPED_SUBRESOURCE mapped;
		TIF(d3d_imm_ctx_->Map(d3dTexture3D_.get(), D3D11CalcSubresource(level, array_index, num_mip_maps_), D3D11Mapping::Mapping(tma, type_, access_hint_, num_mip_maps_), 0, &mapped));
		uint8_t* p = static_cast<uint8_t*>(mapped.pData);
		data = p + z_offset * mapped.DepthPitch + y_offset * mapped.RowPitch + x_offset * NumFormatBytes(format_);
		row_pitch = mapped.RowPitch;
		slice_pitch = mapped.DepthPitch;
	}
Exemplo n.º 9
0
	void OGLESTextureCube::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)
	{
		last_tma_ = tma;

		uint32_t const texel_size = NumFormatBytes(format_);
		uint32_t const w = this->Width(level);

		row_pitch = w * texel_size;

		uint8_t* p = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0];
		if (IsCompressedFormat(format_))
		{
			uint32_t const block_size = NumFormatBytes(format_) * 4;
			data = p + (y_offset / 4) * row_pitch + (x_offset / 4 * block_size);
		}
		else
		{
			data = p + (y_offset * w + x_offset) * texel_size;
		}
	}
Exemplo n.º 10
0
	uint32_t RenderLayout::NumIndices() const
	{
		uint32_t n = 0;
		if (index_stream_)
		{
			if (0xFFFFFFFF == force_num_indices_)
			{
				n = index_stream_->Size() / NumFormatBytes(index_format_);
			}
			else
			{
				n = force_num_indices_;
			}
		}
		return n;
	}
Exemplo n.º 11
0
	void OGLTexture1D::UpdateSubresource1D(uint32_t array_index, uint32_t level,
		uint32_t x_offset, uint32_t width,
		void const * data)
	{
		OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());

		GLint gl_internalFormat;
		GLenum gl_format;
		GLenum gl_type;
		OGLMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

		re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		re.BindTexture(0, target_type_, texture_);

		if (IsCompressedFormat(format_))
		{
			uint32_t const block_size = NumFormatBytes(format_) * 4;
			GLsizei const image_size = ((width + 3) / 4) * block_size;

			if (array_size_ > 1)
			{
				glCompressedTexSubImage2D(target_type_, level, x_offset, array_index,
					width, 1, gl_format, image_size, data);
			}
			else
			{
				glCompressedTexSubImage1D(target_type_, level, x_offset,
					width, gl_format, image_size, data);
			}
		}
		else
		{
			if (array_size_ > 1)
			{
				glTexSubImage2D(target_type_, level, x_offset, array_index, width, 1,
					gl_format, gl_type, data);
			}
			else
			{
				glTexSubImage1D(target_type_, level, x_offset, width,
					gl_format, gl_type, data);
			}
		}
	}
Exemplo n.º 12
0
	void OGLESTexture3D::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)
	{
		BOOST_ASSERT(0 == array_index);
		KFL_UNUSED(array_index);

		last_tma_ = tma;

		uint32_t const texel_size = NumFormatBytes(format_);
		uint32_t const w = this->Width(level);
		uint32_t const h = this->Height(level);

		row_pitch = w * texel_size;
		slice_pitch = row_pitch * h;

		uint8_t* p = &tex_data_[level][0];		
		data = p + ((z_offset * h + y_offset) * w + x_offset) * texel_size;
	}
Exemplo n.º 13
0
	void OGLESTextureCube::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)
	{
		BOOST_ASSERT(0 == array_index);
		UNREF_PARAM(array_index);

		last_tma_ = tma;

		uint32_t const texel_size = NumFormatBytes(format_);
		int block_size;
		if (IsCompressedFormat(format_))
		{
			if ((EF_BC1 == format_) || (EF_SIGNED_BC1 == format_) || (EF_BC1_SRGB == format_)
				|| (EF_BC4 == format_) || (EF_SIGNED_BC4 == format_) || (EF_BC4_SRGB == format_))
			{
				block_size = 8;
			}
			else
			{
				block_size = 16;
			}
		}
		else
		{
			block_size = 0;
		}

		row_pitch = widths_[level] * texel_size;

		uint8_t* p = &tex_data_[face * num_mip_maps_ + level][0];
		if (IsCompressedFormat(format_))
		{
			data = p + (y_offset / 4) * row_pitch + (x_offset / 4 * block_size);
		}
		else
		{
			data = p + (y_offset * widths_[level] + x_offset) * texel_size;
		}
	}
Exemplo n.º 14
0
	void OGLESTextureCube::UnmapCube(uint32_t array_index, CubeFaces face, uint32_t level)
	{
		switch (last_tma_)
		{
		case TMA_Read_Only:
			break;

		case TMA_Write_Only:
		case TMA_Read_Write:
			{
				GLint gl_internalFormat;
				GLenum gl_format;
				GLenum gl_type;
				OGLESMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

				uint32_t const w = this->Width(level);

				OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
				re.BindTexture(0, target_type_, texture_);

				if (IsCompressedFormat(format_))
				{
					uint32_t const block_size = NumFormatBytes(format_) * 4;
					GLsizei const image_size = ((this->Width(level) + 3) / 4) * ((this->Height(level) + 3) / 4) * block_size;

					glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level,
						0, 0, w, w, gl_format, image_size, &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0]);
				}
				else
				{
					glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level,
						0, 0, w, w, gl_format, gl_type, &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0]);
				}
			}
			break;
		default:
			BOOST_ASSERT(false);
			break;
		}
	}
Exemplo n.º 15
0
	void OGLESTexture2D::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glBindTexture(target_type_, texture_);
		for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
		{
			for (uint32_t level = 0; level < num_mip_maps_; ++ level)
			{
				uint32_t const w = this->Width(level);
				uint32_t const h = this->Height(level);

				if (IsCompressedFormat(format_))
				{
					uint32_t const block_size = NumFormatBytes(format_) * 4;
					GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * block_size;

					void* ptr;
					if (nullptr == init_data)
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size, 0);
						ptr = nullptr;
					}
					else
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size);
						std::memcpy(&tex_data_[array_index * num_mip_maps_ + level][0],
							init_data[array_index * num_mip_maps_ + level].data, image_size);
						ptr = &tex_data_[array_index * num_mip_maps_ + level][0];
					}

					if (array_size_ > 1)
					{
						if (0 == array_index)
						{
							glCompressedTexImage3D(target_type_, level, glinternalFormat,
								w, h, array_size_, 0, image_size * array_size_, nullptr);
						}

						if (init_data != nullptr)
						{
							glCompressedTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1,
								glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
						}
					}
					else
					{
						glCompressedTexImage2D(target_type_, level, glinternalFormat,
							w, h, 0, image_size, ptr);
					}
				}
				else
				{
					GLsizei const image_size = w * h * texel_size;

					void* ptr;
					if (nullptr == init_data)
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size, 0);
						ptr = nullptr;
					}
					else
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size);
						std::memcpy(&tex_data_[array_index * num_mip_maps_ + level][0],
							init_data[array_index * num_mip_maps_ + level].data, image_size);
						ptr = &tex_data_[array_index * num_mip_maps_ + level][0];
					}

					if (array_size_ > 1)
					{
						if (0 == array_index)
						{
							glTexImage3D(target_type_, level, glinternalFormat, w, h, array_size_, 0, glformat, gltype, nullptr);
						}

						if (init_data != nullptr)
						{
							glTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1,
								glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
						}
					}
					else
					{
						glTexImage2D(target_type_, level, glinternalFormat, w, h, 0, glformat, gltype, ptr);
					}
				}
			}
		}

		hw_res_ready_ = true;
	}
Exemplo n.º 16
0
	void OGLESTexture2D::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(type_ == target.Type());

		OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		if (glloader_GLES_VERSION_3_0() && ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_)))))
		{
			GLuint fbo_src, fbo_dst;
			re.GetFBOForBlit(fbo_src, fbo_dst);

			GLuint old_fbo = re.BindFramebuffer();

			glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src);
			if (array_size_ > 1)
			{
				glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index);
			}
			else
			{
				if (sample_count_ <= 1)
				{
					glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level);
				}
				else
				{
					glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER,
										GL_COLOR_ATTACHMENT0,
										GL_RENDERBUFFER, texture_);
				}
			}

			OGLESTexture& ogl_target = *checked_cast<OGLESTexture*>(&target);
			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst);
			if (array_size_ > 1)
			{
				glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLTexture(), dst_level, dst_array_index);
			}
			else
			{
				glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLType(), ogl_target.GLTexture(), dst_level);
			}

			glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height,
							dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height,
							GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR);

			re.BindFramebuffer(old_fbo, true);
		}
		else if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format()))
		{
			GLint gl_internalFormat;
			GLenum gl_format;
			GLenum gl_type;
			OGLESMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

			GLint gl_target_internal_format;
			GLenum gl_target_format;
			GLenum gl_target_type;
			OGLESMapping::MappingFormat(gl_target_internal_format, gl_target_format, gl_target_type, target.Format());

			if (IsCompressedFormat(format_))
			{
				BOOST_ASSERT((src_width == dst_width) && (src_height == dst_height));
				BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3)));
				BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3)));
				BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3)));
				BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3)));

				Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height);
				Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height);

				uint32_t const block_size = NumFormatBytes(format_) * 4;
				uint8_t const * s = mapper_src.Pointer<uint8_t>();
				uint8_t* d = mapper_dst.Pointer<uint8_t>();
				for (uint32_t y = 0; y < src_height; y += 4)
				{
					std::memcpy(d, s, src_width / 4 * block_size);

					s += mapper_src.RowPitch();
					d += mapper_dst.RowPitch();
				}
			}
			else
			{
				size_t const format_size = NumFormatBytes(format_);

				Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height);
				Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height);
				uint8_t const * s = mapper_src.Pointer<uint8_t>();
				uint8_t* d = mapper_dst.Pointer<uint8_t>();
				for (uint32_t y = 0; y < src_height; ++ y)
				{
					std::memcpy(d, s, src_width * format_size);

					s += mapper_src.RowPitch();
					d += mapper_dst.RowPitch();
				}
			}
		}
		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);
		}
	}
Exemplo n.º 17
0
	OGLESTextureCube::OGLESTextureCube(uint32_t size, uint32_t numMipMaps, uint32_t array_size, ElementFormat format,
								uint32_t sample_count, uint32_t sample_quality, uint32_t access_hint, ElementInitData const * init_data)
					: OGLESTexture(TT_Cube, array_size, sample_count, sample_quality, access_hint)
	{
		if (IsSRGB(format))
		{
			format = this->SRGBToRGB(format);
		}

		format_ = format;

		if (0 == numMipMaps)
		{
			num_mip_maps_ = 1;
			uint32_t s = size;
			while (s > 1)
			{
				++ num_mip_maps_;

				s = std::max<uint32_t>(1U, s / 2);
			}
		}
		else
		{
			num_mip_maps_ = numMipMaps;
		}
		array_size_ = 1;

		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glGenTextures(1, &texture_);
		glBindTexture(target_type_, texture_);
		glTexParameteri(target_type_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(target_type_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		if (glloader_GLES_VERSION_3_0())
		{
			glTexParameteri(target_type_, GL_TEXTURE_BASE_LEVEL, 0);
			glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);
		}
		else 
		if (glloader_GLES_APPLE_texture_max_level())
		{
			glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL_APPLE, num_mip_maps_ - 1);
		}

		tex_data_.resize(6 * num_mip_maps_);
		widths_.resize(6 * num_mip_maps_);
		for (int face = 0; face < 6; ++ face)
		{
			uint32_t s = size;
			for (uint32_t level = 0; level < num_mip_maps_; ++ level)
			{
				widths_[face * num_mip_maps_ + level] = s;

				if (IsCompressedFormat(format_))
				{
					int block_size;
					if ((EF_BC1 == format_) || (EF_SIGNED_BC1 == format_) || (EF_BC1_SRGB == format_)
						|| (EF_BC4 == format_) || (EF_SIGNED_BC4 == format_) || (EF_BC4_SRGB == format_))
					{
						block_size = 8;
					}
					else
					{
						block_size = 16;
					}

					GLsizei const image_size = ((s + 3) / 4) * ((s + 3) / 4) * block_size;

					if (nullptr == init_data)
					{
						tex_data_[face * num_mip_maps_ + level].resize(image_size, 0);
					}
					else
					{
						tex_data_[face * num_mip_maps_ + level].resize(image_size);
						std::memcpy(&tex_data_[face * num_mip_maps_ + level][0], init_data[face * num_mip_maps_ + level].data, image_size);
					}
					glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
						s, s, 0, image_size, &tex_data_[face * num_mip_maps_ + level][0]);
				}
				else
				{
					GLsizei const image_size = s * s * texel_size;

					if (nullptr == init_data)
					{
						tex_data_[face * num_mip_maps_ + level].resize(image_size, 0);
					}
					else
					{
						tex_data_[face * num_mip_maps_ + level].resize(image_size);
						std::memcpy(&tex_data_[face * num_mip_maps_ + level][0], init_data[face * num_mip_maps_ + level].data, image_size);
					}
					glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
						s, s, 0, glformat, gltype, &tex_data_[face * num_mip_maps_ + level][0]);
				}

				s = std::max(1U, s / 2);
			}
		}
	}
Exemplo n.º 18
0
	D3D11GraphBuffer::D3D11GraphBuffer(EBufferUsage eUsage, uint32 uAccess, uint32 uBindFlag, PixelInitData const* cpInitData, PixelFormat Fmt)
	: CGraphBuffer(eUsage, uAccess),
	  m_uBindFlag(uBindFlag), m_uBufSize(0), m_FmtShader(Fmt)
	{
		if ((m_uAcces & EAH_GPU_Unordered) && (m_FmtShader != EF_Unknown))
		{
			m_uBindFlag = 0;
		}

		D3D11Render const & ren(*checked_cast<D3D11Render const *>(&MonFac::Only().InstFactory().InstRender()));
		m_pDevice = ren.GetD3DDevice();
		m_pImmContext = ren.GetD3DDeviceImmContext();
		m_uByteSize = 0;
		//填写 desc 结构
		if (cpInitData != NULL)
		{
			D3D11_BUFFER_DESC buf_desc;
			this->GetD3DFlags(buf_desc.Usage, buf_desc.CPUAccessFlags, buf_desc.BindFlags, buf_desc.MiscFlags);
			//数据长度
			buf_desc.ByteWidth = cpInitData->m_uRowPitch;
			m_uByteSize = cpInitData->m_uRowPitch;
			//缓冲格式
			buf_desc.StructureByteStride = NumFormatBytes(m_FmtShader);

			//填充这个玩意
			D3D11_SUBRESOURCE_DATA subres_init;
			subres_init.pSysMem = cpInitData->m_cpData;
			subres_init.SysMemPitch = cpInitData->m_uRowPitch;
			subres_init.SysMemSlicePitch = cpInitData->m_uSlicePitch;
			//可以开始创建 buffer
			ID3D11Buffer* buffer;
			ErO(m_pDevice->CreateBuffer(&buf_desc, &subres_init, &buffer));
			m_pBuf = MakeCOMPtr(buffer);
			m_uBufSize = this->GetSize();
			//填写buffer 详细信息
			if ((m_uAcces & EAH_GPU_Read) && (m_FmtShader != EF_Unknown))
			{
				//shader 资源 view
				D3D11_SHADER_RESOURCE_VIEW_DESC sr_desc;
				sr_desc.Format = (m_uAcces & EAH_GPU_Structured) ? DXGI_FORMAT_UNKNOWN : D3D11Mapping::MappingFormat(m_FmtShader);
				//资源类型
				sr_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
				//视图访问的第一个元素
				sr_desc.Buffer.ElementOffset = 0;
				//全部成员个数
				sr_desc.Buffer.ElementWidth = m_uByteSize / NumFormatBytes(m_FmtShader);
				//创建buf 类型shader资源
				ID3D11ShaderResourceView* d3d_sr_view;
				ErO(m_pDevice->CreateShaderResourceView(m_pBuf.get(), &sr_desc, &d3d_sr_view));
				m_pShaderRes = MakeCOMPtr(d3d_sr_view);
			}
			//无序访问资源 view
			if ((m_uAcces & EAH_GPU_Unordered) && (m_FmtShader != EF_Unknown))
			{
				D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
				//资源格式
			     // DXGI_FORMAT_R8_SNORM  = 63,DXGI_FORMAT_R8_SINT  = 64, DXGI_FORMAT_A8_UNORM 等  
				uav_desc.Format = DXGI_FORMAT_UNKNOWN;
				//资源类型 如何访问指定资源
				uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
				uav_desc.Buffer.FirstElement = 0;
				//元素个数
				uav_desc.Buffer.NumElements = this->GetSize() / buf_desc.StructureByteStride;
				//查看资源选项
				uav_desc.Buffer.Flags = 0;
				//创建无序视图
				ID3D11UnorderedAccessView* d3d_ua_view;
				ErO(m_pDevice->CreateUnorderedAccessView(m_pBuf.get(), &uav_desc, &d3d_ua_view));
				m_pUnorderAcces = MakeCOMPtr(d3d_ua_view);
			}
		}
	}
Exemplo n.º 19
0
	void OGLESTexture3D::CopyToSubTexture3D(Texture& target,
			uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_z_offset, uint32_t dst_width, uint32_t dst_height, uint32_t dst_depth,
			uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_z_offset, uint32_t src_width, uint32_t src_height, uint32_t src_depth)
	{
		KFL_UNUSED(dst_depth);

		BOOST_ASSERT(type_ == target.Type());
		BOOST_ASSERT(0 == src_array_index);
		BOOST_ASSERT(0 == dst_array_index);

		if ((src_width == dst_width) && (src_height == dst_height) && (src_depth == dst_depth) && (format_ == target.Format()))
		{
			if (IsCompressedFormat(format_))
			{
				BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3)));
				BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3)));
				BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3)));
				BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3)));

				for (uint32_t z = 0; z < src_depth; ++ z)
				{
					Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only,
						src_x_offset, src_y_offset, src_z_offset + z, src_width, src_height, 1);
					Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only,
						dst_x_offset, dst_y_offset, dst_z_offset + z, dst_width, dst_height, 1);

					uint32_t const block_size = NumFormatBytes(format_) * 4;
					uint8_t const * s = mapper_src.Pointer<uint8_t>();
					uint8_t* d = mapper_dst.Pointer<uint8_t>();
					for (uint32_t y = 0; y < src_height; y += 4)
					{
						std::memcpy(d, s, src_width / 4 * block_size);

						s += mapper_src.RowPitch();
						d += mapper_dst.RowPitch();
					}
				}
			}
			else
			{
				for (uint32_t z = 0; z < src_depth; ++ z)
				{
					size_t const format_size = NumFormatBytes(format_);

					Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only,
						src_x_offset, src_y_offset, src_z_offset + z, src_width, src_height, 1);
					Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only,
						dst_x_offset, dst_y_offset, dst_z_offset + z, dst_width, dst_height, 1);
					uint8_t const * s = mapper_src.Pointer<uint8_t>();
					uint8_t* d = mapper_dst.Pointer<uint8_t>();
					for (uint32_t y = 0; y < src_height; ++ y)
					{
						std::memcpy(d, s, src_width * format_size);

						s += mapper_src.RowPitch();
						d += mapper_dst.RowPitch();
					}
				}
			}
		}
		else
		{
			this->ResizeTexture3D(target, dst_array_index, dst_level, dst_x_offset, dst_y_offset, dst_z_offset, dst_width, dst_height, dst_depth,
				src_array_index, src_level, src_x_offset, src_y_offset, src_z_offset, src_width, src_height, src_depth, true);
		}
	}
Exemplo n.º 20
0
	void OGLTexture1D::CreateHWResource(ArrayRef<ElementInitData> init_data, float4 const * clear_value_hint)
	{
		KFL_UNUSED(clear_value_hint);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		if (sample_count_ <= 1)
		{
			uint32_t const pbo_size = mipmap_start_offset_.back() * array_size_;
			if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
			{
				glTextureParameteri(texture_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				glNamedBufferStorage(pbo_, pbo_size, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);

				uint32_t const w0 = this->Width(0);

				if (array_size_ > 1)
				{
					glTextureStorage2D(texture_, num_mip_maps_, glinternalFormat, w0, array_size_);
				}
				else
				{
					glTextureStorage1D(texture_, num_mip_maps_, glinternalFormat, w0);
				}

				if (!init_data.empty())
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);
							GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									glCompressedTextureSubImage2D(texture_, level, 0, array_index,
										w, 1, glformat, image_size, data);
								}
								else
								{
									glCompressedTextureSubImage1D(texture_, level, 0,
										w, glformat, image_size, data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									glTextureSubImage2D(texture_, level, 0, array_index, w, 1,
										glformat, gltype, data);
								}
								else
								{
									glTextureSubImage1D(texture_, level, 0, w, glformat, gltype, data);
								}
							}
						}
					}
				}
			}
			else
			{
				auto& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
				
				re.BindTexture(0, target_type_, texture_);
				glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_);
				if (glloader_GL_VERSION_4_4() || glloader_GL_ARB_buffer_storage())
				{
					glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_DYNAMIC_STORAGE_BIT);
				}
				else
				{
					glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_STREAM_COPY);
				}
				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

				if (glloader_GL_VERSION_4_2() || glloader_GL_ARB_texture_storage())
				{
					uint32_t const w0 = this->Width(0);

					if (array_size_ > 1)
					{
						glTexStorage2D(target_type_, num_mip_maps_, glinternalFormat, w0, array_size_);
					}
					else
					{
						glTexStorage1D(target_type_, num_mip_maps_, glinternalFormat, w0);
					}

					if (!init_data.empty())
					{
						for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
						{
							for (uint32_t level = 0; level < num_mip_maps_; ++ level)
							{
								uint32_t const w = this->Width(level);
								GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

								if (IsCompressedFormat(format_))
								{
									uint32_t const block_size = NumFormatBytes(format_) * 4;
									GLsizei const image_size = ((w + 3) / 4) * block_size;

									if (array_size_ > 1)
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index,
											w, 1, glformat, image_size, data);
									}
									else
									{
										glCompressedTexSubImage1D(target_type_, level, 0,
											w, glformat, image_size, data);
									}
								}
								else
								{
									if (array_size_ > 1)
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, data);
									}
									else
									{
										glTexSubImage1D(target_type_, level, 0, w, glformat, gltype, data);
									}
								}
							}
						}
					}
				}
				else
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glCompressedTexImage2D(target_type_, level, glinternalFormat,
											w, array_size_, 0, image_size * array_size_, nullptr);
									}

									if (!init_data.empty())
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glCompressedTexImage1D(target_type_, level, glinternalFormat,
										w, 0, image_size,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr);
									}

									if (!init_data.empty())
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
						}
					}
				}
			}
		}
		else
		{
			glBindRenderbuffer(GL_RENDERBUFFER, texture_);
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1);
		}

		hw_res_ready_ = true;
	}
Exemplo n.º 21
0
	void OGLTexture1D::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		if (sample_count_ <= 1)
		{
			glBindTexture(target_type_, texture_);
			glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

			OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
			for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
			{
				for (uint32_t level = 0; level < num_mip_maps_; ++ level)
				{
					uint32_t const w = this->Width(level);

					re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]);
					if (IsCompressedFormat(format_))
					{
						uint32_t const block_size = NumFormatBytes(format_) * 4;
						GLsizei const image_size = ((w + 3) / 4) * block_size;

						glBufferData(GL_PIXEL_UNPACK_BUFFER, image_size, nullptr, GL_STREAM_DRAW);
						re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

						if (array_size_ > 1)
						{
							if (0 == array_index)
							{
								glCompressedTexImage2D(target_type_, level, glinternalFormat,
									w, array_size_, 0, image_size * array_size_, nullptr);
							}

							if (init_data != nullptr)
							{
								glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1,
									glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
							}
						}
						else
						{
							glCompressedTexImage1D(target_type_, level, glinternalFormat,
								w, 0, image_size, (nullptr == init_data) ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
						}
					}
					else
					{
						GLsizei const image_size = w * texel_size;

						glBufferData(GL_PIXEL_UNPACK_BUFFER, image_size, nullptr, GL_STREAM_DRAW);
						re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

						if (array_size_ > 1)
						{
							if (0 == array_index)
							{
								glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr);
							}

							if (init_data != nullptr)
							{
								glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
									glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
							}
						}
						else
						{
							glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype,
								(nullptr == init_data) ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
						}
					}
				}
			}
		}
		else
		{
			glBindRenderbuffer(GL_RENDERBUFFER, texture_);
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1);
		}

		hw_res_ready_ = true;
	}
Exemplo n.º 22
0
	void OGLTexture1D::Unmap1D(uint32_t array_index, uint32_t level)
	{
		OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		switch (last_tma_)
		{
		case TMA_Read_Only:
			re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			re.BindBuffer(GL_PIXEL_PACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]);
			glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
			break;

		case TMA_Write_Only:
		case TMA_Read_Write:
			{
				GLint gl_internalFormat;
				GLenum gl_format;
				GLenum gl_type;
				OGLMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

				uint32_t const w = this->Width(level);

				re.BindTexture(0, target_type_, texture_);

				re.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]);
				glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);

				if (IsCompressedFormat(format_))
				{
					uint32_t const block_size = NumFormatBytes(format_) * 4;
					GLsizei const image_size = ((w + 3) / 4) * block_size;

					if (array_size_ > 1)
					{
						glCompressedTexSubImage2D(target_type_, level, 0, array_index,
							w, 1, gl_format, image_size, nullptr);
					}
					else
					{
						glCompressedTexSubImage1D(target_type_, level, 0,
							w, gl_format, image_size, nullptr);
					}
				}
				else
				{
					if (array_size_ > 1)
					{
						glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
							gl_format, gl_type, nullptr);
					}
					else
					{
						glTexSubImage1D(target_type_, level, 0, w, gl_format, gl_type, nullptr);
					}
				}
			}
			break;

		default:
			BOOST_ASSERT(false);
			break;
		}
	}
Exemplo n.º 23
0
	void OGLESTextureCube::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());

		OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		if (glloader_GLES_VERSION_3_0() && (!IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_)))))
		{
			GLuint fbo_src, fbo_dst;
			re.GetFBOForBlit(fbo_src, fbo_dst);

			GLuint old_fbo = re.BindFramebuffer();

			glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src);
			if (array_size_ > 1)
			{
				glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index * 6 + src_face - CF_Positive_X);
			}
			else
			{
				glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + src_face - CF_Positive_X, texture_, src_level);
			}

			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst);
			if (target.ArraySize() > 1)
			{
				glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level, dst_array_index * 6 + dst_face - CF_Positive_X);
			}
			else
			{
				glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + dst_face - CF_Positive_X, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level);
			}

			glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height,
							dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height,
							GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR);

			re.BindFramebuffer(old_fbo, true);
		}
		else
		{
			if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format()))
			{
				if (IsCompressedFormat(format_))
				{
					BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3)));
					BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3)));
					BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3)));
					BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3)));

					Texture::Mapper mapper_src(*this, src_array_index, src_face, src_level, TMA_Read_Only, 0, 0, this->Width(src_level), this->Height(src_level));
					Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, 0, 0, target.Width(dst_level), target.Height(dst_level));

					uint32_t const block_size = NumFormatBytes(format_) * 4;
					uint8_t const * s = mapper_src.Pointer<uint8_t>() + (src_y_offset / 4) * mapper_src.RowPitch() + (src_x_offset / 4 * block_size);
					uint8_t* d = mapper_dst.Pointer<uint8_t>() + (dst_y_offset / 4) * mapper_dst.RowPitch() + (dst_x_offset / 4 * block_size);
					for (uint32_t y = 0; y < src_height; y += 4)
					{
						std::memcpy(d, s, src_width / 4 * block_size);

						s += mapper_src.RowPitch();
						d += mapper_dst.RowPitch();
					}
				}
				else
				{
					size_t const format_size = NumFormatBytes(format_);					

					Texture::Mapper mapper_src(*this, src_array_index, src_face, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height);
					Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height);
					uint8_t const * s = mapper_src.Pointer<uint8_t>();
					uint8_t* d = mapper_dst.Pointer<uint8_t>();
					for (uint32_t y = 0; y < src_height; ++ y)
					{
						std::memcpy(d, s, src_width * format_size);

						s += mapper_src.RowPitch();
						d += mapper_dst.RowPitch();
					}
				}
			}
			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);
			}
		}
	}
Exemplo n.º 24
0
	void OGLESTexture3D::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glBindTexture(target_type_, texture_);
		for (uint32_t level = 0; level < num_mip_maps_; ++ level)
		{
			uint32_t const w = this->Width(level);
			uint32_t const h = this->Height(level);
			uint32_t const d = this->Depth(level);

			if (IsCompressedFormat(format_))
			{
				uint32_t const block_size = NumFormatBytes(format_) * 4;
				GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * d * block_size;

				void* ptr;
				if (nullptr == init_data)
				{
					tex_data_[level].resize(image_size, 0);
					ptr = nullptr;
				}
				else
				{
					tex_data_[level].resize(image_size);
					std::memcpy(&tex_data_[level][0], init_data[level].data, image_size);
					ptr = &tex_data_[level][0];
				}
				if (glloader_GLES_VERSION_3_0())
				{
					glCompressedTexImage3D(target_type_, level, glinternalFormat,
						w, h, d, 0, image_size, ptr);
				}
				else
				{
					glCompressedTexImage3DOES(target_type_, level, glinternalFormat,
						w, h, d, 0, image_size, ptr);
				}
			}
			else
			{
				GLsizei const image_size = w * h * d * texel_size;

				void* ptr;
				if (nullptr == init_data)
				{
					tex_data_[level].resize(image_size, 0);
					ptr = nullptr;
				}
				else
				{
					tex_data_[level].resize(image_size);
					std::memcpy(&tex_data_[level][0], init_data[level].data, image_size);
					ptr = &tex_data_[level][0];
				}
				if (glloader_GLES_VERSION_3_0())
				{
					glTexImage3D(target_type_, level, glinternalFormat, w, h, d, 0, glformat, gltype, ptr);
				}
				else
				{
					glTexImage3DOES(target_type_, level, glinternalFormat, w, h, d, 0, glformat, gltype, ptr);
				}
			}
		}

		hw_res_ready_ = true;
	}
Exemplo n.º 25
0
	void OGLTexture1D::CopyToSubTexture1D(Texture& target,
			uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_width,
			uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_width)
	{
		BOOST_ASSERT(type_ == target.Type());
		
		if ((format_ == target.Format()) && !IsCompressedFormat(format_) && (glloader_GL_VERSION_4_3() || glloader_GL_ARB_copy_image())
			&& (src_width == dst_width) && (1 == sample_count_))
		{
			OGLTexture& ogl_target = *checked_cast<OGLTexture*>(&target);
			glCopyImageSubData(
				texture_, target_type_, src_level,
				src_x_offset, 0, src_array_index,
				ogl_target.GLTexture(), ogl_target.GLType(), dst_level,
				dst_x_offset, 0, dst_array_index, src_width, 1, 1);
		}
		else
		{
			OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
			if ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GL_ARB_texture_rg() || (4 == NumComponents(format_))))
			{
				GLuint fbo_src, fbo_dst;
				re.GetFBOForBlit(fbo_src, fbo_dst);

				GLuint old_fbo = re.BindFramebuffer();

				glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src);
				if (array_size_ > 1)
				{
					glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index);
				}
				else
				{
					if (sample_count_ <= 1)
					{
						glFramebufferTexture1D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level);
					}
					else
					{
						glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER,
											GL_COLOR_ATTACHMENT0,
											GL_RENDERBUFFER, texture_);
					}
				}

				OGLTexture& ogl_target = *checked_cast<OGLTexture*>(&target);
				glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst);
				if (array_size_ > 1)
				{
					glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLTexture(), dst_level, dst_array_index);
				}
				else
				{
					glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, ogl_target.GLTexture(), dst_level);
				}

				glBlitFramebuffer(src_x_offset, 0, src_x_offset + src_width, 1,
								dst_x_offset, 0, dst_x_offset + dst_width, 1,
								GL_COLOR_BUFFER_BIT, (src_width == dst_width) ? GL_NEAREST : GL_LINEAR);

				re.BindFramebuffer(old_fbo, true);
			}
			else
			{
				if ((src_width == dst_width) && (format_ == target.Format()))
				{
					if (IsCompressedFormat(format_))
					{
						BOOST_ASSERT(0 == (src_x_offset & 0x3));
						BOOST_ASSERT(0 == (dst_x_offset & 0x3));
						BOOST_ASSERT(0 == (src_width & 0x3));
						BOOST_ASSERT(0 == (dst_width & 0x3));

						Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, 0, this->Width(src_level));
						Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, 0, target.Width(dst_level));

						uint32_t const block_size = NumFormatBytes(format_) * 4;
						uint8_t const * s = mapper_src.Pointer<uint8_t>() + (src_x_offset / 4 * block_size);
						uint8_t* d = mapper_dst.Pointer<uint8_t>() + (dst_x_offset / 4 * block_size);
						std::memcpy(d, s, src_width / 4 * block_size);
					}
					else
					{
						size_t const format_size = NumFormatBytes(format_);

						Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_width);
						Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_width);
						uint8_t const * s = mapper_src.Pointer<uint8_t>();
						uint8_t* d = mapper_dst.Pointer<uint8_t>();

						std::memcpy(d, s, src_width * format_size);
					}
				}
				else
				{
					this->ResizeTexture1D(target, dst_array_index, dst_level, dst_x_offset, dst_width,
						src_array_index, src_level, src_x_offset, src_width, true);
				}
			}
		}
	}
Exemplo n.º 26
0
	void D3D11GraphicsBuffer::CreateBuffer(D3D11_SUBRESOURCE_DATA const * subres_init)
	{
		D3D11_BUFFER_DESC desc;
		this->GetD3DFlags(desc.Usage, desc.CPUAccessFlags, desc.BindFlags, desc.MiscFlags);
		desc.ByteWidth = size_in_byte_;
		desc.StructureByteStride = NumFormatBytes(fmt_as_shader_res_);

		ID3D11Buffer* buffer;
		TIF(d3d_device_->CreateBuffer(&desc, subres_init, &buffer));
		buffer_ = MakeCOMPtr(buffer);

		if ((access_hint_ & EAH_GPU_Read) && (fmt_as_shader_res_ != EF_Unknown))
		{
			D3D11_SHADER_RESOURCE_VIEW_DESC sr_desc;
			sr_desc.Format = (access_hint_ & EAH_GPU_Structured) ? DXGI_FORMAT_UNKNOWN : D3D11Mapping::MappingFormat(fmt_as_shader_res_);
			sr_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
			sr_desc.Buffer.ElementOffset = 0;
			sr_desc.Buffer.ElementWidth = size_in_byte_ / desc.StructureByteStride;

			ID3D11ShaderResourceView* d3d_sr_view;
			TIF(d3d_device_->CreateShaderResourceView(buffer_.get(), &sr_desc, &d3d_sr_view));
			d3d_sr_view_ = MakeCOMPtr(d3d_sr_view);
		}

		if ((access_hint_ & EAH_GPU_Unordered) && (fmt_as_shader_res_ != EF_Unknown))
		{
			D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
			if (access_hint_ & EAH_Raw)
			{
				uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
			}
			else if (access_hint_ & EAH_GPU_Structured)
			{
				uav_desc.Format = DXGI_FORMAT_UNKNOWN;
			}
			else
			{
				uav_desc.Format = D3D11Mapping::MappingFormat(fmt_as_shader_res_);
			}
			uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
			uav_desc.Buffer.FirstElement = 0;
			uav_desc.Buffer.NumElements = size_in_byte_ / desc.StructureByteStride;
			uav_desc.Buffer.Flags = 0;
			if (access_hint_ & EAH_Raw)
			{
				uav_desc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW;
			}
			if (access_hint_ & EAH_Append)
			{
				uav_desc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_APPEND;
			}
			if (access_hint_ & EAH_Counter)
			{
				uav_desc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_COUNTER;
			}

			ID3D11UnorderedAccessView* d3d_ua_view;
			TIF(d3d_device_->CreateUnorderedAccessView(buffer_.get(), &uav_desc, &d3d_ua_view));
			d3d_ua_view_ = MakeCOMPtr(d3d_ua_view);
		}
	}
Exemplo n.º 27
0
	void OGLESTextureCube::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glBindTexture(target_type_, texture_);
		for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
		{
			for (int face = 0; face < 6; ++ face)
			{
				for (uint32_t level = 0; level < num_mip_maps_; ++ level)
				{
					uint32_t const s = this->Width(level);

					if (IsCompressedFormat(format_))
					{
						uint32_t const block_size = NumFormatBytes(format_) * 4;
						GLsizei const image_size = ((s + 3) / 4) * ((s + 3) / 4) * block_size;

						void* ptr;
						if (nullptr == init_data)
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size, 0);
							ptr = nullptr;
						}
						else
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size);
							std::memcpy(&tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0],
								init_data[(array_index * 6 + face) * num_mip_maps_ + level].data, image_size);
							ptr = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0];
						}

						if (array_size_ > 1)
						{
							if (0 == array_index)
							{
								glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
									s, s, array_size_, 0, image_size * array_size_, nullptr);
							}

							if (init_data != nullptr)
							{
								glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, 0, 0, array_index, s, s, 1,
									glformat, image_size, init_data[(array_index * 6 + face) * num_mip_maps_ + level].data);
							}
						}
						else
						{
							glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
								s, s, 0, image_size, ptr);
						}
					}
					else
					{
						GLsizei const image_size = s * s * texel_size;

						void* ptr;
						if (nullptr == init_data)
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size, 0);
							ptr = nullptr;
						}
						else
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size);
							std::memcpy(&tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0],
								init_data[face * num_mip_maps_ + level].data, image_size);
							ptr = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0];
						}

						if (array_size_ > 1)
						{
							if (0 == array_index)
							{
								glTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat, s, s, array_size_, 0, glformat, gltype, nullptr);
							}

							if (init_data != nullptr)
							{
								glTexSubImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, 0, 0, array_index, s, s, 1,
									glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
							}
						}
						else
						{
							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
								s, s, 0, glformat, gltype, ptr);
						}
					}
				}
			}
		}

		hw_res_ready_ = true;
	}
Exemplo n.º 28
0
	void OGLTexture1D::Unmap1D(uint32_t array_index, uint32_t level)
	{
		OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		switch (last_tma_)
		{
		case TMA_Read_Only:
			re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			re.BindBuffer(GL_PIXEL_PACK_BUFFER, pbo_);
			glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
			break;

		case TMA_Write_Only:
		case TMA_Read_Write:
			{
				GLint gl_internalFormat;
				GLenum gl_format;
				GLenum gl_type;
				OGLMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

				uint32_t const w = this->Width(level);

				re.BindTexture(0, target_type_, texture_);

				re.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_);
				glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);

				GLvoid* offset = reinterpret_cast<GLvoid*>(
					static_cast<GLintptr>(array_index * mipmap_start_offset_.back() + mipmap_start_offset_[level]));
				if (IsCompressedFormat(format_))
				{
					uint32_t const block_size = NumFormatBytes(format_) * 4;
					GLsizei const image_size = ((w + 3) / 4) * block_size;

					if (array_size_ > 1)
					{
						glCompressedTexSubImage2D(target_type_, level, 0, array_index,
							w, 1, gl_format, image_size, offset);
					}
					else
					{
						glCompressedTexSubImage1D(target_type_, level, 0,
							w, gl_format, image_size, offset);
					}
				}
				else
				{
					if (array_size_ > 1)
					{
						glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
							gl_format, gl_type, offset);
					}
					else
					{
						glTexSubImage1D(target_type_, level, 0, w, gl_format, gl_type, offset);
					}
				}
			}
			break;

		default:
			KFL_UNREACHABLE("Invalid texture map access mode");
		}
	}