diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.h b/rpcs3/Emu/RSX/GL/GLVertexProgram.h index 2b769c469e..7a630d0cd3 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.h +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.h @@ -50,17 +50,14 @@ public: void Task(); }; -class GLVertexProgram +class GLVertexProgram : public rsx::VertexProgramBase { public: GLVertexProgram(); ~GLVertexProgram(); ParamArray parr; - u32 id; gl::glsl::shader shader; - std::vector constant_ids; - bool has_indexed_constants; void Decompile(const RSXVertexProgram& prog); diff --git a/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.h b/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.h index 2065e2ead7..b1147c7016 100644 --- a/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.h @@ -139,4 +139,4 @@ public: VertexProgramDecompiler(const RSXVertexProgram& prog); std::string Decompile(); -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/RSX/Program/program_util.cpp b/rpcs3/Emu/RSX/Program/program_util.cpp index 2c00369b15..339e58d721 100644 --- a/rpcs3/Emu/RSX/Program/program_util.cpp +++ b/rpcs3/Emu/RSX/Program/program_util.cpp @@ -109,4 +109,52 @@ namespace rsx return texture_dimensions == other.texture_dimensions && multisampled_textures == other.multisampled_textures; } + + int VertexProgramBase::TranslateConstantsRange(int first_index, int count) const + { + // The constant ids should be sorted, so just find the first one and check for continuity + int index = -1; + int next = first_index; + int last = first_index + count - 1; + + // Early rejection test + if (constant_ids.empty() || first_index > constant_ids.back() || last < first_index) + { + return -1; + } + + for (size_t i = 0; i < constant_ids.size(); ++i) + { + if (constant_ids[i] > first_index && index < 0) + { + // No chance of a match + return -1; + } + + if (constant_ids[i] == next) + { + // Index matched + if (index < 0) + { + index = static_cast(i); + } + + if (last == next++) + { + return index; + } + + continue; + } + + if (index >= 0) + { + // Previously matched but no more + return -1; + } + } + + // OOB or partial match + return -1; + } } diff --git a/rpcs3/Emu/RSX/Program/program_util.h b/rpcs3/Emu/RSX/Program/program_util.h index 7974290180..32ad3b1c48 100644 --- a/rpcs3/Emu/RSX/Program/program_util.h +++ b/rpcs3/Emu/RSX/Program/program_util.h @@ -57,4 +57,16 @@ namespace rsx void set_dimension(texture_dimension_extended type, u32 index); bool operator == (const vertex_program_texture_state& other) const; }; + + struct VertexProgramBase + { + u32 id; + std::vector constant_ids; + bool has_indexed_constants; + + // Translates an incoming range of constants against our mapping. + // If there is no linear mapping available, return -1, otherwise returns the translated index of the first slot + // TODO: Move this somewhere else during refactor + int TranslateConstantsRange(int first_index, int count) const; + }; } diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.h b/rpcs3/Emu/RSX/VK/VKVertexProgram.h index eeef80421d..940272d069 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.h +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.h @@ -52,7 +52,7 @@ public: const std::vector& get_inputs() { return inputs; } }; -class VKVertexProgram +class VKVertexProgram : public rsx::VertexProgramBase { public: VKVertexProgram(); @@ -60,11 +60,8 @@ public: ParamArray parr; VkShaderModule handle = nullptr; - u32 id; vk::glsl::shader shader; std::vector uniforms; - std::vector constant_ids; - bool has_indexed_constants; void Decompile(const RSXVertexProgram& prog); void Compile();