diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 94a168c01b..e59d27a2aa 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -189,7 +189,9 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS) "layout(std140, binding = " << GL_RASTERIZER_STATE_BIND_SLOT << ") uniform RasterizerHeap\n" "{\n" " uvec4 stipple_pattern[8];\n" - "};\n\n"; + "};\n\n" + + "#define texture_base_index 0\n\n"; } void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) diff --git a/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl b/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl index 0af25a0150..e06110f0a6 100644 --- a/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl @@ -366,19 +366,19 @@ vec4 _texture(in vec4 coord, float bias) switch (type) { case RSX_SAMPLE_TEXTURE_1D: - coord.x = _texcoord_xform(coord.x, texture_parameters[ur0]); + coord.x = _texcoord_xform(coord.x, texture_parameters[ur0 + texture_base_index]); vr0 = texture(SAMPLER1D(ur0), coord.x, bias); break; case RSX_SAMPLE_TEXTURE_2D: - coord.xy = _texcoord_xform(coord.xy, texture_parameters[ur0]); + coord.xy = _texcoord_xform(coord.xy, texture_parameters[ur0 + texture_base_index]); vr0 = texture(SAMPLER2D(ur0), coord.xy, bias); break; case RSX_SAMPLE_TEXTURE_CUBE: - coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0]); + coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0 + texture_base_index]); vr0 = texture(SAMPLERCUBE(ur0), coord.xyz, bias); break; case RSX_SAMPLE_TEXTURE_3D: - coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0]); + coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0 + texture_base_index]); vr0 = texture(SAMPLER3D(ur0), coord.xyz, bias); break; } @@ -405,19 +405,19 @@ vec4 _textureLod(in vec4 coord, float lod) switch (type) { case RSX_SAMPLE_TEXTURE_1D: - coord.x = _texcoord_xform(coord.x, texture_parameters[ur0]); + coord.x = _texcoord_xform(coord.x, texture_parameters[ur0 + texture_base_index]); vr0 = textureLod(SAMPLER1D(ur0), coord.x, lod); break; case RSX_SAMPLE_TEXTURE_2D: - coord.xy = _texcoord_xform(coord.xy, texture_parameters[ur0]); + coord.xy = _texcoord_xform(coord.xy, texture_parameters[ur0 + texture_base_index]); vr0 = textureLod(SAMPLER2D(ur0), coord.xy, lod); break; case RSX_SAMPLE_TEXTURE_CUBE: - coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0]); + coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0 + texture_base_index]); vr0 = textureLod(SAMPLERCUBE(ur0), coord.xyz, lod); break; case RSX_SAMPLE_TEXTURE_3D: - coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0]); + coord.xyz = _texcoord_xform(coord.xyz, texture_parameters[ur0 + texture_base_index]); vr0 = textureLod(SAMPLER3D(ur0), coord.xyz, lod); break; } diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureDepthConversion.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureDepthConversion.glsl index 01eb79803f..ef77ae179d 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureDepthConversion.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureDepthConversion.glsl @@ -1,8 +1,8 @@ R"( #define ZS_READ(index, coord) vec2(texture(TEX_NAME(index), coord).r, float(texture(TEX_NAME_STENCIL(index), coord).x)) -#define TEX1D_Z24X8_RGBA8(index, coord1) _process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE1(index, coord1)), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) -#define TEX2D_Z24X8_RGBA8(index, coord2) _process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE2(index, coord2)), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) -#define TEX3D_Z24X8_RGBA8(index, coord3) _process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE3(index, coord3)), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) +#define TEX1D_Z24X8_RGBA8(index, coord1) _process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE1(index, coord1)), texture_parameters[index + texture_base_index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) +#define TEX2D_Z24X8_RGBA8(index, coord2) _process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE2(index, coord2)), texture_parameters[index + texture_base_index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) +#define TEX3D_Z24X8_RGBA8(index, coord3) _process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE3(index, coord3)), texture_parameters[index + texture_base_index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) // NOTE: Memory layout is fetched as byteswapped BGRA [GBAR] (GOW collection, DS2, DeS) // The A component (Z) is useless (should contain stencil8 or just 1) diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureMSAAOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureMSAAOps.glsl index 8575508f54..37f2427ba0 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureMSAAOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureMSAAOps.glsl @@ -4,7 +4,7 @@ R"( #define TEX2D_MS(index, coord2) _process_texel(sampleTexture2DMS(TEX_NAME(index), coord2, index), TEX_FLAGS(index)) #define TEX2D_SHADOW_MS(index, coord3) vec4(comparison_passes(sampleTexture2DMS(TEX_NAME(index), coord3.xy, index).x, coord3.z, ZCOMPARE_FUNC(index))) #define TEX2D_SHADOWPROJ_MS(index, coord4) TEX2D_SHADOW_MS(index, (coord4.xyz / coord4.w)) -#define TEX2D_Z24X8_RGBA8_MS(index, coord2) _process_texel(convert_z24x8_to_rgba8(ZS_READ_MS(index, coord2), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) +#define TEX2D_Z24X8_RGBA8_MS(index, coord2) _process_texel(convert_z24x8_to_rgba8(ZS_READ_MS(index, coord2), texture_parameters[index + texture_base_index].remap, TEX_FLAGS(index)), TEX_FLAGS(index)) vec3 compute2x2DownsampleWeights(const in float coord, const in float uv_step, const in float actual_step) { diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl index 16e420d547..7ef54a244d 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl @@ -24,17 +24,17 @@ R"( uint _texture_flag_override = 0; #define _enable_texture_expand() _texture_flag_override = SIGN_EXPAND_MASK #define _disable_texture_expand() _texture_flag_override = 0 - #define TEX_FLAGS(index) (texture_parameters[index].flags | _texture_flag_override) + #define TEX_FLAGS(index) (texture_parameters[index + texture_base_index].flags | _texture_flag_override) #else - #define TEX_FLAGS(index) texture_parameters[index].flags + #define TEX_FLAGS(index) texture_parameters[index + texture_base_index].flags #endif #define TEX_NAME(index) tex##index #define TEX_NAME_STENCIL(index) tex##index##_stencil -#define COORD_SCALE1(index, coord1) _texcoord_xform(coord1, texture_parameters[index]) -#define COORD_SCALE2(index, coord2) _texcoord_xform(coord2, texture_parameters[index]) -#define COORD_SCALE3(index, coord3) _texcoord_xform(coord3, texture_parameters[index]) +#define COORD_SCALE1(index, coord1) _texcoord_xform(coord1, texture_parameters[index + texture_base_index]) +#define COORD_SCALE2(index, coord2) _texcoord_xform(coord2, texture_parameters[index + texture_base_index]) +#define COORD_SCALE3(index, coord3) _texcoord_xform(coord3, texture_parameters[index + texture_base_index]) #define COORD_PROJ1(index, coord2) COORD_SCALE1(index, coord2.x / coord2.y) #define COORD_PROJ2(index, coord3) COORD_SCALE2(index, coord3.xy / coord3.z) #define COORD_PROJ3(index, coord4) COORD_SCALE3(index, coord4.xyz / coord4.w) @@ -57,9 +57,9 @@ R"( #ifdef _ENABLE_SHADOW #ifdef _EMULATED_TEXSHADOW - #define SHADOW_COORD(index, coord3) _texcoord_xform_shadow(coord3, texture_parameters[index]) - #define SHADOW_COORD4(index, coord4) _texcoord_xform_shadow(coord4, texture_parameters[index]) - #define SHADOW_COORD_PROJ(index, coord4) _texcoord_xform_shadow(coord4.xyz / coord4.w, texture_parameters[index]) + #define SHADOW_COORD(index, coord3) _texcoord_xform_shadow(coord3, texture_parameters[index + texture_base_index]) + #define SHADOW_COORD4(index, coord4) _texcoord_xform_shadow(coord4, texture_parameters[index + texture_base_index]) + #define SHADOW_COORD_PROJ(index, coord4) _texcoord_xform_shadow(coord4.xyz / coord4.w, texture_parameters[index + texture_base_index]) #define TEX2D_SHADOW(index, coord3) texture(TEX_NAME(index), SHADOW_COORD(index, coord3)) #define TEX3D_SHADOW(index, coord4) texture(TEX_NAME(index), SHADOW_COORD4(index, coord4)) diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index 716b9c095d..f071d5ddfa 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -240,9 +240,9 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) " fragment_context_t fs_contexts[];\n" "};\n\n"; - OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.tex_param_location << ") uniform TextureParametersBuffer\n"; + OS << "layout(std430, set=1, binding=" << vk_prog->binding_table.tex_param_location << ") readonly buffer TextureParametersBuffer\n"; OS << "{\n"; - OS << " sampler_info texture_parameters[16];\n"; + OS << " sampler_info texture_parameters[];\n"; OS << "};\n\n"; OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.polygon_stipple_params_location << ") uniform RasterizerHeap\n"; @@ -271,10 +271,11 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) in.location = vk_prog->binding_table.tex_param_location; in.name = "TextureParametersBuffer"; - in.type = vk::glsl::input_type_uniform_buffer; + in.type = vk::glsl::input_type_storage_buffer; inputs.push_back(in); in.location = vk_prog->binding_table.polygon_stipple_params_location; + in.type = vk::glsl::input_type_uniform_buffer; in.name = "RasterizerHeap"; inputs.push_back(in); @@ -283,13 +284,14 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) "{\n" " layout(offset=12) uint fs_constants_offset;\n" " uint fs_context_offset;\n" + " uint fs_texture_base_index;\n" "};\n\n"; const vk::glsl::program_input push_constants { .domain = glsl::glsl_fragment_program, .type = vk::glsl::input_type_push_constant, - .bound_data = vk::glsl::push_constant_ref{.offset = 12, .size = 8 }, + .bound_data = vk::glsl::push_constant_ref{.offset = 12, .size = 12 }, .set = vk::glsl::binding_set_index_vertex, .location = umax, .name = "fs_push_constants_block" @@ -338,6 +340,8 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) "const float wpos_bias fs_contexts[fs_context_offset].wpos_bias;\n\n"; } + OS << "#define texture_base_index fs_texture_base_index\n\n"; + glsl::insert_glsl_legacy_function(OS, m_shader_props); } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index f1d105ff79..6657867e49 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -512,7 +512,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000, VK_TRUE); m_fragment_env_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment env buffer"); m_vertex_env_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex env buffer"); - m_fragment_texture_params_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment texture params buffer"); + m_fragment_texture_params_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment texture params buffer"); m_vertex_layout_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex layout buffer", 0x10000, VK_TRUE); m_fragment_constants_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment constants buffer"); m_transform_constants_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer"); @@ -554,7 +554,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) m_vertex_env_buffer_info = { m_vertex_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_env_buffer_info = { m_fragment_env_ring_info.heap->value, 0, VK_WHOLE_SIZE }; - m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, 0, 16 }; + m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, 0, 128 }; m_vertex_layout_stream_info = { m_vertex_layout_ring_info.heap->value, 0, VK_WHOLE_SIZE }; m_fragment_constants_buffer_info = { m_fragment_constants_ring_info.heap->value, 0, VK_WHOLE_SIZE }; @@ -2029,12 +2029,11 @@ void VKGSRender::load_program_env() if (update_fragment_texture_env) { - auto mem = m_fragment_texture_params_ring_info.static_alloc<256, 768>(); - auto buf = m_fragment_texture_params_ring_info.map(mem, 768); + m_texture_parameters_dynamic_offset = m_fragment_texture_params_ring_info.static_alloc<16, 768>(); + auto buf = m_fragment_texture_params_ring_info.map(m_texture_parameters_dynamic_offset, 768); current_fragment_program.texture_params.write_to(buf, current_fp_metadata.referenced_textures_mask); m_fragment_texture_params_ring_info.unmap(); - m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, mem, 768 }; } if (update_raster_env) @@ -2196,6 +2195,7 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_ { u32 fs_constants_offset; u32 fs_context_offset; + u32 fs_texture_base_index; }; struct rsx_prog_vertex_layout_entry_t @@ -2214,6 +2214,7 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_ const u32 vertex_layout_offset = static_cast(m_vertex_layout_dynamic_offset) / 144u; const u32 fs_constant_id_offset = static_cast(m_fragment_constants_dynamic_offset) / 16u; const u32 fs_context_offset = static_cast(m_fragment_env_dynamic_offset) / 32u; + const u32 fs_texture_base_index = static_cast(m_texture_parameters_dynamic_offset) / 48u; // Pack rsx_vs_prog_push_constants_block_t vs_push_constants; @@ -2224,6 +2225,7 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_ rsx_fs_prog_push_constants_block_t fs_push_constants; fs_push_constants.fs_constants_offset = fs_constant_id_offset; fs_push_constants.fs_context_offset = fs_context_offset; + fs_push_constants.fs_texture_base_index = fs_texture_base_index; vkCmdPushConstants( *m_current_command_buffer, diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index f0515325de..f26ef515b4 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -155,6 +155,7 @@ private: u64 m_vertex_layout_dynamic_offset = 0; u64 m_fragment_constants_dynamic_offset = 0; u64 m_fragment_env_dynamic_offset = 0; + u64 m_texture_parameters_dynamic_offset = 0; std::array frame_context_storage; //Temp frame context to use if the real frame queue is overburdened. Only used for storage