citra-emu
/
citra
Archived
1
0
Fork 0

video_core: Merge tex0 and tex_cube (#7173)

This commit is contained in:
GPUCode 2023-11-17 13:14:10 +02:00 committed by GitHub
parent 680e132318
commit 26d5727b19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 39 additions and 53 deletions

View File

@ -14,7 +14,7 @@
#include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_rasterizer.h"
#include "video_core/renderer_opengl/pica_to_gl.h" #include "video_core/renderer_opengl/pica_to_gl.h"
#include "video_core/renderer_opengl/renderer_opengl.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/texture/texture_decode.h"
#include "video_core/video_core.h" #include "video_core/video_core.h"
@ -576,10 +576,9 @@ void RasterizerOpenGL::BindTextureCube(const Pica::TexturingRegs::FullTextureCon
Surface& surface = res_cache.GetTextureCube(config); Surface& surface = res_cache.GetTextureCube(config);
Sampler& sampler = res_cache.GetSampler(texture.config); Sampler& sampler = res_cache.GetSampler(texture.config);
state.texture_units[0].target = GL_TEXTURE_CUBE_MAP;
state.texture_cube_unit.texture_cube = surface.Handle(); state.texture_units[0].texture_2d = surface.Handle();
state.texture_cube_unit.sampler = sampler.Handle(); state.texture_units[0].sampler = sampler.Handle();
state.texture_units[0].texture_2d = 0;
} }
void RasterizerOpenGL::BindMaterial(u32 texture_index, Surface& surface) { void RasterizerOpenGL::BindMaterial(u32 texture_index, Surface& surface) {
@ -612,7 +611,8 @@ bool RasterizerOpenGL::IsFeedbackLoop(u32 texture_index, const Framebuffer* fram
} }
void RasterizerOpenGL::UnbindSpecial() { 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_px = 0;
state.image_shadow_texture_nx = 0; state.image_shadow_texture_nx = 0;
state.image_shadow_texture_py = 0; state.image_shadow_texture_py = 0;

View File

@ -50,11 +50,11 @@ OpenGLState::OpenGLState() {
for (auto& texture_unit : texture_units) { for (auto& texture_unit : texture_units) {
texture_unit.texture_2d = 0; texture_unit.texture_2d = 0;
texture_unit.target = GL_TEXTURE_2D;
texture_unit.sampler = 0; texture_unit.sampler = 0;
} }
texture_cube_unit.texture_cube = 0; color_buffer.texture_2d = 0;
texture_cube_unit.sampler = 0;
texture_buffer_lut_lf.texture_buffer = 0; texture_buffer_lut_lf.texture_buffer = 0;
texture_buffer_lut_rg.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) { for (u32 i = 0; i < texture_units.size(); ++i) {
if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) {
glActiveTexture(TextureUnits::PicaTexture(i).Enum()); 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) { if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
glBindSampler(i, 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 // Texture buffer LUTs
if (texture_buffer_lut_lf.texture_buffer != cur_state.texture_buffer_lut_lf.texture_buffer) { if (texture_buffer_lut_lf.texture_buffer != cur_state.texture_buffer_lut_lf.texture_buffer) {
glActiveTexture(TextureUnits::TextureBufferLUT_LF.Enum()); glActiveTexture(TextureUnits::TextureBufferLUT_LF.Enum());
@ -368,8 +360,6 @@ OpenGLState& OpenGLState::ResetTexture(GLuint handle) {
unit.texture_2d = 0; 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) if (texture_buffer_lut_lf.texture_buffer == handle)
texture_buffer_lut_lf.texture_buffer = 0; texture_buffer_lut_lf.texture_buffer = 0;
if (texture_buffer_lut_rg.texture_buffer == handle) if (texture_buffer_lut_rg.texture_buffer == handle)
@ -399,9 +389,6 @@ OpenGLState& OpenGLState::ResetSampler(GLuint handle) {
unit.sampler = 0; unit.sampler = 0;
} }
} }
if (texture_cube_unit.sampler == handle) {
texture_cube_unit.sampler = 0;
}
return *this; return *this;
} }

View File

@ -22,12 +22,11 @@ constexpr TextureUnit PicaTexture(int unit) {
return TextureUnit{unit}; return TextureUnit{unit};
} }
constexpr TextureUnit TextureCube{6};
constexpr TextureUnit TextureBufferLUT_LF{3}; constexpr TextureUnit TextureBufferLUT_LF{3};
constexpr TextureUnit TextureBufferLUT_RG{4}; constexpr TextureUnit TextureBufferLUT_RG{4};
constexpr TextureUnit TextureBufferLUT_RGBA{5}; constexpr TextureUnit TextureBufferLUT_RGBA{5};
constexpr TextureUnit TextureNormalMap{7}; constexpr TextureUnit TextureNormalMap{6};
constexpr TextureUnit TextureColorBuffer{10}; constexpr TextureUnit TextureColorBuffer{7};
} // namespace TextureUnits } // namespace TextureUnits
@ -95,15 +94,11 @@ public:
// 3 texture units - one for each that is used in PICA fragment shader emulation // 3 texture units - one for each that is used in PICA fragment shader emulation
struct TextureUnit { struct TextureUnit {
GLuint texture_2d; // GL_TEXTURE_BINDING_2D GLuint texture_2d; // GL_TEXTURE_BINDING_2D
GLenum target; // GL_TEXTURE_TARGET
GLuint sampler; // GL_SAMPLER_BINDING GLuint sampler; // GL_SAMPLER_BINDING
}; };
std::array<TextureUnit, 3> texture_units; std::array<TextureUnit, 3> texture_units;
struct {
GLuint texture_cube; // GL_TEXTURE_BINDING_CUBE_MAP
GLuint sampler; // GL_SAMPLER_BINDING
} texture_cube_unit;
struct { struct {
GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER
} texture_buffer_lut_lf; } texture_buffer_lut_lf;

View File

@ -61,11 +61,10 @@ constexpr std::array<vk::DescriptorSetLayoutBinding, 6> BUFFER_BINDINGS = {{
{5, vk::DescriptorType::eUniformTexelBuffer, 1, vk::ShaderStageFlagBits::eFragment}, {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}, {0, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment},
{1, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment}, {1, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment},
{2, 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 // TODO: Use descriptor array for shadow cube

View File

@ -119,12 +119,10 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory,
pipeline_cache.BindTexelBuffer(5, *texture_rgba_view); pipeline_cache.BindTexelBuffer(5, *texture_rgba_view);
Surface& null_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_ID); 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); Sampler& null_sampler = res_cache.GetSampler(VideoCore::NULL_SAMPLER_ID);
for (u32 i = 0; i < 3; i++) { for (u32 i = 0; i < 3; i++) {
pipeline_cache.BindTexture(i, null_surface.ImageView(), null_sampler.Handle()); 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++) { for (u32 i = 0; i < 7; i++) {
pipeline_cache.BindStorageImage(i, null_surface.StorageView()); pipeline_cache.BindStorageImage(i, null_surface.StorageView());
@ -637,7 +635,7 @@ void RasterizerVulkan::BindTextureCube(const Pica::TexturingRegs::FullTextureCon
Surface& surface = res_cache.GetTextureCube(config); Surface& surface = res_cache.GetTextureCube(config);
Sampler& sampler = res_cache.GetSampler(texture.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, 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() { void RasterizerVulkan::UnbindSpecial() {
Surface& null_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_ID); 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++) { for (u32 i = 0; i < 6; i++) {
pipeline_cache.BindStorageImage(i, null_surface.StorageView()); pipeline_cache.BindStorageImage(i, null_surface.StorageView());
} }

View File

@ -10,6 +10,7 @@ using ProcTexClamp = TexturingRegs::ProcTexClamp;
using ProcTexShift = TexturingRegs::ProcTexShift; using ProcTexShift = TexturingRegs::ProcTexShift;
using ProcTexCombiner = TexturingRegs::ProcTexCombiner; using ProcTexCombiner = TexturingRegs::ProcTexCombiner;
using ProcTexFilter = TexturingRegs::ProcTexFilter; using ProcTexFilter = TexturingRegs::ProcTexFilter;
using TextureType = Pica::TexturingRegs::TextureConfig::TextureType;
constexpr static size_t RESERVE_SIZE = 8 * 1024 * 1024; 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 += "#extension GL_ARM_shader_framebuffer_fetch : enable\n";
out += "#define destFactor gl_LastFragColorARM\n"; out += "#define destFactor gl_LastFragColorARM\n";
} else { } 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; use_blend_fallback = true;
} }
} }
@ -1301,27 +1302,32 @@ void FragmentModule::DefineInterface() {
} }
void FragmentModule::DefineBindings() { void FragmentModule::DefineBindings() {
// Uniform and texture buffers
out += FSUniformBlockDef; out += FSUniformBlockDef;
out += "layout(binding = 3) uniform samplerBuffer texture_buffer_lut_lf;\n"; 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 = 4) uniform samplerBuffer texture_buffer_lut_rg;\n";
out += "layout(binding = 5) uniform samplerBuffer texture_buffer_lut_rgba;\n\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++) { 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) { 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) { 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"}; 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++) { for (u32 i = 0; i < postfixes.size(); i++) {
out += fmt::format( out += fmt::format(
"layout({}binding = {}, r32ui) uniform readonly uimage2D shadow_texture_{};\n", "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));"; out += "return textureProj(tex0, vec3(texcoord0, texcoord0_w));";
break; break;
case TexturingRegs::TextureConfig::TextureCube: case TexturingRegs::TextureConfig::TextureCube:
out += "return texture(tex_cube, vec3(texcoord0, texcoord0_w));"; out += "return texture(tex0, vec3(texcoord0, texcoord0_w));";
break; break;
case TexturingRegs::TextureConfig::Shadow2D: case TexturingRegs::TextureConfig::Shadow2D:
out += "return shadowTexture(texcoord0, texcoord0_w);"; out += "return shadowTexture(texcoord0, texcoord0_w);";

View File

@ -12,6 +12,7 @@ using Pica::LightingRegs;
using Pica::RasterizerRegs; using Pica::RasterizerRegs;
using Pica::TexturingRegs; using Pica::TexturingRegs;
using TevStageConfig = TexturingRegs::TevStageConfig; using TevStageConfig = TexturingRegs::TevStageConfig;
using TextureType = TexturingRegs::TextureConfig::TextureType;
constexpr u32 SPIRV_VERSION_1_3 = 0x00010300; 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 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 sampled_image{OpLoad(TypeSampledImage(image_type), tex_id)};
const Id texcoord0_w{OpLoad(f32_id, texcoord0_w_id)}; const Id texcoord0_w{OpLoad(f32_id, texcoord0_w_id)};
const Id coord{OpCompositeConstruct(vec_ids.Get(3), OpCompositeExtract(f32_id, texcoord, 0), 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); ret_val = sample_3d(tex0_id, true);
break; break;
case Pica::TexturingRegs::TextureConfig::TextureCube: case Pica::TexturingRegs::TextureConfig::TextureCube:
ret_val = sample_3d(tex_cube_id, false); ret_val = sample_3d(tex0_id, false);
break; break;
case Pica::TexturingRegs::TextureConfig::Shadow2D: case Pica::TexturingRegs::TextureConfig::Shadow2D:
ret_val = SampleShadow(); ret_val = SampleShadow();
@ -1564,20 +1565,24 @@ void FragmentModule::DefineInterface() {
view_id = DefineInput(vec_ids.Get(3), 7); view_id = DefineInput(vec_ids.Get(3), 7);
color_id = DefineOutput(vec_ids.Get(4), 0); 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); 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); 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_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); image_r32_id = TypeImage(u32_id, spv::Dim::Dim2D, 0, 0, 0, 2, spv::ImageFormat::R32ui);
sampler_id = TypeSampler(); sampler_id = TypeSampler();
// Define lighting texture buffers
texture_buffer_lut_lf_id = DefineUniformConst(image_buffer_id, 0, 3); 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_rg_id = DefineUniformConst(image_buffer_id, 0, 4);
texture_buffer_lut_rgba_id = DefineUniformConst(image_buffer_id, 0, 5); 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); tex1_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 1);
tex2_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 2); tex2_id = DefineUniformConst(TypeSampledImage(image2d_id), 1, 2);
tex_cube_id = DefineUniformConst(TypeSampledImage(image_cube_id), 1, 3);
// Define shadow textures // Define shadow textures
shadow_texture_px_id = DefineUniformConst(image_r32_id, 2, 0, true); shadow_texture_px_id = DefineUniformConst(image_r32_id, 2, 0, true);

View File

@ -252,7 +252,6 @@ private:
Id tex0_id{}; Id tex0_id{};
Id tex1_id{}; Id tex1_id{};
Id tex2_id{}; Id tex2_id{};
Id tex_cube_id{};
Id texture_buffer_lut_lf_id{}; Id texture_buffer_lut_lf_id{};
Id texture_buffer_lut_rg_id{}; Id texture_buffer_lut_rg_id{};
Id texture_buffer_lut_rgba_id{}; Id texture_buffer_lut_rgba_id{};