forked from eden-emu/eden
		
	gl_rasterizer: Implement image bindings
This commit is contained in:
		
							parent
							
								
									714bd740bb
								
							
						
					
					
						commit
						0c8851163d
					
				
					 5 changed files with 106 additions and 32 deletions
				
			
		|  | @ -62,6 +62,7 @@ public: | |||
|         static constexpr std::size_t NumVertexAttributes = 32; | ||||
|         static constexpr std::size_t NumVaryings = 31; | ||||
|         static constexpr std::size_t NumTextureSamplers = 32; | ||||
|         static constexpr std::size_t NumImages = 8; // TODO(Rodrigo): Investigate this number
 | ||||
|         static constexpr std::size_t NumClipDistances = 8; | ||||
|         static constexpr std::size_t MaxShaderProgram = 6; | ||||
|         static constexpr std::size_t MaxShaderStage = 5; | ||||
|  |  | |||
|  | @ -1022,7 +1022,7 @@ bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding, | |||
|     auto& unit{state.texture_units[binding]}; | ||||
|     unit.sampler = sampler_cache.GetSampler(texture.tsc); | ||||
| 
 | ||||
|     const auto view = texture_cache.GetImageSurface(texture.tic, entry); | ||||
|     const auto view = texture_cache.GetTextureSurface(texture.tic, entry); | ||||
|     if (!view) { | ||||
|         // Can occur when texture addr is null or its memory is unmapped/invalid
 | ||||
|         unit.texture = 0; | ||||
|  | @ -1054,7 +1054,12 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { | |||
|             tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second); | ||||
|             return compute.GetTextureInfo(tex_handle, entry.GetOffset()); | ||||
|         }(); | ||||
|         UNIMPLEMENTED(); | ||||
|         const auto view = texture_cache.GetImageSurface(texture.tic, entry); | ||||
|         if (!view) { | ||||
|             state.images[bindpoint] = 0; | ||||
|             continue; | ||||
|         } | ||||
|         state.images[bindpoint] = view->GetTexture(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,44 +24,52 @@ using VideoCore::Surface::SurfaceTarget; | |||
| using VideoCore::Surface::SurfaceTargetFromTextureType; | ||||
| using VideoCore::Surface::SurfaceType; | ||||
| 
 | ||||
| SurfaceTarget TextureType2SurfaceTarget(Tegra::Shader::TextureType type, bool is_array) { | ||||
| namespace { | ||||
| 
 | ||||
| SurfaceTarget TextureTypeToSurfaceTarget(Tegra::Shader::TextureType type, bool is_array) { | ||||
|     switch (type) { | ||||
|     case Tegra::Shader::TextureType::Texture1D: { | ||||
|         if (is_array) | ||||
|             return SurfaceTarget::Texture1DArray; | ||||
|         else | ||||
|             return SurfaceTarget::Texture1D; | ||||
|     } | ||||
|     case Tegra::Shader::TextureType::Texture2D: { | ||||
|         if (is_array) | ||||
|             return SurfaceTarget::Texture2DArray; | ||||
|         else | ||||
|             return SurfaceTarget::Texture2D; | ||||
|     } | ||||
|     case Tegra::Shader::TextureType::Texture3D: { | ||||
|     case Tegra::Shader::TextureType::Texture1D: | ||||
|         return is_array ? SurfaceTarget::Texture1DArray : SurfaceTarget::Texture1D; | ||||
|     case Tegra::Shader::TextureType::Texture2D: | ||||
|         return is_array ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D; | ||||
|     case Tegra::Shader::TextureType::Texture3D: | ||||
|         ASSERT(!is_array); | ||||
|         return SurfaceTarget::Texture3D; | ||||
|     } | ||||
|     case Tegra::Shader::TextureType::TextureCube: { | ||||
|         if (is_array) | ||||
|             return SurfaceTarget::TextureCubeArray; | ||||
|         else | ||||
|             return SurfaceTarget::TextureCubemap; | ||||
|     } | ||||
|     default: { | ||||
|     case Tegra::Shader::TextureType::TextureCube: | ||||
|         return is_array ? SurfaceTarget::TextureCubeArray : SurfaceTarget::TextureCubemap; | ||||
|     default: | ||||
|         UNREACHABLE(); | ||||
|         return SurfaceTarget::Texture2D; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| SurfaceTarget ImageTypeToSurfaceTarget(Tegra::Shader::ImageType type) { | ||||
|     switch (type) { | ||||
|     case Tegra::Shader::ImageType::Texture1D: | ||||
|         return SurfaceTarget::Texture1D; | ||||
|     case Tegra::Shader::ImageType::TextureBuffer: | ||||
|         return SurfaceTarget::TextureBuffer; | ||||
|     case Tegra::Shader::ImageType::Texture1DArray: | ||||
|         return SurfaceTarget::Texture1DArray; | ||||
|     case Tegra::Shader::ImageType::Texture2D: | ||||
|         return SurfaceTarget::Texture2D; | ||||
|     case Tegra::Shader::ImageType::Texture2DArray: | ||||
|         return SurfaceTarget::Texture2DArray; | ||||
|     case Tegra::Shader::ImageType::Texture3D: | ||||
|         return SurfaceTarget::Texture3D; | ||||
|     default: | ||||
|         UNREACHABLE(); | ||||
|         return SurfaceTarget::Texture2D; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace { | ||||
| constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { | ||||
|     return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile); | ||||
| } | ||||
| 
 | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | ||||
| SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& tic, | ||||
|                                               const VideoCommon::Shader::Sampler& entry) { | ||||
|     SurfaceParams params; | ||||
|     params.is_tiled = tic.IsTiled(); | ||||
|  | @ -94,8 +102,17 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | |||
|     params.component_type = ComponentTypeFromTexture(tic.r_type.Value()); | ||||
|     params.type = GetFormatType(params.pixel_format); | ||||
|     // TODO: on 1DBuffer we should use the tic info.
 | ||||
|     if (!tic.IsBuffer()) { | ||||
|         params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); | ||||
|     if (tic.IsBuffer()) { | ||||
|         params.target = SurfaceTarget::TextureBuffer; | ||||
|         params.width = tic.Width(); | ||||
|         params.pitch = params.width * params.GetBytesPerPixel(); | ||||
|         params.height = 1; | ||||
|         params.depth = 1; | ||||
|         params.num_levels = 1; | ||||
|         params.emulated_levels = 1; | ||||
|         params.is_layered = false; | ||||
|     } else { | ||||
|         params.target = TextureTypeToSurfaceTarget(entry.GetType(), entry.IsArray()); | ||||
|         params.width = tic.Width(); | ||||
|         params.height = tic.Height(); | ||||
|         params.depth = tic.Depth(); | ||||
|  | @ -107,7 +124,27 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | |||
|         params.num_levels = tic.max_mip_level + 1; | ||||
|         params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap()); | ||||
|         params.is_layered = params.IsLayered(); | ||||
|     } else { | ||||
|     } | ||||
|     return params; | ||||
| } | ||||
| 
 | ||||
| SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | ||||
|                                             const VideoCommon::Shader::Image& entry) { | ||||
|     SurfaceParams params; | ||||
|     params.is_tiled = tic.IsTiled(); | ||||
|     params.srgb_conversion = tic.IsSrgbConversionEnabled(); | ||||
|     params.block_width = params.is_tiled ? tic.BlockWidth() : 0, | ||||
|     params.block_height = params.is_tiled ? tic.BlockHeight() : 0, | ||||
|     params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, | ||||
|     params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; | ||||
|     params.pixel_format = | ||||
|         PixelFormatFromTextureFormat(tic.format, tic.r_type.Value(), params.srgb_conversion); | ||||
|     params.type = GetFormatType(params.pixel_format); | ||||
|     params.component_type = ComponentTypeFromTexture(tic.r_type.Value()); | ||||
|     params.type = GetFormatType(params.pixel_format); | ||||
|     params.target = ImageTypeToSurfaceTarget(entry.GetType()); | ||||
|     // TODO: on 1DBuffer we should use the tic info.
 | ||||
|     if (tic.IsBuffer()) { | ||||
|         params.target = SurfaceTarget::TextureBuffer; | ||||
|         params.width = tic.Width(); | ||||
|         params.pitch = params.width * params.GetBytesPerPixel(); | ||||
|  | @ -116,6 +153,18 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | |||
|         params.num_levels = 1; | ||||
|         params.emulated_levels = 1; | ||||
|         params.is_layered = false; | ||||
|     } else { | ||||
|         params.width = tic.Width(); | ||||
|         params.height = tic.Height(); | ||||
|         params.depth = tic.Depth(); | ||||
|         params.pitch = params.is_tiled ? 0 : tic.Pitch(); | ||||
|         if (params.target == SurfaceTarget::TextureCubemap || | ||||
|             params.target == SurfaceTarget::TextureCubeArray) { | ||||
|             params.depth *= 6; | ||||
|         } | ||||
|         params.num_levels = tic.max_mip_level + 1; | ||||
|         params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap()); | ||||
|         params.is_layered = params.IsLayered(); | ||||
|     } | ||||
|     return params; | ||||
| } | ||||
|  |  | |||
|  | @ -23,9 +23,13 @@ using VideoCore::Surface::SurfaceCompression; | |||
| class SurfaceParams { | ||||
| public: | ||||
|     /// Creates SurfaceCachedParams from a texture configuration.
 | ||||
|     static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic, | ||||
|     static SurfaceParams CreateForTexture(const Tegra::Texture::TICEntry& tic, | ||||
|                                           const VideoCommon::Shader::Sampler& entry); | ||||
| 
 | ||||
|     /// Creates SurfaceCachedParams from an image configuration.
 | ||||
|     static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic, | ||||
|                                         const VideoCommon::Shader::Image& entry); | ||||
| 
 | ||||
|     /// Creates SurfaceCachedParams for a depth buffer configuration.
 | ||||
|     static SurfaceParams CreateForDepthBuffer( | ||||
|         Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format, | ||||
|  |  | |||
|  | @ -89,13 +89,28 @@ public: | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     TView GetImageSurface(const Tegra::Texture::TICEntry& tic, | ||||
|     TView GetTextureSurface(const Tegra::Texture::TICEntry& tic, | ||||
|                             const VideoCommon::Shader::Sampler& entry) { | ||||
|         std::lock_guard lock{mutex}; | ||||
|         const auto gpu_addr{tic.Address()}; | ||||
|         if (!gpu_addr) { | ||||
|             return {}; | ||||
|         } | ||||
|         const auto params{SurfaceParams::CreateForTexture(tic, entry)}; | ||||
|         const auto [surface, view] = GetSurface(gpu_addr, params, true, false); | ||||
|         if (guard_samplers) { | ||||
|             sampled_textures.push_back(surface); | ||||
|         } | ||||
|         return view; | ||||
|     } | ||||
| 
 | ||||
|     TView GetImageSurface(const Tegra::Texture::TICEntry& tic, | ||||
|                           const VideoCommon::Shader::Image& entry) { | ||||
|         std::lock_guard lock{mutex}; | ||||
|         const auto gpu_addr{tic.Address()}; | ||||
|         if (!gpu_addr) { | ||||
|             return {}; | ||||
|         } | ||||
|         const auto params{SurfaceParams::CreateForImage(tic, entry)}; | ||||
|         const auto [surface, view] = GetSurface(gpu_addr, params, true, false); | ||||
|         if (guard_samplers) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ReinUsesLisp
						ReinUsesLisp