video_core: Merge tex0 and tex_cube (#7173)
This commit is contained in:
		| @@ -14,7 +14,7 @@ | ||||
| #include "video_core/renderer_opengl/gl_rasterizer.h" | ||||
| #include "video_core/renderer_opengl/pica_to_gl.h" | ||||
| #include "video_core/renderer_opengl/renderer_opengl.h" | ||||
| #include "video_core/shader/generator/glsl_shader_gen.h" | ||||
| #include "video_core/shader/generator/shader_gen.h" | ||||
| #include "video_core/texture/texture_decode.h" | ||||
| #include "video_core/video_core.h" | ||||
|  | ||||
| @@ -576,10 +576,9 @@ void RasterizerOpenGL::BindTextureCube(const Pica::TexturingRegs::FullTextureCon | ||||
|  | ||||
|     Surface& surface = res_cache.GetTextureCube(config); | ||||
|     Sampler& sampler = res_cache.GetSampler(texture.config); | ||||
|  | ||||
|     state.texture_cube_unit.texture_cube = surface.Handle(); | ||||
|     state.texture_cube_unit.sampler = sampler.Handle(); | ||||
|     state.texture_units[0].texture_2d = 0; | ||||
|     state.texture_units[0].target = GL_TEXTURE_CUBE_MAP; | ||||
|     state.texture_units[0].texture_2d = surface.Handle(); | ||||
|     state.texture_units[0].sampler = sampler.Handle(); | ||||
| } | ||||
|  | ||||
| void RasterizerOpenGL::BindMaterial(u32 texture_index, Surface& surface) { | ||||
| @@ -612,7 +611,8 @@ bool RasterizerOpenGL::IsFeedbackLoop(u32 texture_index, const Framebuffer* fram | ||||
| } | ||||
|  | ||||
| void RasterizerOpenGL::UnbindSpecial() { | ||||
|     state.texture_cube_unit.texture_cube = 0; | ||||
|     state.texture_units[0].texture_2d = 0; | ||||
|     state.texture_units[0].target = GL_TEXTURE_2D; | ||||
|     state.image_shadow_texture_px = 0; | ||||
|     state.image_shadow_texture_nx = 0; | ||||
|     state.image_shadow_texture_py = 0; | ||||
|   | ||||
| @@ -50,11 +50,11 @@ OpenGLState::OpenGLState() { | ||||
|  | ||||
|     for (auto& texture_unit : texture_units) { | ||||
|         texture_unit.texture_2d = 0; | ||||
|         texture_unit.target = GL_TEXTURE_2D; | ||||
|         texture_unit.sampler = 0; | ||||
|     } | ||||
|  | ||||
|     texture_cube_unit.texture_cube = 0; | ||||
|     texture_cube_unit.sampler = 0; | ||||
|     color_buffer.texture_2d = 0; | ||||
|  | ||||
|     texture_buffer_lut_lf.texture_buffer = 0; | ||||
|     texture_buffer_lut_rg.texture_buffer = 0; | ||||
| @@ -213,21 +213,13 @@ void OpenGLState::Apply() const { | ||||
|     for (u32 i = 0; i < texture_units.size(); ++i) { | ||||
|         if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { | ||||
|             glActiveTexture(TextureUnits::PicaTexture(i).Enum()); | ||||
|             glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); | ||||
|             glBindTexture(texture_units[i].target, texture_units[i].texture_2d); | ||||
|         } | ||||
|         if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { | ||||
|             glBindSampler(i, texture_units[i].sampler); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (texture_cube_unit.texture_cube != cur_state.texture_cube_unit.texture_cube) { | ||||
|         glActiveTexture(TextureUnits::TextureCube.Enum()); | ||||
|         glBindTexture(GL_TEXTURE_CUBE_MAP, texture_cube_unit.texture_cube); | ||||
|     } | ||||
|     if (texture_cube_unit.sampler != cur_state.texture_cube_unit.sampler) { | ||||
|         glBindSampler(TextureUnits::TextureCube.id, texture_cube_unit.sampler); | ||||
|     } | ||||
|  | ||||
|     // Texture buffer LUTs | ||||
|     if (texture_buffer_lut_lf.texture_buffer != cur_state.texture_buffer_lut_lf.texture_buffer) { | ||||
|         glActiveTexture(TextureUnits::TextureBufferLUT_LF.Enum()); | ||||
| @@ -368,8 +360,6 @@ OpenGLState& OpenGLState::ResetTexture(GLuint handle) { | ||||
|             unit.texture_2d = 0; | ||||
|         } | ||||
|     } | ||||
|     if (texture_cube_unit.texture_cube == handle) | ||||
|         texture_cube_unit.texture_cube = 0; | ||||
|     if (texture_buffer_lut_lf.texture_buffer == handle) | ||||
|         texture_buffer_lut_lf.texture_buffer = 0; | ||||
|     if (texture_buffer_lut_rg.texture_buffer == handle) | ||||
| @@ -399,9 +389,6 @@ OpenGLState& OpenGLState::ResetSampler(GLuint handle) { | ||||
|             unit.sampler = 0; | ||||
|         } | ||||
|     } | ||||
|     if (texture_cube_unit.sampler == handle) { | ||||
|         texture_cube_unit.sampler = 0; | ||||
|     } | ||||
|     return *this; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,12 +22,11 @@ constexpr TextureUnit PicaTexture(int unit) { | ||||
|     return TextureUnit{unit}; | ||||
| } | ||||
|  | ||||
| constexpr TextureUnit TextureCube{6}; | ||||
| constexpr TextureUnit TextureBufferLUT_LF{3}; | ||||
| constexpr TextureUnit TextureBufferLUT_RG{4}; | ||||
| constexpr TextureUnit TextureBufferLUT_RGBA{5}; | ||||
| constexpr TextureUnit TextureNormalMap{7}; | ||||
| constexpr TextureUnit TextureColorBuffer{10}; | ||||
| constexpr TextureUnit TextureNormalMap{6}; | ||||
| constexpr TextureUnit TextureColorBuffer{7}; | ||||
|  | ||||
| } // namespace TextureUnits | ||||
|  | ||||
| @@ -95,15 +94,11 @@ public: | ||||
|     // 3 texture units - one for each that is used in PICA fragment shader emulation | ||||
|     struct TextureUnit { | ||||
|         GLuint texture_2d; // GL_TEXTURE_BINDING_2D | ||||
|         GLenum target;     // GL_TEXTURE_TARGET | ||||
|         GLuint sampler;    // GL_SAMPLER_BINDING | ||||
|     }; | ||||
|     std::array<TextureUnit, 3> texture_units; | ||||
|  | ||||
|     struct { | ||||
|         GLuint texture_cube; // GL_TEXTURE_BINDING_CUBE_MAP | ||||
|         GLuint sampler;      // GL_SAMPLER_BINDING | ||||
|     } texture_cube_unit; | ||||
|  | ||||
|     struct { | ||||
|         GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER | ||||
|     } texture_buffer_lut_lf; | ||||
|   | ||||
| @@ -61,11 +61,10 @@ constexpr std::array<vk::DescriptorSetLayoutBinding, 6> BUFFER_BINDINGS = {{ | ||||
|     {5, vk::DescriptorType::eUniformTexelBuffer, 1, vk::ShaderStageFlagBits::eFragment}, | ||||
| }}; | ||||
|  | ||||
| constexpr std::array<vk::DescriptorSetLayoutBinding, 4> TEXTURE_BINDINGS = {{ | ||||
| constexpr std::array<vk::DescriptorSetLayoutBinding, 3> TEXTURE_BINDINGS = {{ | ||||
|     {0, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment}, | ||||
|     {1, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment}, | ||||
|     {2, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment}, | ||||
|     {3, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment}, | ||||
| }}; | ||||
|  | ||||
| // TODO: Use descriptor array for shadow cube | ||||
|   | ||||
| @@ -119,12 +119,10 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, | ||||
|     pipeline_cache.BindTexelBuffer(5, *texture_rgba_view); | ||||
|  | ||||
|     Surface& null_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_ID); | ||||
|     Surface& null_cube_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_CUBE_ID); | ||||
|     Sampler& null_sampler = res_cache.GetSampler(VideoCore::NULL_SAMPLER_ID); | ||||
|     for (u32 i = 0; i < 3; i++) { | ||||
|         pipeline_cache.BindTexture(i, null_surface.ImageView(), null_sampler.Handle()); | ||||
|     } | ||||
|     pipeline_cache.BindTexture(3, null_cube_surface.ImageView(), null_sampler.Handle()); | ||||
|  | ||||
|     for (u32 i = 0; i < 7; i++) { | ||||
|         pipeline_cache.BindStorageImage(i, null_surface.StorageView()); | ||||
| @@ -637,7 +635,7 @@ void RasterizerVulkan::BindTextureCube(const Pica::TexturingRegs::FullTextureCon | ||||
|  | ||||
|     Surface& surface = res_cache.GetTextureCube(config); | ||||
|     Sampler& sampler = res_cache.GetSampler(texture.config); | ||||
|     pipeline_cache.BindTexture(3, surface.ImageView(), sampler.Handle()); | ||||
|     pipeline_cache.BindTexture(0, surface.ImageView(), sampler.Handle()); | ||||
| } | ||||
|  | ||||
| bool RasterizerVulkan::IsFeedbackLoop(u32 texture_index, const Framebuffer* framebuffer, | ||||
| @@ -655,9 +653,6 @@ bool RasterizerVulkan::IsFeedbackLoop(u32 texture_index, const Framebuffer* fram | ||||
|  | ||||
| void RasterizerVulkan::UnbindSpecial() { | ||||
|     Surface& null_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_ID); | ||||
|     const Surface& null_cube_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_CUBE_ID); | ||||
|     const Sampler& null_sampler = res_cache.GetSampler(VideoCore::NULL_SAMPLER_ID); | ||||
|     pipeline_cache.BindTexture(3, null_cube_surface.ImageView(), null_sampler.Handle()); | ||||
|     for (u32 i = 0; i < 6; i++) { | ||||
|         pipeline_cache.BindStorageImage(i, null_surface.StorageView()); | ||||
|     } | ||||
|   | ||||
| @@ -10,6 +10,7 @@ using ProcTexClamp = TexturingRegs::ProcTexClamp; | ||||
| using ProcTexShift = TexturingRegs::ProcTexShift; | ||||
| using ProcTexCombiner = TexturingRegs::ProcTexCombiner; | ||||
| using ProcTexFilter = TexturingRegs::ProcTexFilter; | ||||
| using TextureType = Pica::TexturingRegs::TextureConfig::TextureType; | ||||
|  | ||||
| constexpr static size_t RESERVE_SIZE = 8 * 1024 * 1024; | ||||
|  | ||||
| @@ -1265,7 +1266,7 @@ void FragmentModule::DefineExtensions() { | ||||
|             out += "#extension GL_ARM_shader_framebuffer_fetch : enable\n"; | ||||
|             out += "#define destFactor gl_LastFragColorARM\n"; | ||||
|         } else { | ||||
|             out += "#define destFactor texelFetch(color_buffer, ivec2(gl_FragCoord.xy), 0)\n"; | ||||
|             out += "#define destFactor texelFetch(tex_color, ivec2(gl_FragCoord.xy), 0)\n"; | ||||
|             use_blend_fallback = true; | ||||
|         } | ||||
|     } | ||||
| @@ -1301,27 +1302,32 @@ void FragmentModule::DefineInterface() { | ||||
| } | ||||
|  | ||||
| void FragmentModule::DefineBindings() { | ||||
|     // Uniform and texture buffers | ||||
|     out += FSUniformBlockDef; | ||||
|     out += "layout(binding = 3) uniform samplerBuffer texture_buffer_lut_lf;\n"; | ||||
|     out += "layout(binding = 4) uniform samplerBuffer texture_buffer_lut_rg;\n"; | ||||
|     out += "layout(binding = 5) uniform samplerBuffer texture_buffer_lut_rgba;\n\n"; | ||||
|  | ||||
|     const std::string_view texunit_set = profile.is_vulkan ? "set = 1, " : ""; | ||||
|     // Texture samplers | ||||
|     const auto texunit_set = profile.is_vulkan ? "set = 1, " : ""; | ||||
|     const auto texture_type = config.texture.texture0_type.Value(); | ||||
|     for (u32 i = 0; i < 3; i++) { | ||||
|         out += fmt::format("layout({0}binding = {1}) uniform sampler2D tex{1};\n", texunit_set, i); | ||||
|         const auto sampler = | ||||
|             i == 0 && texture_type == TextureType::TextureCube ? "samplerCube" : "sampler2D"; | ||||
|         out += | ||||
|             fmt::format("layout({0}binding = {1}) uniform {2} tex{1};\n", texunit_set, i, sampler); | ||||
|     } | ||||
|  | ||||
|     out += fmt::format("layout({}binding = 3) uniform samplerCube tex_cube;\n\n", texunit_set); | ||||
|  | ||||
|     if (config.user.use_custom_normal && !profile.is_vulkan) { | ||||
|         out += "layout(binding = 7) uniform sampler2D tex_normal;\n"; | ||||
|         out += "layout(binding = 6) uniform sampler2D tex_normal;\n"; | ||||
|     } | ||||
|     if (use_blend_fallback && !profile.is_vulkan) { | ||||
|         out += "layout(location = 10) uniform sampler2D color_buffer;\n"; | ||||
|         out += "layout(location = 7) uniform sampler2D tex_color;\n"; | ||||
|     } | ||||
|  | ||||
|     // Storage images | ||||
|     static constexpr std::array postfixes = {"px", "nx", "py", "ny", "pz", "nz"}; | ||||
|     const std::string_view shadow_set = profile.is_vulkan ? "set = 2, " : ""; | ||||
|     const auto shadow_set = profile.is_vulkan ? "set = 2, " : ""; | ||||
|     for (u32 i = 0; i < postfixes.size(); i++) { | ||||
|         out += fmt::format( | ||||
|             "layout({}binding = {}, r32ui) uniform readonly uimage2D shadow_texture_{};\n", | ||||
| @@ -1591,7 +1597,7 @@ void FragmentModule::DefineTexUnitSampler(u32 texture_unit) { | ||||
|             out += "return textureProj(tex0, vec3(texcoord0, texcoord0_w));"; | ||||
|             break; | ||||
|         case TexturingRegs::TextureConfig::TextureCube: | ||||
|             out += "return texture(tex_cube, vec3(texcoord0, texcoord0_w));"; | ||||
|             out += "return texture(tex0, vec3(texcoord0, texcoord0_w));"; | ||||
|             break; | ||||
|         case TexturingRegs::TextureConfig::Shadow2D: | ||||
|             out += "return shadowTexture(texcoord0, texcoord0_w);"; | ||||
|   | ||||
| @@ -12,6 +12,7 @@ using Pica::LightingRegs; | ||||
| using Pica::RasterizerRegs; | ||||
| using Pica::TexturingRegs; | ||||
| using TevStageConfig = TexturingRegs::TevStageConfig; | ||||
| using TextureType = TexturingRegs::TextureConfig::TextureType; | ||||
|  | ||||
| constexpr u32 SPIRV_VERSION_1_3 = 0x00010300; | ||||
|  | ||||
| @@ -977,7 +978,7 @@ void FragmentModule::DefineTexSampler(u32 texture_unit) { | ||||
|     }; | ||||
|  | ||||
|     const auto sample_3d = [&](Id tex_id, bool projection) { | ||||
|         const Id image_type = tex_id.value == tex_cube_id.value ? image_cube_id : image2d_id; | ||||
|         const Id image_type = !projection ? image_cube_id : image2d_id; | ||||
|         const Id sampled_image{OpLoad(TypeSampledImage(image_type), tex_id)}; | ||||
|         const Id texcoord0_w{OpLoad(f32_id, texcoord0_w_id)}; | ||||
|         const Id coord{OpCompositeConstruct(vec_ids.Get(3), OpCompositeExtract(f32_id, texcoord, 0), | ||||
| @@ -1001,7 +1002,7 @@ void FragmentModule::DefineTexSampler(u32 texture_unit) { | ||||
|             ret_val = sample_3d(tex0_id, true); | ||||
|             break; | ||||
|         case Pica::TexturingRegs::TextureConfig::TextureCube: | ||||
|             ret_val = sample_3d(tex_cube_id, false); | ||||
|             ret_val = sample_3d(tex0_id, false); | ||||
|             break; | ||||
|         case Pica::TexturingRegs::TextureConfig::Shadow2D: | ||||
|             ret_val = SampleShadow(); | ||||
| @@ -1564,20 +1565,24 @@ void FragmentModule::DefineInterface() { | ||||
|     view_id = DefineInput(vec_ids.Get(3), 7); | ||||
|     color_id = DefineOutput(vec_ids.Get(4), 0); | ||||
|  | ||||
|     // Define the texture unit samplers/uniforms | ||||
|     // Define the texture unit samplers types | ||||
|     image_buffer_id = TypeImage(f32_id, spv::Dim::Buffer, 0, 0, 0, 1, spv::ImageFormat::Unknown); | ||||
|     image2d_id = TypeImage(f32_id, spv::Dim::Dim2D, 0, 0, 0, 1, spv::ImageFormat::Unknown); | ||||
|     image_cube_id = TypeImage(f32_id, spv::Dim::Cube, 0, 0, 0, 1, spv::ImageFormat::Unknown); | ||||
|     image_r32_id = TypeImage(u32_id, spv::Dim::Dim2D, 0, 0, 0, 2, spv::ImageFormat::R32ui); | ||||
|     sampler_id = TypeSampler(); | ||||
|  | ||||
|     // Define lighting texture buffers | ||||
|     texture_buffer_lut_lf_id = DefineUniformConst(image_buffer_id, 0, 3); | ||||
|     texture_buffer_lut_rg_id = DefineUniformConst(image_buffer_id, 0, 4); | ||||
|     texture_buffer_lut_rgba_id = DefineUniformConst(image_buffer_id, 0, 5); | ||||
|     tex0_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 0); | ||||
|  | ||||
|     // Define texture unit samplers | ||||
|     const auto texture_type = config.texture.texture0_type.Value(); | ||||
|     const auto tex0_type = texture_type == TextureType::TextureCube ? image_cube_id : image2d_id; | ||||
|     tex0_id = DefineUniformConst(TypeSampledImage(tex0_type), 1, 0); | ||||
|     tex1_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 1); | ||||
|     tex2_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 2); | ||||
|     tex_cube_id = DefineUniformConst(TypeSampledImage(image_cube_id), 1, 3); | ||||
|  | ||||
|     // Define shadow textures | ||||
|     shadow_texture_px_id = DefineUniformConst(image_r32_id, 2, 0, true); | ||||
|   | ||||
| @@ -252,7 +252,6 @@ private: | ||||
|     Id tex0_id{}; | ||||
|     Id tex1_id{}; | ||||
|     Id tex2_id{}; | ||||
|     Id tex_cube_id{}; | ||||
|     Id texture_buffer_lut_lf_id{}; | ||||
|     Id texture_buffer_lut_rg_id{}; | ||||
|     Id texture_buffer_lut_rgba_id{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 GPUCode
					GPUCode