2012-11-15 00:39:56 +01:00
|
|
|
#pragma once
|
2015-12-02 10:23:25 +01:00
|
|
|
|
2016-02-01 22:50:02 +01:00
|
|
|
#include <stack>
|
|
|
|
|
#include <deque>
|
|
|
|
|
#include <set>
|
2016-05-13 16:01:48 +02:00
|
|
|
#include <mutex>
|
2017-06-25 22:14:56 +02:00
|
|
|
#include <atomic>
|
2012-11-15 00:39:56 +01:00
|
|
|
#include "GCM.h"
|
2016-06-16 19:19:45 +02:00
|
|
|
#include "rsx_cache.h"
|
2014-02-21 14:21:08 +01:00
|
|
|
#include "RSXTexture.h"
|
2013-11-09 22:29:49 +01:00
|
|
|
#include "RSXVertexProgram.h"
|
|
|
|
|
#include "RSXFragmentProgram.h"
|
2016-07-17 19:16:21 +02:00
|
|
|
#include "rsx_methods.h"
|
|
|
|
|
#include "rsx_trace.h"
|
2016-07-31 23:01:31 +02:00
|
|
|
#include <Utilities/GSL.h>
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-08-25 16:56:13 +02:00
|
|
|
#include "Utilities/Thread.h"
|
2014-12-21 21:42:15 +01:00
|
|
|
#include "Utilities/Timer.h"
|
2016-04-27 00:27:24 +02:00
|
|
|
#include "Utilities/geometry.h"
|
2016-07-18 23:39:24 +02:00
|
|
|
#include "rsx_trace.h"
|
2017-01-28 13:32:45 +01:00
|
|
|
#include "restore_new.h"
|
2016-08-21 19:17:09 +02:00
|
|
|
#include "Utilities/variant.hpp"
|
2017-01-28 13:32:45 +01:00
|
|
|
#include "define_new_memleakdetect.h"
|
2015-11-06 00:56:27 +01:00
|
|
|
|
2017-07-26 04:33:32 +02:00
|
|
|
#include "Emu/Cell/lv2/sys_rsx.h"
|
|
|
|
|
|
2015-11-06 00:56:27 +01:00
|
|
|
extern u64 get_system_time();
|
|
|
|
|
|
|
|
|
|
extern bool user_asked_for_frame_capture;
|
2016-07-17 19:16:21 +02:00
|
|
|
extern rsx::frame_capture_data frame_debug;
|
2015-11-06 00:56:27 +01:00
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
namespace rsx
|
2013-11-09 22:29:49 +01:00
|
|
|
{
|
2015-10-04 00:45:26 +02:00
|
|
|
namespace limits
|
2013-11-09 22:29:49 +01:00
|
|
|
{
|
2015-10-04 00:45:26 +02:00
|
|
|
enum
|
|
|
|
|
{
|
2016-07-19 16:50:40 +02:00
|
|
|
fragment_textures_count = 16,
|
2015-10-04 00:45:26 +02:00
|
|
|
vertex_textures_count = 4,
|
|
|
|
|
vertex_count = 16,
|
|
|
|
|
fragment_count = 32,
|
|
|
|
|
tiles_count = 15,
|
|
|
|
|
zculls_count = 8,
|
|
|
|
|
color_buffers_count = 4
|
|
|
|
|
};
|
2013-11-09 22:29:49 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-20 14:23:25 +01:00
|
|
|
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size);
|
2015-12-01 14:55:15 +01:00
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
u32 get_address(u32 offset, u32 location);
|
2014-02-02 21:47:17 +01:00
|
|
|
|
2016-01-05 21:55:43 +01:00
|
|
|
struct tiled_region
|
2016-01-05 17:26:44 +01:00
|
|
|
{
|
|
|
|
|
u32 address;
|
|
|
|
|
u32 base;
|
|
|
|
|
GcmTileInfo *tile;
|
|
|
|
|
u8 *ptr;
|
|
|
|
|
|
|
|
|
|
void write(const void *src, u32 width, u32 height, u32 pitch);
|
|
|
|
|
void read(void *dst, u32 width, u32 height, u32 pitch);
|
|
|
|
|
};
|
|
|
|
|
|
2016-08-21 19:17:09 +02:00
|
|
|
struct vertex_array_buffer
|
|
|
|
|
{
|
|
|
|
|
rsx::vertex_base_type type;
|
|
|
|
|
u8 attribute_size;
|
|
|
|
|
u8 stride;
|
|
|
|
|
gsl::span<const gsl::byte> data;
|
|
|
|
|
u8 index;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct vertex_array_register
|
|
|
|
|
{
|
|
|
|
|
rsx::vertex_base_type type;
|
|
|
|
|
u8 attribute_size;
|
|
|
|
|
std::array<u32, 4> data;
|
|
|
|
|
u8 index;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct empty_vertex_array
|
|
|
|
|
{
|
|
|
|
|
u8 index;
|
|
|
|
|
};
|
|
|
|
|
|
2016-08-28 17:00:02 +02:00
|
|
|
struct draw_array_command
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* First and count of index subranges.
|
|
|
|
|
*/
|
|
|
|
|
std::vector<std::pair<u32, u32>> indexes_range;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct draw_indexed_array_command
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* First and count of subranges to fetch in index buffer.
|
|
|
|
|
*/
|
|
|
|
|
std::vector<std::pair<u32, u32>> ranges_to_fetch_in_index_buffer;
|
|
|
|
|
|
|
|
|
|
gsl::span<const gsl::byte> raw_index_buffer;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct draw_inlined_array
|
|
|
|
|
{
|
|
|
|
|
std::vector<u32> inline_vertex_array;
|
|
|
|
|
};
|
|
|
|
|
|
2017-07-31 13:38:28 +02:00
|
|
|
struct interleaved_range_info
|
|
|
|
|
{
|
|
|
|
|
bool interleaved = false;
|
|
|
|
|
bool all_modulus = false;
|
|
|
|
|
u32 base_offset = 0;
|
|
|
|
|
u32 real_offset_address = 0;
|
|
|
|
|
u8 memory_location = 0;
|
|
|
|
|
u8 attribute_stride = 0;
|
|
|
|
|
u16 min_divisor = 0;
|
|
|
|
|
|
|
|
|
|
std::vector<u8> locations;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum attribute_buffer_placement : u8
|
|
|
|
|
{
|
|
|
|
|
none = 0,
|
|
|
|
|
persistent = 1,
|
|
|
|
|
transient = 2
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct vertex_input_layout
|
|
|
|
|
{
|
|
|
|
|
std::vector<interleaved_range_info> interleaved_blocks; //Interleaved blocks to be uploaded as-is
|
|
|
|
|
std::vector<std::pair<u8, u32>> volatile_blocks; //Volatile data blocks (immediate draw vertex data for example)
|
|
|
|
|
std::vector<u8> referenced_registers; //Volatile register data
|
|
|
|
|
|
|
|
|
|
std::array<attribute_buffer_placement, 16> attribute_placement;
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-01 22:50:02 +01:00
|
|
|
class thread : public named_thread
|
2015-10-04 00:45:26 +02:00
|
|
|
{
|
2016-07-20 14:16:19 +02:00
|
|
|
std::shared_ptr<thread_ctrl> m_vblank_thread;
|
|
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
protected:
|
|
|
|
|
std::stack<u32> m_call_stack;
|
2017-03-25 22:59:57 +01:00
|
|
|
std::array<push_buffer_vertex_info, 16> vertex_push_buffers;
|
2017-03-28 12:41:45 +02:00
|
|
|
std::vector<u32> element_push_buffer;
|
2015-10-04 00:45:26 +02:00
|
|
|
|
|
|
|
|
public:
|
2017-07-26 04:33:32 +02:00
|
|
|
RsxDmaControl* ctrl = nullptr;
|
2015-10-04 00:45:26 +02:00
|
|
|
|
|
|
|
|
Timer timer_sync;
|
|
|
|
|
|
|
|
|
|
GcmTileInfo tiles[limits::tiles_count];
|
|
|
|
|
GcmZcullInfo zculls[limits::zculls_count];
|
|
|
|
|
|
2015-10-31 18:19:45 +01:00
|
|
|
// Constant stored for whole frame
|
|
|
|
|
std::unordered_map<u32, color4f> local_transform_constants;
|
|
|
|
|
|
2015-11-06 00:56:27 +01:00
|
|
|
bool capture_current_frame = false;
|
2015-11-09 23:57:35 +01:00
|
|
|
void capture_frame(const std::string &name);
|
2016-01-20 13:46:58 +01:00
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
public:
|
2016-07-27 23:43:22 +02:00
|
|
|
std::shared_ptr<class ppu_thread> intr_thread;
|
|
|
|
|
|
2017-07-26 04:57:43 +02:00
|
|
|
// I hate this flag, but until hle is closer to lle, its needed
|
|
|
|
|
bool isHLE{ false };
|
|
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
u32 ioAddress, ioSize;
|
2017-05-15 13:30:14 +02:00
|
|
|
u32 flip_status;
|
2015-10-04 00:45:26 +02:00
|
|
|
int debug_level;
|
|
|
|
|
|
2017-07-26 04:33:32 +02:00
|
|
|
atomic_t<bool> requested_vsync{false};
|
2017-07-26 04:57:43 +02:00
|
|
|
atomic_t<bool> enable_second_vhandler{false};
|
2017-07-26 04:33:32 +02:00
|
|
|
|
|
|
|
|
RsxDisplayInfo display_buffers[8];
|
|
|
|
|
u32 display_buffers_count{0};
|
|
|
|
|
u32 current_display_buffer{0};
|
2015-10-04 00:45:26 +02:00
|
|
|
u32 ctxt_addr;
|
|
|
|
|
u32 label_addr;
|
|
|
|
|
|
|
|
|
|
u32 local_mem_addr, main_mem_addr;
|
|
|
|
|
|
2016-01-19 18:23:09 +01:00
|
|
|
bool m_rtts_dirty;
|
2016-02-21 18:56:56 +01:00
|
|
|
bool m_transform_constants_dirty;
|
2016-02-04 23:25:04 +01:00
|
|
|
bool m_textures_dirty[16];
|
2017-06-30 00:20:23 +02:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
s32 m_skip_frame_ctr = 0;
|
|
|
|
|
bool skip_frame = false;
|
2016-01-19 18:23:09 +01:00
|
|
|
protected:
|
|
|
|
|
std::array<u32, 4> get_color_surface_addresses() const;
|
|
|
|
|
u32 get_zeta_surface_address() const;
|
2017-07-31 13:38:28 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Analyze vertex inputs and group all interleaved blocks
|
|
|
|
|
*/
|
|
|
|
|
vertex_input_layout analyse_inputs_interleaved() const;
|
|
|
|
|
|
|
|
|
|
RSXVertexProgram current_vertex_program = {};
|
|
|
|
|
RSXFragmentProgram current_fragment_program = {};
|
|
|
|
|
|
|
|
|
|
void get_current_vertex_program();
|
2017-02-10 10:08:46 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets current fragment program and associated fragment state
|
|
|
|
|
* get_surface_info is a helper takes 2 parameters: rsx_texture_address and surface_is_depth
|
|
|
|
|
* returns whether surface is a render target and surface pitch in native format
|
|
|
|
|
*/
|
2017-07-31 13:38:28 +02:00
|
|
|
void get_current_fragment_program(std::function<std::tuple<bool, u16>(u32, fragment_texture&, bool)> get_surface_info);
|
2015-10-04 00:45:26 +02:00
|
|
|
public:
|
|
|
|
|
double fps_limit = 59.94;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
u64 last_flip_time;
|
2015-09-26 22:46:04 +02:00
|
|
|
vm::ps3::ptr<void(u32)> flip_handler = vm::null;
|
|
|
|
|
vm::ps3::ptr<void(u32)> user_handler = vm::null;
|
|
|
|
|
vm::ps3::ptr<void(u32)> vblank_handler = vm::null;
|
2015-10-04 00:45:26 +02:00
|
|
|
u64 vblank_count;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
std::set<u32> m_used_gcm_commands;
|
2017-03-21 12:58:25 +01:00
|
|
|
bool invalid_command_interrupt_raised = false;
|
2017-03-25 22:59:57 +01:00
|
|
|
bool in_begin_end = false;
|
2015-10-04 00:45:26 +02:00
|
|
|
|
2017-07-27 18:04:55 +02:00
|
|
|
bool conditional_render_test_failed = false;
|
|
|
|
|
bool conditional_render_enabled = false;
|
|
|
|
|
bool zcull_stats_enabled = false;
|
|
|
|
|
bool zcull_rendering_enabled = false;
|
|
|
|
|
bool zcull_pixel_cnt_enabled = false;
|
|
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
protected:
|
2016-01-20 13:46:58 +01:00
|
|
|
thread();
|
|
|
|
|
virtual ~thread();
|
2015-10-04 00:45:26 +02:00
|
|
|
|
2015-11-26 09:06:29 +01:00
|
|
|
virtual void on_task() override;
|
2016-07-20 14:16:19 +02:00
|
|
|
virtual void on_exit() override;
|
2017-02-16 19:29:56 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Execute a backend local task queue
|
|
|
|
|
*/
|
|
|
|
|
virtual void do_local_task() {}
|
2015-11-26 09:06:29 +01:00
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
public:
|
2015-11-26 09:06:29 +01:00
|
|
|
virtual std::string get_name() const override;
|
|
|
|
|
|
2016-07-24 01:56:03 +02:00
|
|
|
virtual void on_init(const std::shared_ptr<void>&) override {} // disable start() (TODO)
|
2016-02-01 22:50:02 +01:00
|
|
|
virtual void on_stop() override {} // disable join()
|
|
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
virtual void begin();
|
|
|
|
|
virtual void end();
|
|
|
|
|
|
2016-02-01 22:50:02 +01:00
|
|
|
virtual void on_init_rsx() = 0;
|
2015-11-26 09:06:29 +01:00
|
|
|
virtual void on_init_thread() = 0;
|
2017-06-18 16:53:02 +02:00
|
|
|
virtual bool do_method(u32 /*cmd*/, u32 /*value*/) { return false; }
|
2015-10-04 00:45:26 +02:00
|
|
|
virtual void flip(int buffer) = 0;
|
|
|
|
|
virtual u64 timestamp() const;
|
2017-06-18 16:53:02 +02:00
|
|
|
virtual bool on_access_violation(u32 /*address*/, bool /*is_writing*/) { return false; }
|
2017-08-07 23:54:40 +02:00
|
|
|
virtual void on_notify_memory_unmapped(u32 /*address_base*/, u32 /*size*/) {}
|
2015-10-04 00:45:26 +02:00
|
|
|
|
2017-07-27 18:04:55 +02:00
|
|
|
//zcull
|
|
|
|
|
virtual void notify_zcull_info_changed() {}
|
|
|
|
|
virtual void clear_zcull_stats(u32 type) {}
|
|
|
|
|
virtual u32 get_zcull_stats(u32 type) { return UINT32_MAX; }
|
|
|
|
|
|
2016-07-31 23:01:31 +02:00
|
|
|
gsl::span<const gsl::byte> get_raw_index_array(const std::vector<std::pair<u32, u32> >& draw_indexed_clause) const;
|
2016-08-21 19:17:09 +02:00
|
|
|
gsl::span<const gsl::byte> get_raw_vertex_buffer(const rsx::data_array_format_info&, u32 base_offset, const std::vector<std::pair<u32, u32>>& vertex_ranges) const;
|
|
|
|
|
|
2017-03-25 22:59:57 +01:00
|
|
|
std::vector<std::variant<vertex_array_buffer, vertex_array_register, empty_vertex_array>>
|
2017-07-22 00:54:28 +02:00
|
|
|
get_vertex_buffers(const rsx::rsx_state& state, const std::vector<std::pair<u32, u32>>& vertex_ranges, const u64 consumed_attrib_mask) const;
|
2017-03-25 22:59:57 +01:00
|
|
|
|
2016-08-28 17:00:02 +02:00
|
|
|
std::variant<draw_array_command, draw_indexed_array_command, draw_inlined_array>
|
|
|
|
|
get_draw_command(const rsx::rsx_state& state) const;
|
2016-07-31 23:01:31 +02:00
|
|
|
|
2017-07-31 13:38:28 +02:00
|
|
|
/**
|
2017-03-25 22:59:57 +01:00
|
|
|
* Immediate mode rendering requires a temp push buffer to hold attrib values
|
|
|
|
|
* Appends a value to the push buffer (currently only supports 32-wide types)
|
|
|
|
|
*/
|
2017-03-26 11:01:50 +02:00
|
|
|
void append_to_push_buffer(u32 attribute, u32 size, u32 subreg_index, vertex_base_type type, u32 value);
|
2017-03-28 12:41:45 +02:00
|
|
|
u32 get_push_buffer_vertex_count() const;
|
|
|
|
|
|
|
|
|
|
void append_array_element(u32 index);
|
|
|
|
|
u32 get_push_buffer_index_count() const;
|
2017-03-25 22:59:57 +01:00
|
|
|
|
2017-06-25 22:14:56 +02:00
|
|
|
protected:
|
|
|
|
|
|
2017-07-31 13:38:28 +02:00
|
|
|
/**
|
|
|
|
|
* Computes VRAM requirements needed to upload raw vertex streams
|
|
|
|
|
* result.first contains persistent memory requirements
|
|
|
|
|
* result.second contains volatile memory requirements
|
|
|
|
|
*/
|
|
|
|
|
std::pair<u32, u32> calculate_memory_requirements(vertex_input_layout& layout, const u32 vertex_count);
|
2017-06-25 22:14:56 +02:00
|
|
|
|
2017-07-31 13:38:28 +02:00
|
|
|
/**
|
|
|
|
|
* Generates vertex input descriptors as an array of 16x4 s32s
|
|
|
|
|
*/
|
|
|
|
|
void fill_vertex_layout_state(vertex_input_layout& layout, const u32 vertex_count, s32* buffer);
|
2017-06-25 22:14:56 +02:00
|
|
|
|
2017-07-31 13:38:28 +02:00
|
|
|
/**
|
|
|
|
|
* Uploads vertex data described in the layout descriptor
|
|
|
|
|
* Copies from local memory to the write-only output buffers provided in a sequential manner
|
|
|
|
|
*/
|
|
|
|
|
void write_vertex_data_to_memory(vertex_input_layout &layout, const u32 first_vertex, const u32 vertex_count, void *persistent_data, void *volatile_data);
|
2017-06-25 22:14:56 +02:00
|
|
|
|
2016-01-20 15:12:49 +01:00
|
|
|
private:
|
|
|
|
|
std::mutex m_mtx_task;
|
|
|
|
|
|
|
|
|
|
struct internal_task_entry
|
|
|
|
|
{
|
|
|
|
|
std::function<bool()> callback;
|
2016-04-25 12:49:12 +02:00
|
|
|
//std::promise<void> promise;
|
2016-01-20 15:12:49 +01:00
|
|
|
|
|
|
|
|
internal_task_entry(std::function<bool()> callback) : callback(callback)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::deque<internal_task_entry> m_internal_tasks;
|
|
|
|
|
void do_internal_task();
|
|
|
|
|
|
|
|
|
|
public:
|
2016-04-25 12:49:12 +02:00
|
|
|
//std::future<void> add_internal_task(std::function<bool()> callback);
|
|
|
|
|
//void invoke(std::function<bool()> callback);
|
2016-01-20 15:12:49 +01:00
|
|
|
|
2015-10-31 18:08:49 +01:00
|
|
|
/**
|
|
|
|
|
* Fill buffer with 4x4 scale offset matrix.
|
|
|
|
|
* Vertex shader's position is to be multiplied by this matrix.
|
2017-06-14 17:47:01 +02:00
|
|
|
* if flip_y is set, the matrix is modified to use d3d convention.
|
2015-10-31 18:08:49 +01:00
|
|
|
*/
|
2017-06-14 17:47:01 +02:00
|
|
|
void fill_scale_offset_data(void *buffer, bool flip_y) const;
|
2017-04-25 12:32:39 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fill buffer with user clip information
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void fill_user_clip_data(void *buffer) const;
|
2015-10-31 18:08:49 +01:00
|
|
|
|
2015-10-31 18:19:45 +01:00
|
|
|
/**
|
|
|
|
|
* Fill buffer with vertex program constants.
|
|
|
|
|
* Buffer must be at least 512 float4 wide.
|
|
|
|
|
*/
|
2015-12-17 18:31:27 +01:00
|
|
|
void fill_vertex_program_constants_data(void *buffer);
|
2015-10-31 18:19:45 +01:00
|
|
|
|
2017-02-10 10:08:46 +01:00
|
|
|
/**
|
|
|
|
|
* Fill buffer with fragment rasterization state.
|
|
|
|
|
* Fills current fog values, alpha test parameters and texture scaling parameters
|
|
|
|
|
*/
|
|
|
|
|
void fill_fragment_state_buffer(void *buffer, const RSXFragmentProgram &fragment_program);
|
|
|
|
|
|
2015-12-31 19:15:44 +01:00
|
|
|
/**
|
|
|
|
|
* Write inlined array data to buffer.
|
|
|
|
|
* The storage of inlined data looks different from memory stored arrays.
|
|
|
|
|
* There is no swapping required except for 4 u8 (according to Bleach Soul Resurection)
|
|
|
|
|
*/
|
|
|
|
|
void write_inline_array_to_buffer(void *dst_buffer);
|
|
|
|
|
|
2015-11-06 00:56:27 +01:00
|
|
|
/**
|
|
|
|
|
* Copy rtt values to buffer.
|
|
|
|
|
* TODO: It's more efficient to combine multiple call of this function into one.
|
|
|
|
|
*/
|
2016-01-16 20:07:27 +01:00
|
|
|
virtual std::array<std::vector<gsl::byte>, 4> copy_render_targets_to_memory() {
|
|
|
|
|
return std::array<std::vector<gsl::byte>, 4>();
|
|
|
|
|
};
|
2015-11-06 00:56:27 +01:00
|
|
|
|
|
|
|
|
/**
|
2016-01-16 20:07:27 +01:00
|
|
|
* Copy depth and stencil content to buffers.
|
2015-11-06 00:56:27 +01:00
|
|
|
* TODO: It's more efficient to combine multiple call of this function into one.
|
|
|
|
|
*/
|
2016-01-16 20:07:27 +01:00
|
|
|
virtual std::array<std::vector<gsl::byte>, 2> copy_depth_stencil_buffer_to_memory() {
|
|
|
|
|
return std::array<std::vector<gsl::byte>, 2>();
|
|
|
|
|
};
|
2015-11-10 18:59:15 +01:00
|
|
|
|
|
|
|
|
virtual std::pair<std::string, std::string> get_programs() const { return std::make_pair("", ""); };
|
2016-01-20 13:46:58 +01:00
|
|
|
|
2017-06-18 16:53:02 +02:00
|
|
|
virtual bool scaled_image_from_memory(blit_src_info& /*src_info*/, blit_dst_info& /*dst_info*/, bool /*interpolate*/){ return false; }
|
2017-03-15 13:32:36 +01:00
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
public:
|
|
|
|
|
void reset();
|
2017-07-26 04:33:32 +02:00
|
|
|
void init(u32 ioAddress, u32 ioSize, u32 ctrlAddress, u32 localAddress);
|
2015-10-04 00:45:26 +02:00
|
|
|
|
2016-01-05 21:55:43 +01:00
|
|
|
tiled_region get_tiled_address(u32 offset, u32 location);
|
2016-01-05 17:26:44 +01:00
|
|
|
GcmTileInfo *find_tile(u32 offset, u32 location);
|
|
|
|
|
|
2015-10-04 00:45:26 +02:00
|
|
|
u32 ReadIO32(u32 addr);
|
|
|
|
|
void WriteIO32(u32 addr, u32 value);
|
|
|
|
|
};
|
|
|
|
|
}
|