diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 81505f001c..d02c941089 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -298,56 +298,63 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(Primitive_type draw_mo throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", draw_mode); } -DXGI_FORMAT get_color_surface_format(u8 format) +DXGI_FORMAT get_color_surface_format(Surface_color_format format) { switch (format) { - case CELL_GCM_SURFACE_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM; - case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM; //BIT.TRIP Runner2 use this - case CELL_GCM_SURFACE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT; - case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT; - case CELL_GCM_SURFACE_A8B8G8R8: return DXGI_FORMAT_R8G8B8A8_UNORM; + case Surface_color_format::r5g6b5: return DXGI_FORMAT_B5G6R5_UNORM; + case Surface_color_format::x8r8g8b8_o8r8g8b8: + case Surface_color_format::x8r8g8b8_z8r8g8b8: + case Surface_color_format::x8b8g8r8_o8b8g8r8: + case Surface_color_format::x8b8g8r8_z8b8g8r8: + return DXGI_FORMAT_B8G8R8X8_UNORM; //BIT.TRIP Runner2 use this + case Surface_color_format::a8b8g8r8: + case Surface_color_format::a8r8g8b8: return DXGI_FORMAT_R8G8B8A8_UNORM; + case Surface_color_format::b8: return DXGI_FORMAT_R8_UNORM; + case Surface_color_format::g8b8: return DXGI_FORMAT_R8G8_UNORM; + case Surface_color_format::w16z16y16x16: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case Surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case Surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT; } throw EXCEPTION("Invalid format (0x%x)", format); } -DXGI_FORMAT get_depth_stencil_surface_format(u8 format) +DXGI_FORMAT get_depth_stencil_surface_format(Surface_depth_format format) { switch (format) { - case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM; - case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case Surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM; + case Surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT; } throw EXCEPTION("Invalid format (0x%x)", format); } -DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) +DXGI_FORMAT get_depth_stencil_surface_clear_format(Surface_depth_format format) { switch (format) { - case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM; - case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case Surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM; + case Surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT; } throw EXCEPTION("Invalid format (0x%x)", format); } -DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) +DXGI_FORMAT get_depth_stencil_typeless_surface_format(Surface_depth_format format) { switch (format) { - case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_TYPELESS; - case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24G8_TYPELESS; + case Surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS; + case Surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS; } throw EXCEPTION("Invalid format (0x%x)", format); } -DXGI_FORMAT get_depth_samplable_surface_format(u8 format) +DXGI_FORMAT get_depth_samplable_surface_format(Surface_depth_format format) { switch (format) { - case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_FLOAT; - case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case Surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM; + case Surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; } throw EXCEPTION("Invalid format (0x%x)", format); } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h index cfa47e8bda..813864d379 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h @@ -66,27 +66,27 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(Primitive_type draw_mo /** * Convert color surface format to DXGI_FORMAT */ -DXGI_FORMAT get_color_surface_format(u8 format); +DXGI_FORMAT get_color_surface_format(Surface_color_format format); /** * Convert depth stencil surface format to DXGI_FORMAT */ -DXGI_FORMAT get_depth_stencil_surface_format(u8 format); +DXGI_FORMAT get_depth_stencil_surface_format(Surface_depth_format format); /** *Convert depth stencil surface format to DXGI_FORMAT suited for clear value */ -DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format); +DXGI_FORMAT get_depth_stencil_surface_clear_format(Surface_depth_format format); /** * Convert depth surface format to a typeless DXGI_FORMAT */ -DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format); +DXGI_FORMAT get_depth_stencil_typeless_surface_format(Surface_depth_format format); /** * Convert depth surface format to a DXGI_FORMAT that can be depth sampled */ -DXGI_FORMAT get_depth_samplable_surface_format(u8 format); +DXGI_FORMAT get_depth_samplable_surface_format(Surface_depth_format format); /** * Convert front face value to bool value telling wheter front face is counterclockwise or not diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 9dd5df2ab0..9d89cdf53f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -348,20 +348,20 @@ void D3D12GSRender::end() namespace { -bool is_flip_surface_in_global_memory(u32 color_target) +bool is_flip_surface_in_global_memory(Surface_target color_target) { switch (color_target) { - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: - case CELL_GCM_SURFACE_TARGET_MRT1: - case CELL_GCM_SURFACE_TARGET_MRT2: - case CELL_GCM_SURFACE_TARGET_MRT3: + case Surface_target::surface_a: + case Surface_target::surface_b: + case Surface_target::surfaces_a_b: + case Surface_target::surfaces_a_b_c: + case Surface_target::surfaces_a_b_c_d: return true; - case CELL_GCM_SURFACE_TARGET_NONE: + case Surface_target::none: return false; } - throw EXCEPTION("Wrong color_target (%u)", color_target); + throw EXCEPTION("Wrong color_target"); } } @@ -370,7 +370,7 @@ void D3D12GSRender::flip(int buffer) ID3D12Resource *resource_to_flip; float viewport_w, viewport_h; - if (!is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + if (!is_flip_surface_in_global_memory(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) { resource_storage &storage = get_current_resource_storage(); assert(storage.ram_framebuffer == nullptr); @@ -459,7 +459,7 @@ void D3D12GSRender::flip(int buffer) shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; shader_resource_view_desc.Texture2D.MipLevels = 1; - if (is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + if (is_flip_surface_in_global_memory(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) shader_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; else shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( @@ -504,7 +504,7 @@ void D3D12GSRender::flip(int buffer) if (!rpcs3::config.rsx.d3d12.overlay.value()) get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backbuffer[m_swap_chain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); - if (is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) && resource_to_flip != nullptr) + if (is_flip_surface_in_global_memory(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) && resource_to_flip != nullptr) get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(resource_to_flip, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); CHECK_HRESULT(get_current_resource_storage().command_list->Close()); m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf()); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 85f0940848..c8a26cba2a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -162,19 +162,19 @@ void D3D12GSRender::load_program() prop.DepthStencilFormat = get_depth_stencil_surface_format(m_surface.depth_format); prop.RenderTargetsFormat = get_color_surface_format(m_surface.color_format); - switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: + case Surface_target::surface_a: + case Surface_target::surface_b: prop.numMRT = 1; break; - case CELL_GCM_SURFACE_TARGET_MRT1: + case Surface_target::surfaces_a_b: prop.numMRT = 2; break; - case CELL_GCM_SURFACE_TARGET_MRT2: + case Surface_target::surfaces_a_b_c: prop.numMRT = 3; break; - case CELL_GCM_SURFACE_TARGET_MRT3: + case Surface_target::surfaces_a_b_c_d: prop.numMRT = 4; break; default: diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index ed29409bfc..bdc74f8ed7 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -13,33 +13,42 @@ #include "D3D12GSRender.h" #include "D3D12Formats.h" - namespace { - UINT get_num_rtt(u8 color_target) + u32 get_max_depth_value(Surface_depth_format format) + { + switch (format) + { + case Surface_depth_format::z16: return 0xFFFF; + case Surface_depth_format::z24s8: return 0xFFFFFF; + } + throw EXCEPTION("Unknow depth format"); + } + + UINT get_num_rtt(Surface_target color_target) { switch (color_target) { - case CELL_GCM_SURFACE_TARGET_NONE: return 0; - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: return 1; - case CELL_GCM_SURFACE_TARGET_MRT1: return 2; - case CELL_GCM_SURFACE_TARGET_MRT2: return 3; - case CELL_GCM_SURFACE_TARGET_MRT3: return 4; + case Surface_target::none: return 0; + case Surface_target::surface_a: + case Surface_target::surface_b: return 1; + case Surface_target::surfaces_a_b: return 2; + case Surface_target::surfaces_a_b_c: return 3; + case Surface_target::surfaces_a_b_c_d: return 4; } throw EXCEPTION("Wrong color_target (%d)", color_target); } - std::vector get_rtt_indexes(u8 color_target) + std::vector get_rtt_indexes(Surface_target color_target) { switch (color_target) { - case CELL_GCM_SURFACE_TARGET_NONE: return{}; - case CELL_GCM_SURFACE_TARGET_0: return{ 0 }; - case CELL_GCM_SURFACE_TARGET_1: return{ 1 }; - case CELL_GCM_SURFACE_TARGET_MRT1: return{ 0, 1 }; - case CELL_GCM_SURFACE_TARGET_MRT2: return{ 0, 1, 2 }; - case CELL_GCM_SURFACE_TARGET_MRT3: return{ 0, 1, 2, 3 }; + case Surface_target::none: return{}; + case Surface_target::surface_a: return{ 0 }; + case Surface_target::surface_b: return{ 1 }; + case Surface_target::surfaces_a_b: return{ 0, 1 }; + case Surface_target::surfaces_a_b_c: return{ 0, 1, 2 }; + case Surface_target::surfaces_a_b_c_d: return{ 0, 1, 2, 3 }; } throw EXCEPTION("Wrong color_target (%d)", color_target); } @@ -63,6 +72,50 @@ namespace { return register_value & 0xff; } + + size_t get_aligned_pitch(Surface_color_format format, u32 width) + { + switch (format) + { + case Surface_color_format::b8: return align(width, 256); + case Surface_color_format::g8b8: + case Surface_color_format::x1r5g5b5_o1r5g5b5: + case Surface_color_format::x1r5g5b5_z1r5g5b5: + case Surface_color_format::r5g6b5: return align(width * 2, 256); + case Surface_color_format::a8b8g8r8: + case Surface_color_format::x8b8g8r8_o8b8g8r8: + case Surface_color_format::x8b8g8r8_z8b8g8r8: + case Surface_color_format::x8r8g8b8_o8r8g8b8: + case Surface_color_format::x8r8g8b8_z8r8g8b8: + case Surface_color_format::x32: + case Surface_color_format::a8r8g8b8: return align(width * 4, 256); + case Surface_color_format::w16z16y16x16: return align(width * 8, 256); + case Surface_color_format::w32z32y32x32: return align(width * 16, 256); + } + throw EXCEPTION("Unknow color surface format"); + } + + size_t get_packed_pitch(Surface_color_format format, u32 width) + { + switch (format) + { + case Surface_color_format::b8: return width; + case Surface_color_format::g8b8: + case Surface_color_format::x1r5g5b5_o1r5g5b5: + case Surface_color_format::x1r5g5b5_z1r5g5b5: + case Surface_color_format::r5g6b5: return width * 2; + case Surface_color_format::a8b8g8r8: + case Surface_color_format::x8b8g8r8_o8b8g8r8: + case Surface_color_format::x8b8g8r8_z8b8g8r8: + case Surface_color_format::x8r8g8b8_o8r8g8b8: + case Surface_color_format::x8r8g8b8_z8r8g8b8: + case Surface_color_format::x32: + case Surface_color_format::a8r8g8b8: return width * 4; + case Surface_color_format::w16z16y16x16: return width * 8; + case Surface_color_format::w32z32y32x32: return width * 16; + } + throw EXCEPTION("Unknow color surface format"); + } } void D3D12GSRender::clear_surface(u32 arg) @@ -82,7 +135,7 @@ void D3D12GSRender::clear_surface(u32 arg) if (arg & 0x1) { u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; - u32 max_depth_value = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff; + u32 max_depth_value = get_max_depth_value(m_surface.depth_format); get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, 1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL])); } @@ -95,7 +148,7 @@ void D3D12GSRender::clear_surface(u32 arg) if (arg & 0xF0) { CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.current_rtts_handle); - size_t rtt_index = get_num_rtt(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]); + size_t rtt_index = get_num_rtt(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])); get_current_resource_storage().render_targets_descriptors_heap_index += rtt_index; for (unsigned i = 0; i < rtt_index; i++) get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, g_descriptor_stride_rtv), get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(), @@ -169,7 +222,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis m_surface.unpack(surface_format); std::array clear_color = get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]); - m_rtts.prepare_render_target(copycmdlist, surface_format, clip_h_reg, clip_v_reg, target_reg, address_color, address_z, m_device.Get(), clear_color, 1.f, 0); + m_rtts.prepare_render_target(copycmdlist, surface_format, clip_h_reg, clip_v_reg, to_surface_target(target_reg), address_color, address_z, m_device.Get(), clear_color, 1.f, 0); // write descriptors DXGI_FORMAT dxgi_format = get_color_surface_format(m_surface.color_format); @@ -180,7 +233,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis m_rtts.current_rtts_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart()) .Offset((INT)get_current_resource_storage().render_targets_descriptors_heap_index * g_descriptor_stride_rtv); size_t rtt_index = 0; - for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + for (u8 i : get_rtt_indexes(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) { if (std::get<1>(m_rtts.m_bound_render_targets[i]) == nullptr) continue; @@ -203,7 +256,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis void D3D12GSRender::set_rtt_and_ds(ID3D12GraphicsCommandList *command_list) { - UINT num_rtt = get_num_rtt(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]); + UINT num_rtt = get_num_rtt(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])); D3D12_CPU_DESCRIPTOR_HANDLE* rtt_handle = (num_rtt > 0) ? &m_rtts.current_rtts_handle : nullptr; D3D12_CPU_DESCRIPTOR_HANDLE* ds_handle = (std::get<1>(m_rtts.m_bound_depth_stencil) != nullptr) ? &m_rtts.current_ds_handle : nullptr; command_list->OMSetRenderTargets((UINT)num_rtt, rtt_handle, true, ds_handle); @@ -225,26 +278,14 @@ namespace ID3D12GraphicsCommandList * command_list, data_heap &readback_heap, ID3D12Resource * color_surface, - int color_surface_format + Surface_color_format color_surface_format ) { int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; DXGI_FORMAT dxgi_format = get_color_surface_format(color_surface_format); - size_t row_pitch; - switch (color_surface_format) - { - case CELL_GCM_SURFACE_R5G6B5: - row_pitch = align(clip_w * 2, 256); - break; - case CELL_GCM_SURFACE_A8R8G8B8: - row_pitch = align(clip_w * 4, 256); - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - row_pitch = align(clip_w * 8, 256); - break; - } + size_t row_pitch = get_aligned_pitch(color_surface_format, clip_w); size_t buffer_size = row_pitch * clip_h; size_t heap_offset = readback_heap.alloc(buffer_size); @@ -283,6 +324,8 @@ namespace } } + + void D3D12GSRender::copy_render_target_to_dma_location() { // Add all buffer write @@ -384,7 +427,7 @@ void D3D12GSRender::copy_render_target_to_dma_location() size_t color_buffer_offset_in_heap[4]; if (rpcs3::state.config.rsx.opengl.write_color_buffers) { - for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + for (u8 i : get_rtt_indexes(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) { if (!address_color[i]) continue; @@ -423,25 +466,11 @@ void D3D12GSRender::copy_render_target_to_dma_location() m_readback_resources.unmap(); } - size_t srcPitch, dstPitch; - switch (m_surface.color_format) - { - case CELL_GCM_SURFACE_R5G6B5: - srcPitch = align(clip_w * 2, 256); - dstPitch = clip_w * 2; - break; - case CELL_GCM_SURFACE_A8R8G8B8: - srcPitch = align(clip_w * 4, 256); - dstPitch = clip_w * 4; - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - srcPitch = align(clip_w * 8, 256); - dstPitch = clip_w * 8; - break; - } - if (rpcs3::state.config.rsx.opengl.write_color_buffers) { + size_t srcPitch = get_aligned_pitch(m_surface.color_format, clip_w); + size_t dstPitch = get_packed_pitch(m_surface.color_format, clip_w); + void *dest_buffer[] = { vm::base(address_color[0]), @@ -450,7 +479,7 @@ void D3D12GSRender::copy_render_target_to_dma_location() vm::base(address_color[3]), }; - for (u8 i : get_rtt_indexes(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + for (u8 i : get_rtt_indexes(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) { if (!address_color[i]) continue; @@ -473,22 +502,8 @@ void D3D12GSRender::copy_render_targets_to_memory(void *buffer, u8 rtt) int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - size_t srcPitch, dstPitch; - switch (m_surface.color_format) - { - case CELL_GCM_SURFACE_R5G6B5: - srcPitch = align(clip_w * 2, 256); - dstPitch = clip_w * 2; - break; - case CELL_GCM_SURFACE_A8R8G8B8: - srcPitch = align(clip_w * 4, 256); - dstPitch = clip_w * 4; - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - srcPitch = align(clip_w * 8, 256); - dstPitch = clip_w * 8; - break; - } + size_t srcPitch = get_aligned_pitch(m_surface.color_format, clip_w); + size_t dstPitch = get_packed_pitch(m_surface.color_format, clip_w); copy_readback_buffer_to_dest(buffer, m_readback_resources, heap_offset, srcPitch, dstPitch, clip_h); } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h index 3d0970f94b..4e43d440b2 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h @@ -11,18 +11,18 @@ namespace rsx { namespace { - std::vector get_rtt_indexes(u8 color_target) + std::vector get_rtt_indexes(Surface_target color_target) { switch (color_target) { - case CELL_GCM_SURFACE_TARGET_NONE: return{}; - case CELL_GCM_SURFACE_TARGET_0: return{ 0 }; - case CELL_GCM_SURFACE_TARGET_1: return{ 1 }; - case CELL_GCM_SURFACE_TARGET_MRT1: return{ 0, 1 }; - case CELL_GCM_SURFACE_TARGET_MRT2: return{ 0, 1, 2 }; - case CELL_GCM_SURFACE_TARGET_MRT3: return{ 0, 1, 2, 3 }; + case Surface_target::none: return{}; + case Surface_target::surface_a: return{ 0 }; + case Surface_target::surface_b: return{ 1 }; + case Surface_target::surfaces_a_b: return{ 0, 1 }; + case Surface_target::surfaces_a_b_c: return{ 0, 1, 2 }; + case Surface_target::surfaces_a_b_c_d: return{ 0, 1, 2, 3 }; } - throw EXCEPTION("Wrong color_target (%d)", color_target); + throw EXCEPTION("Wrong color_target"); } } @@ -56,7 +56,7 @@ namespace rsx gsl::not_null bind_address_as_render_targets( command_list_type command_list, u32 address, - u8 surface_color_format, size_t width, size_t height, + Surface_color_format surface_color_format, size_t width, size_t height, Args&&... extra_params) { auto It = m_render_targets_storage.find(address); @@ -75,7 +75,7 @@ namespace rsx m_render_targets_storage.erase(address); } - m_render_targets_storage[address] = Traits::create_new_render_target(address, surface_color_format, width, height, std::forward(extra_params)...); + m_render_targets_storage[address] = Traits::create_new_surface(address, surface_color_format, width, height, std::forward(extra_params)...); return m_render_targets_storage[address].Get(); } @@ -83,7 +83,7 @@ namespace rsx gsl::not_null bind_address_as_depth_stencil( command_list_type command_list, u32 address, - u8 surface_depth_format, size_t width, size_t height, + Surface_depth_format surface_depth_format, size_t width, size_t height, Args&&... extra_params) { auto It = m_depth_stencil_storage.find(address); @@ -99,7 +99,7 @@ namespace rsx m_depth_stencil_storage.erase(address); } - m_depth_stencil_storage[address] = Traits::create_new_depth_stencil(address, surface_depth_format, width, height, std::forward(extra_params)...); + m_depth_stencil_storage[address] = Traits::create_new_surface(address, surface_depth_format, width, height, std::forward(extra_params)...); return m_depth_stencil_storage[address].Get(); } public: @@ -108,7 +108,7 @@ namespace rsx command_list_type command_list, u32 set_surface_format_reg, u32 clip_horizontal_reg, u32 clip_vertical_reg, - u32 set_surface_target, + Surface_target set_surface_target, const std::array &surface_addresses, u32 address_z, Args&&... extra_params) { @@ -178,9 +178,9 @@ struct render_target_traits using command_list_type = gsl::not_null; static - ComPtr create_new_render_target( + ComPtr create_new_surface( u32 address, - u8 surface_color_format, size_t width, size_t height, + Surface_color_format surface_color_format, size_t width, size_t height, gsl::not_null device, const std::array &clear_color, float, u8) { DXGI_FORMAT dxgi_format = get_color_surface_format(surface_color_format); @@ -226,9 +226,9 @@ struct render_target_traits } static - ComPtr create_new_depth_stencil( + ComPtr create_new_surface( u32 address, - u8 surfaceDepthFormat, size_t width, size_t height, + Surface_depth_format surfaceDepthFormat, size_t width, size_t height, gsl::not_null device, const std::array& , float clear_depth, u8 clear_stencil) { D3D12_CLEAR_VALUE clear_depth_value = {}; @@ -272,14 +272,14 @@ struct render_target_traits static - bool rtt_has_format_width_height(const ComPtr &rtt, u8 surface_color_format, size_t width, size_t height) + bool rtt_has_format_width_height(const ComPtr &rtt, Surface_color_format surface_color_format, size_t width, size_t height) { DXGI_FORMAT dxgi_format = get_color_surface_format(surface_color_format); return rtt->GetDesc().Format == dxgi_format && rtt->GetDesc().Width == width && rtt->GetDesc().Height == height; } static - bool ds_has_format_width_height(const ComPtr &rtt, u8 surface_depth_stencil_format, size_t width, size_t height) + bool ds_has_format_width_height(const ComPtr &rtt, Surface_depth_format surface_depth_stencil_format, size_t width, size_t height) { //TODO: Check format return rtt->GetDesc().Width == width && rtt->GetDesc().Height == height; diff --git a/rpcs3/Emu/RSX/GCM.cpp b/rpcs3/Emu/RSX/GCM.cpp index 6d0d3bf7e8..61af633ec0 100644 --- a/rpcs3/Emu/RSX/GCM.cpp +++ b/rpcs3/Emu/RSX/GCM.cpp @@ -762,6 +762,69 @@ Primitive_type to_primitive_type(u8 in) throw new EXCEPTION("Unknow primitive type %d", in); } + +enum +{ + // Surface Target + CELL_GCM_SURFACE_TARGET_NONE = 0, + CELL_GCM_SURFACE_TARGET_0 = 1, + CELL_GCM_SURFACE_TARGET_1 = 2, + CELL_GCM_SURFACE_TARGET_MRT1 = 0x13, + CELL_GCM_SURFACE_TARGET_MRT2 = 0x17, + CELL_GCM_SURFACE_TARGET_MRT3 = 0x1f, + + // Surface Depth + CELL_GCM_SURFACE_Z16 = 1, + CELL_GCM_SURFACE_Z24S8 = 2, + + // Surface Antialias + CELL_GCM_SURFACE_CENTER_1 = 0, + CELL_GCM_SURFACE_DIAGONAL_CENTERED_2 = 3, + CELL_GCM_SURFACE_SQUARE_CENTERED_4 = 4, + CELL_GCM_SURFACE_SQUARE_ROTATED_4 = 5, + + // Surface format + CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5 = 1, + CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5 = 2, + CELL_GCM_SURFACE_R5G6B5 = 3, + CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8 = 4, + CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8 = 5, + CELL_GCM_SURFACE_A8R8G8B8 = 8, + CELL_GCM_SURFACE_B8 = 9, + CELL_GCM_SURFACE_G8B8 = 10, + CELL_GCM_SURFACE_F_W16Z16Y16X16 = 11, + CELL_GCM_SURFACE_F_W32Z32Y32X32 = 12, + CELL_GCM_SURFACE_F_X32 = 13, + CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8 = 14, + CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8 = 15, + CELL_GCM_SURFACE_A8B8G8R8 = 16, + +}; + +Surface_target to_surface_target(u8 in) +{ + switch (in) + { + case CELL_GCM_SURFACE_TARGET_NONE: return Surface_target::none; + case CELL_GCM_SURFACE_TARGET_0: return Surface_target::surface_a; + case CELL_GCM_SURFACE_TARGET_1: return Surface_target::surface_b; + case CELL_GCM_SURFACE_TARGET_MRT1: return Surface_target::surfaces_a_b; + case CELL_GCM_SURFACE_TARGET_MRT2: return Surface_target::surfaces_a_b_c; + case CELL_GCM_SURFACE_TARGET_MRT3: return Surface_target::surfaces_a_b_c_d; + } + throw EXCEPTION("Unknow surface target %x", in); +} + +Surface_depth_format to_surface_depth_format(u8 in) +{ + switch (in) + { + case CELL_GCM_SURFACE_Z16: return Surface_depth_format::z16; + case CELL_GCM_SURFACE_Z24S8: return Surface_depth_format::z24s8; + } + throw EXCEPTION("Unknow surface depth format %x", in); +} + std::string rsx::get_method_name(const u32 id) { auto found = methods.find(id); @@ -773,6 +836,40 @@ std::string rsx::get_method_name(const u32 id) return fmt::format("unknown/illegal method [0x%08x]", id); } +Surface_antialiasing to_surface_antialiasing(u8 in) +{ + switch (in) + { + case CELL_GCM_SURFACE_CENTER_1: return Surface_antialiasing::center_1_sample; + case CELL_GCM_SURFACE_DIAGONAL_CENTERED_2: return Surface_antialiasing::diagonal_centered_2_samples; + case CELL_GCM_SURFACE_SQUARE_CENTERED_4: return Surface_antialiasing::square_centered_4_samples; + case CELL_GCM_SURFACE_SQUARE_ROTATED_4: return Surface_antialiasing::square_rotated_4_samples; + } + throw EXCEPTION("unknow surface antialiasing format %x", in); +} + +Surface_color_format to_surface_color_format(u8 in) +{ + switch (in) + { + case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: return Surface_color_format::x1r5g5b5_z1r5g5b5; + case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: return Surface_color_format::x1r5g5b5_o1r5g5b5; + case CELL_GCM_SURFACE_R5G6B5: return Surface_color_format::r5g6b5; + case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: return Surface_color_format::x8r8g8b8_z8r8g8b8; + case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: return Surface_color_format::x8r8g8b8_o8r8g8b8; + case CELL_GCM_SURFACE_A8R8G8B8: return Surface_color_format::a8r8g8b8; + case CELL_GCM_SURFACE_B8: return Surface_color_format::b8; + case CELL_GCM_SURFACE_G8B8: return Surface_color_format::g8b8; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: return Surface_color_format::w16z16y16x16; + case CELL_GCM_SURFACE_F_W32Z32Y32X32: return Surface_color_format::w32z32y32x32; + case CELL_GCM_SURFACE_F_X32: return Surface_color_format::x32; + case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: return Surface_color_format::x8b8g8r8_z8b8g8r8; + case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: return Surface_color_format::x8b8g8r8_o8b8g8r8; + case CELL_GCM_SURFACE_A8B8G8R8: return Surface_color_format::a8b8g8r8; + } + throw EXCEPTION("unknow surface color format %x", in); +} + // Various parameter pretty printing function namespace { @@ -892,46 +989,58 @@ namespace std::string depth_stencil_surface_format(u32 format) { - switch (format) + switch (to_surface_depth_format(format)) { - case CELL_GCM_SURFACE_Z16: return "CELL_GCM_SURFACE_Z16"; - case CELL_GCM_SURFACE_Z24S8: return "CELL_GCM_SURFACE_Z24S8"; + case Surface_depth_format::z16: return "CELL_GCM_SURFACE_Z16"; + case Surface_depth_format::z24s8: return "CELL_GCM_SURFACE_Z24S8"; + } + return "Error"; + } + + std::string surface_antialiasing(u8 format) + { + switch (to_surface_antialiasing(format)) + { + case Surface_antialiasing::center_1_sample: "1 sample centered"; + case Surface_antialiasing::diagonal_centered_2_samples: return "2 samples diagonal centered"; + case Surface_antialiasing::square_centered_4_samples: return "4 samples square centered"; + case Surface_antialiasing::square_rotated_4_samples: return "4 samples diagonal rotated"; } return "Error"; } std::string color_surface_format(u32 format) { - switch (format) + switch (to_surface_color_format(format)) { - case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: return "CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5"; - case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: return "CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5"; - case CELL_GCM_SURFACE_R5G6B5: return "CELL_GCM_SURFACE_R5G6B5"; - case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: return "CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8"; - case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: return "CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8"; - case CELL_GCM_SURFACE_A8R8G8B8: return "CELL_GCM_SURFACE_A8R8G8B8"; - case CELL_GCM_SURFACE_B8: return "CELL_GCM_SURFACE_B8"; - case CELL_GCM_SURFACE_G8B8: return "CELL_GCM_SURFACE_G8B8"; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: return "CELL_GCM_SURFACE_F_W16Z16Y16X16"; - case CELL_GCM_SURFACE_F_W32Z32Y32X32: return "CELL_GCM_SURFACE_F_W32Z32Y32X32"; - case CELL_GCM_SURFACE_F_X32: return "CELL_GCM_SURFACE_F_X32"; - case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: return "CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8"; - case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8"; - case CELL_GCM_SURFACE_A8B8G8R8: return "CELL_GCM_SURFACE_A8B8G8R8"; + case Surface_color_format::x1r5g5b5_z1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5"; + case Surface_color_format::x1r5g5b5_o1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5"; + case Surface_color_format::r5g6b5 : return "CELL_GCM_SURFACE_R5G6B5"; + case Surface_color_format::x8r8g8b8_z8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8"; + case Surface_color_format::x8r8g8b8_o8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8"; + case Surface_color_format::a8r8g8b8: return "CELL_GCM_SURFACE_A8R8G8B8"; + case Surface_color_format::b8: return "CELL_GCM_SURFACE_B8"; + case Surface_color_format::g8b8: return "CELL_GCM_SURFACE_G8B8"; + case Surface_color_format::w16z16y16x16: return "CELL_GCM_SURFACE_F_W16Z16Y16X16"; + case Surface_color_format::w32z32y32x32: return "CELL_GCM_SURFACE_F_W32Z32Y32X32"; + case Surface_color_format::x32: return "CELL_GCM_SURFACE_F_X32"; + case Surface_color_format::x8b8g8r8_z8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8"; + case Surface_color_format::x8b8g8r8_o8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8"; + case Surface_color_format::a8b8g8r8: return "CELL_GCM_SURFACE_A8B8G8R8"; } return "Error"; } std::string surface_target(u32 target) { - switch (target) + switch (to_surface_target(target)) { - case CELL_GCM_SURFACE_TARGET_NONE: return "none"; - case CELL_GCM_SURFACE_TARGET_0: return "surface A"; - case CELL_GCM_SURFACE_TARGET_1: return "surface B"; - case CELL_GCM_SURFACE_TARGET_MRT1: return "surfaces A and B"; - case CELL_GCM_SURFACE_TARGET_MRT2: return "surfaces A, B and C"; - case CELL_GCM_SURFACE_TARGET_MRT3: return "surfaces A,B, C and D"; + case Surface_target::none: return "none"; + case Surface_target::surface_a: return "surface A"; + case Surface_target::surface_b: return "surface B"; + case Surface_target::surfaces_a_b: return "surfaces A and B"; + case Surface_target::surfaces_a_b_c: return "surfaces A, B and C"; + case Surface_target::surfaces_a_b_c_d: return "surfaces A,B, C and D"; } return "Error"; } @@ -1334,7 +1443,7 @@ namespace { NV4097_SET_SURFACE_PITCH_Z, [](u32 arg) -> std::string { return "Surface Zeta: Pitch = " + std::to_string(arg); } }, { NV4097_SET_SURFACE_ZETA_OFFSET, [](u32 arg) -> std::string { return "Surface Zeta: Offset = " + ptr_to_string(arg); } }, { NV4097_SET_CONTEXT_DMA_ZETA, [](u32 arg) -> std::string { return "Surface Zeta: DMA mode = " + dma_mode(arg);} }, - { NV4097_SET_SURFACE_FORMAT, [](u32 arg) -> std::string { return "Surface: Color format = " + color_surface_format(arg & 0x1F) + " DepthStencil format = " + depth_stencil_surface_format((arg >> 5) & 0x7) + " Anti aliasing =" + std::to_string((arg >> 12) & 0x7); } }, + { NV4097_SET_SURFACE_FORMAT, [](u32 arg) -> std::string { return "Surface: Color format = " + color_surface_format(arg & 0x1F) + " DepthStencil format = " + depth_stencil_surface_format((arg >> 5) & 0x7) + " Anti aliasing =" + surface_antialiasing((arg >> 12) & 0x7); } }, { NV4097_SET_SURFACE_CLIP_HORIZONTAL, [](u32 arg) -> std::string { return "Surface: clip x = " + std::to_string(arg & 0xFFFF) + " width = " + std::to_string(arg >> 16); } }, { NV4097_SET_SURFACE_CLIP_VERTICAL, [](u32 arg) -> std::string { return "Surface: clip y = " + std::to_string(arg & 0xFFFF) + " height = " + std::to_string(arg >> 16); } }, { NV4097_SET_SURFACE_COLOR_TARGET, [](u32 arg) -> std::string { return "Surface: Targets " + surface_target(arg); } }, diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 5a1aa4cfe2..9a7dfa4980 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -60,6 +60,56 @@ enum class Primitive_type : u8 Primitive_type to_primitive_type(u8 in); +enum class Surface_target : u8 +{ + none, + surface_a, + surface_b, + surfaces_a_b, + surfaces_a_b_c, + surfaces_a_b_c_d, +}; + +Surface_target to_surface_target(u8 in); + +enum class Surface_depth_format : u8 +{ + z16, // unsigned 16 bits depth + z24s8, // unsigned 24 bits depth + 8 bits stencil +}; + +Surface_depth_format to_surface_depth_format(u8 in); + +enum class Surface_antialiasing : u8 +{ + center_1_sample, + diagonal_centered_2_samples, + square_centered_4_samples, + square_rotated_4_samples, +}; + +Surface_antialiasing to_surface_antialiasing(u8 in); + +enum class Surface_color_format : u8 +{ + x1r5g5b5_z1r5g5b5, + x1r5g5b5_o1r5g5b5, + r5g6b5, + x8r8g8b8_z8r8g8b8, + x8r8g8b8_o8r8g8b8, + a8r8g8b8, + b8, + g8b8, + w16z16y16x16, + w32z32y32x32, + x32, + x8b8g8r8_z8b8g8r8, + x8b8g8r8_o8b8g8r8, + a8b8g8r8, +}; + +Surface_color_format to_surface_color_format(u8 in); + enum { CELL_GCM_DISPLAY_FLIP_STATUS_ = 0, @@ -159,44 +209,9 @@ enum // GCM Surface enum { - // Surface Target - CELL_GCM_SURFACE_TARGET_NONE = 0, - CELL_GCM_SURFACE_TARGET_0 = 1, - CELL_GCM_SURFACE_TARGET_1 = 2, - CELL_GCM_SURFACE_TARGET_MRT1 = 0x13, - CELL_GCM_SURFACE_TARGET_MRT2 = 0x17, - CELL_GCM_SURFACE_TARGET_MRT3 = 0x1f, - - // Surface Depth - CELL_GCM_SURFACE_Z16 = 1, - CELL_GCM_SURFACE_Z24S8 = 2, - - // Surface Antialias - CELL_GCM_SURFACE_CENTER_1 = 0, - CELL_GCM_SURFACE_DIAGONAL_CENTERED_2 = 3, - CELL_GCM_SURFACE_SQUARE_CENTERED_4 = 4, - CELL_GCM_SURFACE_SQUARE_ROTATED_4 = 5, - // Surface type CELL_GCM_SURFACE_PITCH = 1, CELL_GCM_SURFACE_SWIZZLE = 2, - - // Surface format - CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5 = 1, - CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5 = 2, - CELL_GCM_SURFACE_R5G6B5 = 3, - CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8 = 4, - CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8 = 5, - CELL_GCM_SURFACE_A8R8G8B8 = 8, - CELL_GCM_SURFACE_B8 = 9, - CELL_GCM_SURFACE_G8B8 = 10, - CELL_GCM_SURFACE_F_W16Z16Y16X16 = 11, - CELL_GCM_SURFACE_F_W32Z32Y32X32 = 12, - CELL_GCM_SURFACE_F_X32 = 13, - CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8 = 14, - CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8 = 15, - CELL_GCM_SURFACE_A8B8G8R8 = 16, - }; enum diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 5ee19311a7..94eb2b9d19 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -9,6 +9,29 @@ #define DUMP_VERTEX_DATA 0 +namespace +{ + u32 get_max_depth_value(Surface_depth_format format) + { + switch (format) + { + case Surface_depth_format::z16: return 0xFFFF; + case Surface_depth_format::z24s8: return 0xFFFFFF; + } + throw EXCEPTION("Unknow depth format"); + } + + u8 get_pixel_size(Surface_depth_format format) + { + switch (format) + { + case Surface_depth_format::z16: return 2; + case Surface_depth_format::z24s8: return 4; + } + throw EXCEPTION("Unknow depth format"); + } +} + GLGSRender::GLGSRender() : GSRender(frame_type::OpenGL) { shaders_cache.load(rsx::shader_language::glsl); @@ -97,7 +120,7 @@ void GLGSRender::begin() __glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a); - if (m_surface.color_format == CELL_GCM_SURFACE_F_W16Z16Y16X16) //TODO: check another color formats + if (m_surface.color_format == Surface_color_format::w16z16y16x16) //TODO: check another color formats { u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2]; @@ -654,8 +677,8 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) if (arg & 0x1) { - u32 surface_depth_format = (rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7; - u32 max_depth_value = surface_depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff; + Surface_depth_format surface_depth_format = to_surface_depth_format((rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7); + u32 max_depth_value = get_max_depth_value(surface_depth_format); u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; @@ -832,52 +855,52 @@ struct color_format color_swizzle swizzle; }; -color_format surface_color_format_to_gl(int color_format) +color_format surface_color_format_to_gl(Surface_color_format color_format) { //color format switch (color_format) { - case CELL_GCM_SURFACE_R5G6B5: + case Surface_color_format::r5g6b5: return{ gl::texture::type::ushort_5_6_5, gl::texture::format::bgr, false, 3, 2 }; - case CELL_GCM_SURFACE_A8R8G8B8: + case Surface_color_format::a8r8g8b8: return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 }; - case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: + case Surface_color_format::x8r8g8b8_o8r8g8b8: return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1, { gl::texture::channel::one, gl::texture::channel::r, gl::texture::channel::g, gl::texture::channel::b } }; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: + case Surface_color_format::w16z16y16x16: return{ gl::texture::type::f16, gl::texture::format::rgba, true, 4, 2 }; - case CELL_GCM_SURFACE_F_W32Z32Y32X32: + case Surface_color_format::w32z32y32x32: return{ gl::texture::type::f32, gl::texture::format::rgba, true, 4, 4 }; - case CELL_GCM_SURFACE_B8: - case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: - case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: - case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: - case CELL_GCM_SURFACE_G8B8: - case CELL_GCM_SURFACE_F_X32: - case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: - case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: - case CELL_GCM_SURFACE_A8B8G8R8: + case Surface_color_format::b8: + case Surface_color_format::x1r5g5b5_o1r5g5b5: + case Surface_color_format::x1r5g5b5_z1r5g5b5: + case Surface_color_format::x8r8g8b8_z8r8g8b8: + case Surface_color_format::g8b8: + case Surface_color_format::x32: + case Surface_color_format::x8b8g8r8_o8b8g8r8: + case Surface_color_format::x8b8g8r8_z8b8g8r8: + case Surface_color_format::a8b8g8r8: default: LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 }; } } -std::pair surface_depth_format_to_gl(int depth_format) +std::pair surface_depth_format_to_gl(Surface_depth_format depth_format) { switch (depth_format) { - case CELL_GCM_SURFACE_Z16: + case Surface_depth_format::z16: return std::make_pair(gl::texture::type::ushort, gl::texture::format::depth); default: LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", depth_format); - case CELL_GCM_SURFACE_Z24S8: + case Surface_depth_format::z24s8: return std::make_pair(gl::texture::type::uint_24_8, gl::texture::format::depth_stencil); //return std::make_pair(gl::texture::type::f32, gl::texture::format::depth); } @@ -926,7 +949,7 @@ void GLGSRender::init_buffers(bool skip_reading) switch (m_surface.depth_format) { - case CELL_GCM_SURFACE_Z16: + case Surface_depth_format::z16: { __glcheck m_draw_tex_depth_stencil.config() .size({ (int)m_surface.width, (int)m_surface.height }) @@ -938,7 +961,7 @@ void GLGSRender::init_buffers(bool skip_reading) break; } - case CELL_GCM_SURFACE_Z24S8: + case Surface_depth_format::z24s8: { __glcheck m_draw_tex_depth_stencil.config() .size({ (int)m_surface.width, (int)m_surface.height }) @@ -950,9 +973,6 @@ void GLGSRender::init_buffers(bool skip_reading) break; } - case 0: - break; - default: { LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface.depth_format); @@ -972,27 +992,27 @@ void GLGSRender::init_buffers(bool skip_reading) set_viewport(); - switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - case CELL_GCM_SURFACE_TARGET_NONE: break; + case Surface_target::none: break; - case CELL_GCM_SURFACE_TARGET_0: + case Surface_target::surface_a: __glcheck draw_fbo.draw_buffer(draw_fbo.color[0]); break; - case CELL_GCM_SURFACE_TARGET_1: + case Surface_target::surface_b: __glcheck draw_fbo.draw_buffer(draw_fbo.color[1] ); break; - case CELL_GCM_SURFACE_TARGET_MRT1: + case Surface_target::surfaces_a_b: __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1] }); break; - case CELL_GCM_SURFACE_TARGET_MRT2: + case Surface_target::surfaces_a_b_c: __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2] }); break; - case CELL_GCM_SURFACE_TARGET_MRT3: + case Surface_target::surfaces_a_b_c_d: __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2], draw_fbo.color[3] }); break; @@ -1070,28 +1090,28 @@ void GLGSRender::read_buffers() } }; - switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - case CELL_GCM_SURFACE_TARGET_NONE: + case Surface_target::none: break; - case CELL_GCM_SURFACE_TARGET_0: + case Surface_target::surface_a: read_color_buffers(0, 1); break; - case CELL_GCM_SURFACE_TARGET_1: + case Surface_target::surface_b: read_color_buffers(1, 1); break; - case CELL_GCM_SURFACE_TARGET_MRT1: + case Surface_target::surfaces_a_b: read_color_buffers(0, 2); break; - case CELL_GCM_SURFACE_TARGET_MRT2: + case Surface_target::surfaces_a_b_c: read_color_buffers(0, 3); break; - case CELL_GCM_SURFACE_TARGET_MRT3: + case Surface_target::surfaces_a_b_c_d: read_color_buffers(0, 4); break; } @@ -1107,8 +1127,7 @@ void GLGSRender::read_buffers() auto depth_format = surface_depth_format_to_gl(m_surface.depth_format); - int pixel_size = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 2 : 4; - + int pixel_size = get_pixel_size(m_surface.depth_format); gl::buffer pbo_depth; __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); @@ -1116,7 +1135,7 @@ void GLGSRender::read_buffers() { u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); - if (m_surface.depth_format == CELL_GCM_SURFACE_Z16) + if (m_surface.depth_format == Surface_depth_format::z16) { u16 *dst = (u16*)pixels; const be_t* src = vm::ps3::_ptr(depth_address); @@ -1202,28 +1221,28 @@ void GLGSRender::write_buffers() } }; - switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - case CELL_GCM_SURFACE_TARGET_NONE: + case Surface_target::none: break; - case CELL_GCM_SURFACE_TARGET_0: + case Surface_target::surface_a: write_color_buffers(0, 1); break; - case CELL_GCM_SURFACE_TARGET_1: + case Surface_target::surface_b: write_color_buffers(1, 1); break; - case CELL_GCM_SURFACE_TARGET_MRT1: + case Surface_target::surfaces_a_b: write_color_buffers(0, 2); break; - case CELL_GCM_SURFACE_TARGET_MRT2: + case Surface_target::surfaces_a_b_c: write_color_buffers(0, 3); break; - case CELL_GCM_SURFACE_TARGET_MRT3: + case Surface_target::surfaces_a_b_c_d: write_color_buffers(0, 4); break; } @@ -1241,7 +1260,7 @@ void GLGSRender::write_buffers() gl::buffer pbo_depth; - int pixel_size = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 2 : 4; + int pixel_size = get_pixel_size(m_surface.depth_format); __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); __glcheck m_draw_tex_depth_stencil.copy_to(pbo_depth, depth_format.second, depth_format.first); @@ -1250,7 +1269,7 @@ void GLGSRender::write_buffers() { u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); - if (m_surface.depth_format == CELL_GCM_SURFACE_Z16) + if (m_surface.depth_format == Surface_depth_format::z16) { const u16 *src = (const u16*)pixels; be_t* dst = vm::ps3::_ptr(depth_address); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 2ae9725017..0bc8ddabe1 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -278,21 +278,21 @@ namespace rsx int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; size_t pitch = clip_w * 4; std::vector color_index_to_record; - switch (method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + switch (to_surface_target(method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) { - case CELL_GCM_SURFACE_TARGET_0: + case Surface_target::surface_a: color_index_to_record = { 0 }; break; - case CELL_GCM_SURFACE_TARGET_1: + case Surface_target::surface_b: color_index_to_record = { 1 }; break; - case CELL_GCM_SURFACE_TARGET_MRT1: + case Surface_target::surfaces_a_b: color_index_to_record = { 0, 1 }; break; - case CELL_GCM_SURFACE_TARGET_MRT2: + case Surface_target::surfaces_a_b_c: color_index_to_record = { 0, 1, 2 }; break; - case CELL_GCM_SURFACE_TARGET_MRT3: + case Surface_target::surfaces_a_b_c_d: color_index_to_record = { 0, 1, 2, 3 }; break; } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index c92549e59d..0e49853c63 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -167,9 +167,9 @@ namespace rsx { u8 log2height; u8 log2width; - u8 antialias; - u8 depth_format; - u8 color_format; + Surface_antialiasing antialias; + Surface_depth_format depth_format; + Surface_color_format color_format; u32 width; u32 height; @@ -181,9 +181,9 @@ namespace rsx log2height = surface_format >> 24; log2width = (surface_format >> 16) & 0xff; - antialias = (surface_format >> 12) & 0xf; - depth_format = (surface_format >> 5) & 0x7; - color_format = surface_format & 0x1f; + antialias = to_surface_antialiasing((surface_format >> 12) & 0xf); + depth_format = to_surface_depth_format((surface_format >> 5) & 0x7); + color_format = to_surface_color_format(surface_format & 0x1f); width = 1 << (u32(log2width) + 1); height = 1 << (u32(log2width) + 1); diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 10e4b3328f..2502985fbc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -267,12 +267,12 @@ u8 GcmSurfaceFormat2GcmTextureFormat(u8 surfaceFormat, u8 surfaceType) { u8 result = 0; - switch (surfaceFormat) + switch (to_surface_color_format(surfaceFormat)) { - case CELL_GCM_SURFACE_A8R8G8B8: + case Surface_color_format::a8r8g8b8: result = CELL_GCM_TEXTURE_A8R8G8B8; break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: + case Surface_color_format::w16z16y16x16: result = CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT; break; default: @@ -933,15 +933,15 @@ s32 cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptrcolorFormat, gcmSurface->type); s32 xW = 1, xH = 1; - switch(gcmSurface->antialias) + switch(to_surface_antialiasing(gcmSurface->antialias)) { - case CELL_GCM_SURFACE_SQUARE_ROTATED_4: + case Surface_antialiasing::square_rotated_4_samples: xW=xH=2; break; - case CELL_GCM_SURFACE_SQUARE_CENTERED_4: + case Surface_antialiasing::square_centered_4_samples: xW=xH=2; break; - case CELL_GCM_SURFACE_DIAGONAL_CENTERED_2: + case Surface_antialiasing::diagonal_centered_2_samples: xW=2; break; default: