diff --git a/rpcs3/Emu/RSX/Core/RSXDriverState.h b/rpcs3/Emu/RSX/Core/RSXDriverState.h index 7c7ff3abbb..e915cd67e2 100644 --- a/rpcs3/Emu/RSX/Core/RSXDriverState.h +++ b/rpcs3/Emu/RSX/Core/RSXDriverState.h @@ -38,9 +38,11 @@ namespace rsx rtt_config_valid = (1 << 23), // Render target configuration is valid rtt_cache_state_dirty = (1 << 24), // Texture cache state is indeterminate + xform_instancing_state_dirty = (1 << 25), // Transform instancing state has changed + fragment_program_dirty = fragment_program_ucode_dirty | fragment_program_state_dirty, vertex_program_dirty = vertex_program_ucode_dirty | vertex_program_state_dirty, - invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty, + invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty | xform_instancing_state_dirty, invalidate_zclip_bits = vertex_state_dirty | zclip_config_state_dirty, memory_barrier_bits = framebuffer_reads_dirty, diff --git a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp index 1a4491df11..8d9aecfaee 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp @@ -393,12 +393,10 @@ namespace rsx return; } - // FIXME: This doesn't belong here - constexpr u32 instance_control_mask = RSX_SHADER_CONTROL_INSTANCED_CONSTANTS; - RSX(ctx)->current_vertex_program.ctrl &= ~instance_control_mask; - if (REGS(ctx)->current_draw_clause.is_trivial_instanced_draw) + // Notify the backend if the drawing style changes (instanced vs non-instanced) + if (REGS(ctx)->current_draw_clause.is_trivial_instanced_draw != RSX(ctx)->is_current_vertex_program_instanced()) { - RSX(ctx)->current_vertex_program.ctrl |= RSX_SHADER_CONTROL_INSTANCED_CONSTANTS; + RSX(ctx)->m_graphics_state |= rsx::pipeline_state::xform_instancing_state_dirty; } RSX(ctx)->end(); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 9a242a3028..ca10f7fdea 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -1940,13 +1940,6 @@ namespace rsx void thread::prefetch_vertex_program() { - // Test if instanced command is coming up - current_vertex_program.ctrl = 0; - if (rsx::method_registers.current_draw_clause.is_trivial_instanced_draw) - { - current_vertex_program.ctrl |= RSX_SHADER_CONTROL_INSTANCED_CONSTANTS; - } - if (!m_graphics_state.test(rsx::pipeline_state::vertex_program_ucode_dirty)) { return; @@ -1994,6 +1987,17 @@ namespace rsx void thread::get_current_vertex_program(const std::array, rsx::limits::vertex_textures_count>& sampler_descriptors) { + if (m_graphics_state.test(rsx::pipeline_state::xform_instancing_state_dirty)) + { + current_vertex_program.ctrl = 0; + if (rsx::method_registers.current_draw_clause.is_trivial_instanced_draw) + { + current_vertex_program.ctrl |= RSX_SHADER_CONTROL_INSTANCED_CONSTANTS; + } + + m_graphics_state.clear(rsx::pipeline_state::xform_instancing_state_dirty); + } + if (!m_graphics_state.test(rsx::pipeline_state::vertex_program_dirty)) { return; @@ -3002,7 +3006,7 @@ namespace rsx u32 thread::get_load() { - //Average load over around 30 frames + // Average load over around 30 frames if (!performance_counters.last_update_timestamp || performance_counters.sampled_frames > 30) { const auto timestamp = get_system_time(); diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 4724b43ecd..4bcd08c9f4 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -424,9 +424,17 @@ namespace rsx */ virtual void on_semaphore_acquire_wait() {} + /** + * Load an image from memory with optional scaling and rotation. + * Returns false to tell the HW decoder to perform the operation on the CPU as a fallback when the operation cannot be safely accelerated. + */ + virtual bool scaled_image_from_memory(const blit_src_info& /*src_info*/, const blit_dst_info& /*dst_info*/, bool /*interpolate*/) { return false; } + + + // Program public "get" handlers virtual std::pair get_programs() const { return std::make_pair("", ""); } - virtual bool scaled_image_from_memory(const blit_src_info& /*src_info*/, const blit_dst_info& /*dst_info*/, bool /*interpolate*/) { return false; } + bool is_current_vertex_program_instanced() const { return !!(current_vertex_program.ctrl & RSX_SHADER_CONTROL_INSTANCED_CONSTANTS); } public: void reset();