Esempio n. 1
0
static void* remap(puint_t phys_address) {
    if (phys_address < 0x200000)
        return (void*)phys_address;

    uintptr_t map_address = (uintptr_t)_frame_block;
    puint_t* paddress = get_page(map_address, get_active_page(), false);

    page_t page;
    memset(&page, 0, sizeof(page_t));
    page.address = ALIGN(phys_address);
    page.flaggable.present = 1;
    page.flaggable.rw = 1;
    page.flaggable.us = 0;
    *paddress = page.address;

    paddress = get_page(map_address+0x1000, get_active_page(), false);
    memset(&page, 0, sizeof(page_t));
    page.address = ALIGN(phys_address) + 0x1000;
    page.flaggable.present = 1;
    page.flaggable.rw = 1;
    page.flaggable.us = 0;
    *paddress = page.address;

    invalidate_address((void*)map_address);
    invalidate_address((void*)(map_address+0x1000));

    return (void*)(map_address+(phys_address-ALIGN(phys_address)));
}
Esempio n. 2
0
bool D3D12GSRender::on_access_violation(u32 address, bool is_writing)
{
	if (!is_writing)
	{
		return false;
	}

	if (invalidate_address(address))
	{
		LOG_WARNING(RSX, "Reporting Cell writing to 0x%x", address);
		return true;
	}

	return false;
}
Esempio n. 3
0
void D3D12GSRender::copy_render_target_to_dma_location()
{
	// Add all buffer write
	// Cell can't make any assumption about readyness of color/depth buffer
	// Except when a semaphore is written by RSX
	int clip_w = rsx::method_registers.surface_clip_width();
	int clip_h = rsx::method_registers.surface_clip_height();

	size_t depth_row_pitch = align(clip_w * 4, 256);
	size_t depth_buffer_offset_in_heap = 0;


	u32 address_color[] =
	{
		rsx::get_address(rsx::method_registers.surface_a_offset(), rsx::method_registers.surface_a_dma()),
		rsx::get_address(rsx::method_registers.surface_b_offset(), rsx::method_registers.surface_b_dma()),
		rsx::get_address(rsx::method_registers.surface_c_offset(), rsx::method_registers.surface_c_dma()),
		rsx::get_address(rsx::method_registers.surface_d_offset(), rsx::method_registers.surface_d_dma()),
	};
	u32 address_z = rsx::get_address(rsx::method_registers.surface_z_offset(), rsx::method_registers.surface_z_dma());

	bool need_transfer = false;

	if (rsx::method_registers.surface_z_dma() && g_cfg_rsx_write_depth_buffer)
	{
		get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE));
		get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { depth_buffer_offset_in_heap,{ DXGI_FORMAT_R32_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0,
			&CD3DX12_TEXTURE_COPY_LOCATION(std::get<1>(m_rtts.m_bound_depth_stencil), 0), nullptr);
		get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE));
		invalidate_address(address_z);

		need_transfer = true;
	}

	size_t color_buffer_offset_in_heap[4];
	if (g_cfg_rsx_write_color_buffers)
	{
		for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target()))
		{
			if (!address_color[i])
				continue;
			color_buffer_offset_in_heap[i] = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, std::get<1>(m_rtts.m_bound_render_targets[i]), rsx::method_registers.surface_color());
			invalidate_address(address_color[i]);
			need_transfer = true;
		}
	}
	if (need_transfer)
	{
		CHECK_HRESULT(get_current_resource_storage().command_list->Close());
		m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
		get_current_resource_storage().set_new_command_list();
	}

	//Wait for result
	wait_for_command_queue(m_device.Get(), m_command_queue.Get());

	if (address_z && g_cfg_rsx_write_depth_buffer)
	{
		auto ptr = vm::base(address_z);
		char *depth_buffer = (char*)ptr;
		u8 *mapped_buffer = m_readback_resources.map<u8>(depth_buffer_offset_in_heap);

		for (unsigned row = 0; row < (unsigned)clip_h; row++)
		{
			for (unsigned i = 0; i < (unsigned)clip_w; i++)
			{
				unsigned char c = mapped_buffer[row * depth_row_pitch + i];
				depth_buffer[4 * (row * clip_w + i)] = c;
				depth_buffer[4 * (row * clip_w + i) + 1] = c;
				depth_buffer[4 * (row * clip_w + i) + 2] = c;
				depth_buffer[4 * (row * clip_w + i) + 3] = c;
			}
		}
		m_readback_resources.unmap();
	}

	if (g_cfg_rsx_write_color_buffers)
	{
		size_t srcPitch = get_aligned_pitch(rsx::method_registers.surface_color(), clip_w);
		size_t dstPitch = get_packed_pitch(rsx::method_registers.surface_color(), clip_w);

		void *dest_buffer[] =
		{
			vm::base(address_color[0]),
			vm::base(address_color[1]),
			vm::base(address_color[2]),
			vm::base(address_color[3]),
		};

		for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target()))
		{
			if (!address_color[i])
				continue;
			copy_readback_buffer_to_dest(dest_buffer[i], m_readback_resources, color_buffer_offset_in_heap[i], srcPitch, dstPitch, clip_h);
		}
	}
}