summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp132
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h22
4 files changed, 126 insertions, 38 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 61b6fe4b7..a40106c87 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -178,7 +178,10 @@ void ComputePipeline::Configure() {
178 for (const auto& desc : info.image_descriptors) { 178 for (const auto& desc : info.image_descriptors) {
179 for (u32 index = 0; index < desc.count; ++index) { 179 for (u32 index = 0; index < desc.count; ++index) {
180 ImageView& image_view{texture_cache.GetImageView(*(views_it++))}; 180 ImageView& image_view{texture_cache.GetImageView(*(views_it++))};
181 images[image_binding++] = image_view.Handle(desc.type); 181 if (desc.is_written) {
182 texture_cache.MarkModification(image_view.image_id);
183 }
184 images[image_binding++] = image_view.StorageView(desc.type, desc.format);
182 } 185 }
183 } 186 }
184 if (texture_binding != 0) { 187 if (texture_binding != 0) {
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index a5d65fdca..a2ea35d5a 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -332,7 +332,10 @@ void GraphicsPipeline::Configure(bool is_indexed) {
332 for (const auto& desc : info.image_descriptors) { 332 for (const auto& desc : info.image_descriptors) {
333 for (u32 index = 0; index < desc.count; ++index) { 333 for (u32 index = 0; index < desc.count; ++index) {
334 ImageView& image_view{texture_cache.GetImageView(*(views_it++))}; 334 ImageView& image_view{texture_cache.GetImageView(*(views_it++))};
335 images[image_binding++] = image_view.Handle(desc.type); 335 if (desc.is_written) {
336 texture_cache.MarkModification(image_view.image_id);
337 }
338 images[image_binding++] = image_view.StorageView(desc.type, desc.format);
336 } 339 }
337 } 340 }
338 }}; 341 }};
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 7053be161..c373c9cb4 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -328,6 +328,28 @@ void AttachTexture(GLuint fbo, GLenum attachment, const ImageView* image_view) {
328 } 328 }
329} 329}
330 330
331[[nodiscard]] GLenum ShaderFormat(Shader::ImageFormat format) {
332 switch (format) {
333 case Shader::ImageFormat::Typeless:
334 break;
335 case Shader::ImageFormat::R8_SINT:
336 return GL_R8I;
337 case Shader::ImageFormat::R8_UINT:
338 return GL_R8UI;
339 case Shader::ImageFormat::R16_UINT:
340 return GL_R16UI;
341 case Shader::ImageFormat::R16_SINT:
342 return GL_R16I;
343 case Shader::ImageFormat::R32_UINT:
344 return GL_R32UI;
345 case Shader::ImageFormat::R32G32_UINT:
346 return GL_RG32UI;
347 case Shader::ImageFormat::R32G32B32A32_UINT:
348 return GL_RGBA32UI;
349 }
350 UNREACHABLE_MSG("Invalid image format={}", format);
351 return GL_R32UI;
352}
331} // Anonymous namespace 353} // Anonymous namespace
332 354
333ImageBufferMap::~ImageBufferMap() { 355ImageBufferMap::~ImageBufferMap() {
@@ -837,21 +859,28 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
837 } else { 859 } else {
838 internal_format = MaxwellToGL::GetFormatTuple(format).internal_format; 860 internal_format = MaxwellToGL::GetFormatTuple(format).internal_format;
839 } 861 }
840 VideoCommon::SubresourceRange flatten_range = info.range; 862 full_range = info.range;
841 std::array<GLuint, 2> handles; 863 flat_range = info.range;
842 stored_views.reserve(2); 864 set_object_label = device.HasDebuggingToolAttached();
843 865 is_render_target = info.IsRenderTarget();
866 original_texture = image.texture.handle;
867 num_samples = image.info.num_samples;
868 if (!is_render_target) {
869 swizzle[0] = info.x_source;
870 swizzle[1] = info.y_source;
871 swizzle[2] = info.z_source;
872 swizzle[3] = info.w_source;
873 }
844 switch (info.type) { 874 switch (info.type) {
845 case ImageViewType::e1DArray: 875 case ImageViewType::e1DArray:
846 flatten_range.extent.layers = 1; 876 flat_range.extent.layers = 1;
847 [[fallthrough]]; 877 [[fallthrough]];
848 case ImageViewType::e1D: 878 case ImageViewType::e1D:
849 glGenTextures(2, handles.data()); 879 SetupView(Shader::TextureType::Color1D);
850 SetupView(device, image, Shader::TextureType::Color1D, handles[0], info, flatten_range); 880 SetupView(Shader::TextureType::ColorArray1D);
851 SetupView(device, image, Shader::TextureType::ColorArray1D, handles[1], info, info.range);
852 break; 881 break;
853 case ImageViewType::e2DArray: 882 case ImageViewType::e2DArray:
854 flatten_range.extent.layers = 1; 883 flat_range.extent.layers = 1;
855 [[fallthrough]]; 884 [[fallthrough]];
856 case ImageViewType::e2D: 885 case ImageViewType::e2D:
857 if (True(flags & VideoCommon::ImageViewFlagBits::Slice)) { 886 if (True(flags & VideoCommon::ImageViewFlagBits::Slice)) {
@@ -861,26 +890,23 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
861 .base = {.level = info.range.base.level, .layer = 0}, 890 .base = {.level = info.range.base.level, .layer = 0},
862 .extent = {.levels = 1, .layers = 1}, 891 .extent = {.levels = 1, .layers = 1},
863 }; 892 };
864 glGenTextures(1, handles.data()); 893 full_range = slice_range;
865 SetupView(device, image, Shader::TextureType::Color3D, handles[0], info, slice_range); 894
895 SetupView(Shader::TextureType::Color3D);
866 } else { 896 } else {
867 glGenTextures(2, handles.data()); 897 SetupView(Shader::TextureType::Color2D);
868 SetupView(device, image, Shader::TextureType::Color2D, handles[0], info, flatten_range); 898 SetupView(Shader::TextureType::ColorArray2D);
869 SetupView(device, image, Shader::TextureType::ColorArray2D, handles[1], info,
870 info.range);
871 } 899 }
872 break; 900 break;
873 case ImageViewType::e3D: 901 case ImageViewType::e3D:
874 glGenTextures(1, handles.data()); 902 SetupView(Shader::TextureType::Color3D);
875 SetupView(device, image, Shader::TextureType::Color3D, handles[0], info, info.range);
876 break; 903 break;
877 case ImageViewType::CubeArray: 904 case ImageViewType::CubeArray:
878 flatten_range.extent.layers = 6; 905 flat_range.extent.layers = 6;
879 [[fallthrough]]; 906 [[fallthrough]];
880 case ImageViewType::Cube: 907 case ImageViewType::Cube:
881 glGenTextures(2, handles.data()); 908 SetupView(Shader::TextureType::ColorCube);
882 SetupView(device, image, Shader::TextureType::ColorCube, handles[0], info, flatten_range); 909 SetupView(Shader::TextureType::ColorArrayCube);
883 SetupView(device, image, Shader::TextureType::ColorArrayCube, handles[1], info, info.range);
884 break; 910 break;
885 case ImageViewType::Rect: 911 case ImageViewType::Rect:
886 UNIMPLEMENTED(); 912 UNIMPLEMENTED();
@@ -928,22 +954,62 @@ ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
928ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageParams& params) 954ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageParams& params)
929 : VideoCommon::ImageViewBase{params}, views{runtime.null_image_views} {} 955 : VideoCommon::ImageViewBase{params}, views{runtime.null_image_views} {}
930 956
931void ImageView::SetupView(const Device& device, Image& image, Shader::TextureType view_type, 957GLuint ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) {
932 GLuint handle, const VideoCommon::ImageViewInfo& info, 958 if (image_format == Shader::ImageFormat::Typeless) {
933 VideoCommon::SubresourceRange view_range) { 959 return Handle(texture_type);
934 const GLuint parent = image.texture.handle; 960 }
935 const GLenum target = ImageTarget(view_type, image.info.num_samples); 961 const bool is_signed{image_format == Shader::ImageFormat::R8_SINT ||
936 glTextureView(handle, target, parent, internal_format, view_range.base.level, 962 image_format == Shader::ImageFormat::R16_SINT};
963 if (!storage_views) {
964 storage_views = std::make_unique<StorageViews>();
965 }
966 auto& type_views{is_signed ? storage_views->signeds : storage_views->unsigneds};
967 GLuint& view{type_views[static_cast<size_t>(texture_type)]};
968 if (view == 0) {
969 view = MakeView(texture_type, ShaderFormat(image_format));
970 }
971 return view;
972}
973
974void ImageView::SetupView(Shader::TextureType view_type) {
975 views[static_cast<size_t>(view_type)] = MakeView(view_type, internal_format);
976}
977
978GLuint ImageView::MakeView(Shader::TextureType view_type, GLenum view_format) {
979 VideoCommon::SubresourceRange view_range;
980 switch (view_type) {
981 case Shader::TextureType::Color1D:
982 case Shader::TextureType::Color2D:
983 case Shader::TextureType::ColorCube:
984 view_range = flat_range;
985 break;
986 case Shader::TextureType::ColorArray1D:
987 case Shader::TextureType::ColorArray2D:
988 case Shader::TextureType::Color3D:
989 case Shader::TextureType::ColorArrayCube:
990 view_range = full_range;
991 break;
992 default:
993 UNREACHABLE();
994 }
995 OGLTextureView& view = stored_views.emplace_back();
996 view.Create();
997
998 const GLenum target = ImageTarget(view_type, num_samples);
999 glTextureView(view.handle, target, original_texture, view_format, view_range.base.level,
937 view_range.extent.levels, view_range.base.layer, view_range.extent.layers); 1000 view_range.extent.levels, view_range.base.layer, view_range.extent.layers);
938 if (!info.IsRenderTarget()) { 1001 if (!is_render_target) {
939 ApplySwizzle(handle, format, info.Swizzle()); 1002 std::array<SwizzleSource, 4> casted_swizzle;
1003 std::ranges::transform(swizzle, casted_swizzle.begin(), [](u8 component_swizzle) {
1004 return static_cast<SwizzleSource>(component_swizzle);
1005 });
1006 ApplySwizzle(view.handle, format, casted_swizzle);
940 } 1007 }
941 if (device.HasDebuggingToolAttached()) { 1008 if (set_object_label) {
942 const std::string name = VideoCommon::Name(*this); 1009 const std::string name = VideoCommon::Name(*this);
943 glObjectLabel(GL_TEXTURE, handle, static_cast<GLsizei>(name.size()), name.data()); 1010 glObjectLabel(GL_TEXTURE, view.handle, static_cast<GLsizei>(name.size()), name.data());
944 } 1011 }
945 stored_views.emplace_back().handle = handle; 1012 return view.handle;
946 views[static_cast<size_t>(view_type)] = handle;
947} 1013}
948 1014
949Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { 1015Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 2e3e02b79..921072ebe 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -185,6 +185,9 @@ public:
185 const VideoCommon::ImageViewInfo& view_info); 185 const VideoCommon::ImageViewInfo& view_info);
186 explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageParams&); 186 explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageParams&);
187 187
188 [[nodiscard]] GLuint StorageView(Shader::TextureType texture_type,
189 Shader::ImageFormat image_format);
190
188 [[nodiscard]] GLuint Handle(Shader::TextureType handle_type) const noexcept { 191 [[nodiscard]] GLuint Handle(Shader::TextureType handle_type) const noexcept {
189 return views[static_cast<size_t>(handle_type)]; 192 return views[static_cast<size_t>(handle_type)];
190 } 193 }
@@ -206,16 +209,29 @@ public:
206 } 209 }
207 210
208private: 211private:
209 void SetupView(const Device& device, Image& image, Shader::TextureType view_type, GLuint handle, 212 struct StorageViews {
210 const VideoCommon::ImageViewInfo& info, 213 std::array<GLuint, Shader::NUM_TEXTURE_TYPES> signeds{};
211 VideoCommon::SubresourceRange view_range); 214 std::array<GLuint, Shader::NUM_TEXTURE_TYPES> unsigneds{};
215 };
216
217 void SetupView(Shader::TextureType view_type);
218
219 GLuint MakeView(Shader::TextureType view_type, GLenum view_format);
212 220
213 std::array<GLuint, Shader::NUM_TEXTURE_TYPES> views{}; 221 std::array<GLuint, Shader::NUM_TEXTURE_TYPES> views{};
214 std::vector<OGLTextureView> stored_views; 222 std::vector<OGLTextureView> stored_views;
223 std::unique_ptr<StorageViews> storage_views;
215 GLenum internal_format = GL_NONE; 224 GLenum internal_format = GL_NONE;
216 GLuint default_handle = 0; 225 GLuint default_handle = 0;
217 GPUVAddr gpu_addr = 0; 226 GPUVAddr gpu_addr = 0;
218 u32 buffer_size = 0; 227 u32 buffer_size = 0;
228 GLuint original_texture = 0;
229 int num_samples = 0;
230 VideoCommon::SubresourceRange flat_range;
231 VideoCommon::SubresourceRange full_range;
232 std::array<u8, 4> swizzle{};
233 bool set_object_label = false;
234 bool is_render_target = false;
219}; 235};
220 236
221class ImageAlloc : public VideoCommon::ImageAllocBase {}; 237class ImageAlloc : public VideoCommon::ImageAllocBase {};