From 48919330d7a57cb97d1283c7365c0f23d7c20068 Mon Sep 17 00:00:00 2001 From: DHrpcs3 Date: Tue, 5 Jan 2016 23:29:49 +0200 Subject: [PATCH] rsx methods moved from rsx thread --- rpcs3/Emu/RSX/Common/BufferUtils.cpp | 1 + rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 1 + rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 1 + rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 1 + rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 1 + rpcs3/Emu/RSX/GL/GLGSRender.cpp | 1 + rpcs3/Emu/RSX/RSXTexture.cpp | 1 + rpcs3/Emu/RSX/RSXThread.cpp | 831 +----------------- rpcs3/Emu/RSX/RSXThread.h | 63 -- rpcs3/emucore.vcxproj | 2 + rpcs3/emucore.vcxproj.filters | 12 +- 11 files changed, 19 insertions(+), 896 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index af3b0a9684..591da7b89b 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "BufferUtils.h" +#include "../rsx_methods.h" #define MIN2(x, y) ((x) < (y)) ? (x) : (y) #define MAX2(x, y) ((x) > (y)) ? (x) : (y) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 28bda5f5a5..fc9c3b23a7 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -6,6 +6,7 @@ #include "d3dx12.h" #include "../Common/BufferUtils.h" #include "D3D12Formats.h" +#include "../rsx_methods.h" namespace { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index dd8629fb7f..f6d50187d1 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -10,6 +10,7 @@ #include #include "Emu/state.h" #include "D3D12Formats.h" +#include "../rsx_methods.h" PFN_D3D12_CREATE_DEVICE wrapD3D12CreateDevice; PFN_D3D12_GET_DEBUG_INTERFACE wrapD3D12GetDebugInterface; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 89392c0b96..477b05acf5 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -5,6 +5,7 @@ #include "D3D12GSRender.h" #include "Emu/state.h" #include "D3D12Formats.h" +#include "../rsx_methods.h" #define TO_STRING(x) #x diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index 95f50089bd..c940631c59 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -7,6 +7,7 @@ #include "Emu/System.h" #include "Emu/state.h" #include "Emu/RSX/GSRender.h" +#include "../rsx_methods.h" #include "D3D12.h" #include "D3D12GSRender.h" diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 7dab5f83e3..95f5ac3348 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -4,6 +4,7 @@ #include "Emu/System.h" #include "Emu/state.h" #include "GLGSRender.h" +#include "../rsx_methods.h" #define DUMP_VERTEX_DATA 0 diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 017b4e9146..a6eafa09b6 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "RSXThread.h" #include "RSXTexture.h" +#include "rsx_methods.h" namespace rsx { diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index d7846797e3..fd5e3f8554 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -10,7 +10,7 @@ #include "Emu/SysCalls/lv2/sys_time.h" #include "Common/BufferUtils.h" -#include "rsx_utils.h" +#include "rsx_methods.h" #define CMD_DEBUG 0 @@ -19,835 +19,6 @@ frame_capture_data frame_debug; namespace rsx { - using rsx_method_t = void(*)(thread*, u32); - - u32 method_registers[0x10000 >> 2]; - rsx_method_t methods[0x10000 >> 2]{}; - - template struct vertex_data_type_from_element_type; - template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_F }; }; - template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_SF }; }; - template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_UB }; }; - template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_S1 }; }; - - namespace nv406e - { - force_inline void set_reference(thread* rsx, u32 arg) - { - rsx->ctrl->ref.exchange(arg); - } - - force_inline void semaphore_acquire(thread* rsx, u32 arg) - { - //TODO: dma - while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) - { - if (Emu.IsStopped()) - break; - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - } - - force_inline void semaphore_release(thread* rsx, u32 arg) - { - //TODO: dma - vm::write32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET], arg); - } - } - - namespace nv4097 - { - force_inline void texture_read_semaphore_release(thread* rsx, u32 arg) - { - //TODO: dma - vm::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], arg); - } - - force_inline void back_end_write_semaphore_release(thread* rsx, u32 arg) - { - //TODO: dma - vm::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], - (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff)); - } - - //fire only when all data passed to rsx cmd buffer - template - force_inline void set_vertex_data_impl(thread* rsx, u32 arg) - { - static const size_t element_size = (count * sizeof(type)); - static const size_t element_size_in_words = element_size / sizeof(u32); - - auto& info = rsx->register_vertex_info[index]; - - info.type = vertex_data_type_from_element_type::type; - info.size = count; - info.frequency = 0; - info.stride = 0; - - auto& entry = rsx->register_vertex_data[index]; - - //find begin of data - size_t begin = id + index * element_size_in_words; - - size_t position = 0;//entry.size(); - entry.resize(position + element_size); - - memcpy(entry.data() + position, method_registers + begin, element_size); - } - - template - struct set_vertex_data4ub_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data1f_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data2f_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data3f_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data4f_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data2s_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data4s_m - { - force_inline static void impl(thread* rsx, u32 arg) - { - set_vertex_data_impl(rsx, arg); - } - }; - - template - struct set_vertex_data_array_format - { - force_inline static void impl(thread* rsx, u32 arg) - { - auto& info = rsx->vertex_arrays_info[index]; - info.unpack_array(arg); - } - }; - - force_inline void draw_arrays(thread* rsx, u32 arg) - { - rsx->draw_command = thread::Draw_command::draw_command_array; - u32 first = arg & 0xffffff; - u32 count = (arg >> 24) + 1; - - rsx->load_vertex_data(first, count); - } - - force_inline void draw_index_array(thread* rsx, u32 arg) - { - rsx->draw_command = thread::Draw_command::draw_command_indexed; - u32 first = arg & 0xffffff; - u32 count = (arg >> 24) + 1; - - rsx->load_vertex_data(first, count); - rsx->load_vertex_index_data(first, count); - } - - force_inline void draw_inline_array(thread* rsx, u32 arg) - { - rsx->draw_command = thread::Draw_command::draw_command_inlined_array; - rsx->draw_inline_vertex_array = true; - rsx->inline_vertex_array.push_back(arg); - } - - template - struct set_transform_constant - { - force_inline static void impl(thread* rsxthr, u32 arg) - { - u32 load = method_registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; - - static const size_t count = 4; - static const size_t size = count * sizeof(f32); - - size_t reg = index / 4; - size_t subreg = index % 4; - - memcpy(rsxthr->transform_constants[load + reg].rgba + subreg, method_registers + NV4097_SET_TRANSFORM_CONSTANT + reg * count + subreg, sizeof(f32)); - } - }; - - template - struct set_transform_program - { - force_inline static void impl(thread* rsx, u32 arg) - { - u32& load = method_registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD]; - - static const size_t count = 4; - static const size_t size = count * sizeof(u32); - - memcpy(rsx->transform_program + load++ * count, method_registers + NV4097_SET_TRANSFORM_PROGRAM + index * count, size); - } - }; - - force_inline void set_begin_end(thread* rsx, u32 arg) - { - if (arg) - { - rsx->draw_inline_vertex_array = false; - rsx->inline_vertex_array.clear(); - rsx->begin(); - return; - } - - if (!rsx->vertex_draw_count) - { - bool has_array = false; - - for (int i = 0; i < rsx::limits::vertex_count; ++i) - { - if (rsx->vertex_arrays_info[i].size > 0) - { - has_array = true; - break; - } - } - - if (!has_array) - { - u32 min_count = ~0; - - for (int i = 0; i < rsx::limits::vertex_count; ++i) - { - if (!rsx->register_vertex_info[i].size) - continue; - - u32 count = u32(rsx->register_vertex_data[i].size()) / - rsx::get_vertex_type_size(rsx->register_vertex_info[i].type) * rsx->register_vertex_info[i].size; - - if (count < min_count) - min_count = count; - } - - if (min_count && min_count < ~0) - { - rsx->vertex_draw_count = min_count; - } - } - } - - rsx->end(); - rsx->vertex_draw_count = 0; - } - - force_inline void get_report(thread* rsx, u32 arg) - { - u8 type = arg >> 24; - u32 offset = arg & 0xffffff; - - //TODO: use DMA - vm::ptr result = { rsx->local_mem_addr + offset, vm::addr }; - - result->timer = rsx->timestamp(); - - switch (type) - { - case CELL_GCM_ZPASS_PIXEL_CNT: - case CELL_GCM_ZCULL_STATS: - case CELL_GCM_ZCULL_STATS1: - case CELL_GCM_ZCULL_STATS2: - case CELL_GCM_ZCULL_STATS3: - result->value = 0; - LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); - break; - - default: - result->value = 0; - LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); - break; - } - - //result->padding = 0; - } - - force_inline void clear_report_value(thread* rsx, u32 arg) - { - switch (arg) - { - case CELL_GCM_ZPASS_PIXEL_CNT: - LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZPASS_PIXEL_CNT"); - break; - case CELL_GCM_ZCULL_STATS: - LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZCULL_STATS"); - break; - default: - LOG_ERROR(RSX, "NV4097_CLEAR_REPORT_VALUE: Bad type: %d", arg); - break; - } - } - } - - namespace nv308a - { - template - struct color - { - force_inline static void impl(u32 arg) - { - u32 point = method_registers[NV308A_POINT]; - u16 x = point; - u16 y = point >> 16; - - if (y) - { - LOG_ERROR(RSX, "%s: y is not null (0x%x)", __FUNCTION__, y); - } - - u32 address = get_address(method_registers[NV3062_SET_OFFSET_DESTIN] + (x << 2) + index * 4, method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]); - vm::write32(address, arg); - } - }; - } - - namespace nv3089 - { - never_inline void image_in(u32 arg) - { - u32 operation = method_registers[NV3089_SET_OPERATION]; - - u32 clip_x = method_registers[NV3089_CLIP_POINT] & 0xffff; - u32 clip_y = method_registers[NV3089_CLIP_POINT] >> 16; - u32 clip_w = method_registers[NV3089_CLIP_SIZE] & 0xffff; - u32 clip_h = method_registers[NV3089_CLIP_SIZE] >> 16; - - u32 out_x = method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff; - u32 out_y = method_registers[NV3089_IMAGE_OUT_POINT] >> 16; - u32 out_w = method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff; - u32 out_h = method_registers[NV3089_IMAGE_OUT_SIZE] >> 16; - - u16 in_w = method_registers[NV3089_IMAGE_IN_SIZE]; - u16 in_h = method_registers[NV3089_IMAGE_IN_SIZE] >> 16; - u16 in_pitch = method_registers[NV3089_IMAGE_IN_FORMAT]; - u8 in_origin = method_registers[NV3089_IMAGE_IN_FORMAT] >> 16; - u8 in_inter = method_registers[NV3089_IMAGE_IN_FORMAT] >> 24; - u32 src_color_format = method_registers[NV3089_SET_COLOR_FORMAT]; - - f32 in_x = (method_registers[NV3089_IMAGE_IN] & 0xffff) / 16.f; - f32 in_y = (method_registers[NV3089_IMAGE_IN] >> 16) / 16.f; - - if (in_origin != CELL_GCM_TRANSFER_ORIGIN_CORNER) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", in_origin); - } - - if (in_inter != CELL_GCM_TRANSFER_INTERPOLATOR_ZOH && in_inter != CELL_GCM_TRANSFER_INTERPOLATOR_FOH) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", in_inter); - } - - if (operation != CELL_GCM_TRANSFER_OPERATION_SRCCOPY) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown operation (%d)", operation); - } - - const u32 src_offset = method_registers[NV3089_IMAGE_IN_OFFSET]; - const u32 src_dma = method_registers[NV3089_SET_CONTEXT_DMA_IMAGE]; - - u32 dst_offset; - u32 dst_dma = 0; - u16 dst_color_format; - u32 out_pitch = 0; - u32 out_aligment = 64; - - switch (method_registers[NV3089_SET_CONTEXT_SURFACE]) - { - case CELL_GCM_CONTEXT_SURFACE2D: - dst_dma = method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]; - dst_offset = method_registers[NV3062_SET_OFFSET_DESTIN]; - dst_color_format = method_registers[NV3062_SET_COLOR_FORMAT]; - out_pitch = method_registers[NV3062_SET_PITCH] >> 16; - out_aligment = method_registers[NV3062_SET_PITCH] & 0xffff; - break; - - case CELL_GCM_CONTEXT_SWIZZLE2D: - dst_dma = method_registers[NV309E_SET_CONTEXT_DMA_IMAGE]; - dst_offset = method_registers[NV309E_SET_OFFSET]; - dst_color_format = method_registers[NV309E_SET_FORMAT]; - break; - - default: - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers[NV3089_SET_CONTEXT_SURFACE]); - return; - } - - u32 src_address = get_address(src_offset, src_dma); - u32 dst_address = get_address(dst_offset, dst_dma); - - u32 in_bpp = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? 2 : 4; // bytes per pixel - u32 out_bpp = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? 2 : 4; - - if (out_pitch == 0) - { - out_pitch = out_bpp * out_w; - } - - if (in_pitch == 0) - { - in_pitch = in_bpp * in_w; - } - - if (clip_w > out_w) - { - clip_w = out_w; - } - - if (clip_h > out_h) - { - clip_h = out_h; - } - - //LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: src = 0x%x, dst = 0x%x", src_address, dst_address); - - u8* pixels_src = vm::_ptr(src_address); - u8* pixels_dst = vm::_ptr(dst_address); - - if (dst_color_format != CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 && - dst_color_format != CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown dst_color_format (%d)", dst_color_format); - } - - if (src_color_format != CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 && - src_color_format != CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", src_color_format); - } - - //LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: SIZE=0x%08x, pitch=0x%x, offset=0x%x, scaleX=%f, scaleY=%f, CLIP_SIZE=0x%08x, OUT_SIZE=0x%08x", - // method_registers[NV3089_IMAGE_IN_SIZE], in_pitch, src_offset, double(1 << 20) / (method_registers[NV3089_DS_DX]), double(1 << 20) / (method_registers[NV3089_DT_DY]), - // method_registers[NV3089_CLIP_SIZE], method_registers[NV3089_IMAGE_OUT_SIZE]); - - std::unique_ptr temp1, temp2; - - AVPixelFormat in_format = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; - AVPixelFormat out_format = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; - - u32 out_offset = out_x * out_bpp + out_pitch * out_y; - - bool need_clip = method_registers[NV3089_CLIP_SIZE] != method_registers[NV3089_IMAGE_IN_SIZE] || method_registers[NV3089_CLIP_POINT]; - bool need_convert = out_format != in_format || out_w != in_w || out_h != in_h; - - u32 slice_h = (u32)(clip_h * (method_registers[NV3089_DS_DX] / 1048576.f)); - - if (slice_h) - { - if (clip_h < out_h) - { - --slice_h; - } - } - else - { - slice_h = clip_h; - } - - if (method_registers[NV3089_SET_CONTEXT_SURFACE] != CELL_GCM_CONTEXT_SWIZZLE2D) - { - if (need_convert || need_clip) - { - if (need_clip) - { - if (need_convert) - { - convert_scale_image(temp1, out_format, out_w, out_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter ? true : false); - - clip_image(pixels_dst + out_offset, temp1.get(), clip_x, clip_y, clip_w, clip_h, out_bpp, out_pitch, out_pitch); - } - else - { - clip_image(pixels_dst + out_offset, pixels_src, clip_x, clip_y, clip_w, clip_h, out_bpp, in_pitch, out_pitch); - } - } - else - { - convert_scale_image(pixels_dst + out_offset, out_format, out_w, out_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter ? true : false); - } - } - else - { - if (out_pitch != in_pitch || out_pitch != out_bpp * out_w) - { - for (u32 y = 0; y < out_h; ++y) - { - u8 *dst = pixels_dst + out_x * out_bpp + out_pitch * (y + out_y); - u8 *src = pixels_src + in_pitch * y; - - std::memmove(dst, src, out_w * out_bpp); - } - } - else - { - std::memmove(pixels_dst + out_offset, pixels_src, out_pitch * out_h); - } - } - } - else - { - if (need_convert || need_clip) - { - if (need_clip) - { - if (need_convert) - { - convert_scale_image(temp1, out_format, out_w, out_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter ? true : false); - - clip_image(temp2, temp1.get(), clip_x, clip_y, clip_w, clip_h, out_bpp, out_pitch, out_pitch); - } - else - { - clip_image(temp2, pixels_src, clip_x, clip_y, clip_w, clip_h, out_bpp, in_pitch, out_pitch); - } - } - else - { - convert_scale_image(temp2, out_format, out_w, out_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, clip_h, in_inter ? true : false); - } - - pixels_src = temp2.get(); - } - - u8 sw_width_log2 = method_registers[NV309E_SET_FORMAT] >> 16; - u8 sw_height_log2 = method_registers[NV309E_SET_FORMAT] >> 24; - - // 0 indicates height of 1 pixel - sw_height_log2 = sw_height_log2 == 0 ? 1 : sw_height_log2; - - // swizzle based on destination size - u16 sw_width = 1 << sw_width_log2; - u16 sw_height = 1 << sw_height_log2; - - temp2.reset(new u8[out_bpp * sw_width * sw_height]); - - u8* linear_pixels = pixels_src; - u8* swizzled_pixels = temp2.get(); - - // Check and pad texture out if we are given non square texture for swizzle to be correct - if (sw_width != out_w || sw_height != out_h) - { - std::unique_ptr sw_temp(new u8[out_bpp * sw_width * sw_height]); - - switch (out_bpp) - { - case 1: - pad_texture(linear_pixels, sw_temp.get(), out_w, out_h, sw_width, sw_height); - break; - case 2: - pad_texture(linear_pixels, sw_temp.get(), out_w, out_h, sw_width, sw_height); - break; - case 4: - pad_texture(linear_pixels, sw_temp.get(), out_w, out_h, sw_width, sw_height); - break; - } - - linear_pixels = sw_temp.get(); - } - - switch (out_bpp) - { - case 1: - convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, false); - break; - case 2: - convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, false); - break; - case 4: - convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, false); - break; - } - - std::memcpy(pixels_dst, swizzled_pixels, out_bpp * sw_width * sw_height); - } - } - } - - namespace nv0039 - { - force_inline void buffer_notify(u32 arg) - { - const u32 inPitch = method_registers[NV0039_PITCH_IN]; - const u32 outPitch = method_registers[NV0039_PITCH_OUT]; - const u32 lineLength = method_registers[NV0039_LINE_LENGTH_IN]; - const u32 lineCount = method_registers[NV0039_LINE_COUNT]; - const u8 outFormat = method_registers[NV0039_FORMAT] >> 8; - const u8 inFormat = method_registers[NV0039_FORMAT]; - const u32 notify = arg; - - // The existing GCM commands use only the value 0x1 for inFormat and outFormat - if (inFormat != 0x01 || outFormat != 0x01) - { - LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat); - } - - if (lineCount == 1 && !inPitch && !outPitch && !notify) - { - std::memcpy( - vm::base(get_address(method_registers[NV0039_OFFSET_OUT], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT])), - vm::base(get_address(method_registers[NV0039_OFFSET_IN], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN])), - lineLength); - } - else - { - LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", - method_registers[NV0039_OFFSET_IN], method_registers[NV0039_OFFSET_OUT], inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); - } - } - } - - void flip_command(thread* rsx, u32 arg) - { - if (user_asked_for_frame_capture) - { - rsx->capture_current_frame = true; - user_asked_for_frame_capture = false; - frame_debug.reset(); - } - else if (rsx->capture_current_frame) - { - rsx->capture_current_frame = false; - Emu.Pause(); - } - - rsx->gcm_current_buffer = arg; - rsx->flip(arg); - // After each flip PS3 system is executing a routine that changes registers value to some default. - // Some game use this default state (SH3). - rsx->reset(); - - rsx->last_flip_time = get_system_time() - 1000000; - rsx->gcm_current_buffer = arg; - rsx->flip_status = 0; - - if (rsx->flip_handler) - { - Emu.GetCallbackManager().Async([func = rsx->flip_handler](PPUThread& ppu) - { - func(ppu, 1); - }); - } - - rsx->sem_flip.post_and_wait(); - - //sync - double limit; - switch (rpcs3::state.config.rsx.frame_limit.value()) - { - case rsx_frame_limit::_50: limit = 50.; break; - case rsx_frame_limit::_59_94: limit = 59.94; break; - case rsx_frame_limit::_30: limit = 30.; break; - case rsx_frame_limit::_60: limit = 60.; break; - case rsx_frame_limit::Auto: limit = rsx->fps_limit; break; //TODO - - case rsx_frame_limit::Off: - default: - return; - } - - std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - rsx->timer_sync.GetElapsedTimeInMilliSec()))); - rsx->timer_sync.Start(); - rsx->local_transform_constants.clear(); - } - - void user_command(thread* rsx, u32 arg) - { - if (rsx->user_handler) - { - Emu.GetCallbackManager().Async([func = rsx->user_handler, arg](PPUThread& ppu) - { - func(ppu, arg); - }); - } - else - { - throw EXCEPTION("User handler not set"); - } - } - - struct __rsx_methods_t - { - using rsx_impl_method_t = void(*)(u32); - - template - force_inline static void call_impl_func(thread *rsx, u32 arg) - { - impl_func(rsx, arg); - } - - template - force_inline static void call_impl_func(thread *rsx, u32 arg) - { - impl_func(arg); - } - - template - static void wrapper(thread *rsx, u32 arg) - { - // try process using gpu - if (rsx->do_method(id, arg)) - { - if (rsx->capture_current_frame && id == NV4097_CLEAR_SURFACE) - rsx->capture_frame("clear"); - return; - } - - // not handled by renderer - // try process using cpu - if (impl_func != nullptr) - call_impl_func(rsx, arg); - } - - template class T, int index = 0> - struct bind_range_impl_t - { - force_inline static void impl() - { - bind_range_impl_t::impl(); - bind::impl>(); - } - }; - - template class T> - struct bind_range_impl_t - { - force_inline static void impl() - { - } - }; - - template class T, int index = 0> - force_inline static void bind_range() - { - bind_range_impl_t::impl(); - } - - [[noreturn]] never_inline static void bind_redefinition_error(int id) - { - throw EXCEPTION("RSX method implementation redefinition (0x%04x)", id); - } - - template - static void bind_impl() - { - if (methods[id]) - { - bind_redefinition_error(id); - } - - methods[id] = wrapper; - } - - template - static void bind_cpu_only_impl() - { - if (methods[id]) - { - bind_redefinition_error(id); - } - - methods[id] = call_impl_func; - } - - template static void bind() { bind_impl(); } - template static void bind() { bind_impl(); } - - //do not try process on gpu - template static void bind_cpu_only() { bind_cpu_only_impl(); } - //do not try process on gpu - template static void bind_cpu_only() { bind_cpu_only_impl(); } - - __rsx_methods_t() - { - // NV406E - bind_cpu_only(); - bind(); - bind(); - - // NV4097 - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_cpu_only(); - bind_cpu_only(); - - //NV308A - bind_range(); - bind_range(); - - //NV3089 - bind(); - - //NV0039 - bind(); - - // custom methods - bind_cpu_only(); - bind_cpu_only(); - } - } __rsx_methods; - std::string shaders_cache::path_to_root() { return fs::get_executable_dir() + "data/"; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index e4537aa13f..600719b90a 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -148,69 +148,6 @@ namespace rsx static std::string path_to_root(); }; - //TODO - union alignas(4) method_registers_t - { - u8 _u8[0x10000]; - u32 _u32[0x10000 >> 2]; -/* - struct alignas(4) - { - u8 pad[NV4097_SET_TEXTURE_OFFSET - 4]; - - struct alignas(4) texture_t - { - u32 offset; - - union format_t - { - u32 _u32; - - struct - { - u32: 1; - u32 location : 1; - u32 cubemap : 1; - u32 border_type : 1; - u32 dimension : 4; - u32 format : 8; - u32 mipmap : 16; - }; - } format; - - union address_t - { - u32 _u32; - - struct - { - u32 wrap_s : 4; - u32 aniso_bias : 4; - u32 wrap_t : 4; - u32 unsigned_remap : 4; - u32 wrap_r : 4; - u32 gamma : 4; - u32 signed_remap : 4; - u32 zfunc : 4; - }; - } address; - - u32 control0; - u32 control1; - u32 filter; - u32 image_rect; - u32 border_color; - } textures[limits::textures_count]; - }; -*/ - u32& operator[](int index) - { - return _u32[index >> 2]; - } - }; - - extern u32 method_registers[0x10000 >> 2]; - u32 get_vertex_type_size(u32 type); u32 get_address(u32 offset, u32 location); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index a9d013b1f7..b7481ccaf9 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -129,6 +129,7 @@ + @@ -575,6 +576,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index c0cdafaaf1..659e72fb71 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -377,9 +377,6 @@ Loader - - Source Files - Utilities @@ -930,6 +927,12 @@ Emu\GPU\RSX + + Emu\GPU\RSX + + + Source Files + @@ -1779,5 +1782,8 @@ Emu\GPU\RSX + + Emu\GPU\RSX + \ No newline at end of file