Пример #1
0
std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer_for_emulated_primitives_array(const std::vector<std::pair<u32, u32> > &vertex_ranges)
{
	size_t index_count = 0;
	for (const auto &pair : vertex_ranges)
		index_count += get_index_count(draw_mode, pair.second);

	// Alloc
	size_t buffer_size = align(index_count * sizeof(u16), 64);
	size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);

	void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
	size_t first = 0;
	for (const auto &pair : vertex_ranges)
	{
		size_t element_count = get_index_count(draw_mode, pair.second);
		write_index_array_for_non_indexed_non_native_primitive_to_buffer((char*)mapped_buffer, draw_mode, (u32)first, (u32)pair.second);
		mapped_buffer = (char*)mapped_buffer + element_count * sizeof(u16);
		first += pair.second;
	}
	m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
	D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
		m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
		(UINT)buffer_size,
		DXGI_FORMAT_R16_UINT
	};

	return std::make_tuple(index_buffer_view, index_count);
}
Пример #2
0
			inline void set_index_data(const Uint32 index,
				const Uint32 data)
			{
				assert(index < get_index_count());
				assert((data < get_vertex_count()) ||
					((get_restart_index() == data) &&
						get_use_restart_index()));
				assert(index < m_indices.size());
				assert(get_index_count() == m_indices.size());

				m_indices[index] = data;

				assert(m_indices[index] == data);
			}
Пример #3
0
			inline Uint32 get_index_data(const Uint32 index) const
			{
				assert(index < get_index_count());

				return m_indexes[index];
			}
Пример #4
0
			inline void set_index_data(const Uint32 index, const Uint32 data)
			{
				assert(index < get_index_count());

				m_indexes[index] = data;
			}
Пример #5
0
std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list)
{
	if (draw_command == rsx::draw_command::inlined_array)
	{
		size_t vertex_count;
		std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> vertex_buffer_view;
		std::tie(vertex_buffer_view, vertex_count) = upload_inlined_vertex_array(
			vertex_arrays_info,
			{ (const gsl::byte*) inline_vertex_array.data(), gsl::narrow<int>(inline_vertex_array.size() * sizeof(uint)) },
			m_buffer_data, m_vertex_buffer_data.Get(), command_list);

		if (is_primitive_native(draw_mode))
			return std::make_tuple(false, vertex_count, vertex_buffer_view);

		D3D12_INDEX_BUFFER_VIEW index_buffer_view;
		size_t index_count;
		std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array({ { 0, (u32)vertex_count } });
		command_list->IASetIndexBuffer(&index_buffer_view);
		return std::make_tuple(true, index_count, vertex_buffer_view);
	}

	if (draw_command == rsx::draw_command::array)
	{
		if (is_primitive_native(draw_mode))
		{
			size_t vertex_count = get_vertex_count(first_count_commands);
			return std::make_tuple(false, vertex_count, upload_vertex_attributes(first_count_commands, command_list));
		}

		D3D12_INDEX_BUFFER_VIEW index_buffer_view;
		size_t index_count;
		std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array(first_count_commands);
		command_list->IASetIndexBuffer(&index_buffer_view);
		return std::make_tuple(true, index_count, upload_vertex_attributes(first_count_commands, command_list));
	}

	assert(draw_command == rsx::draw_command::indexed);

	// Index count
	size_t index_count = get_index_count(draw_mode, gsl::narrow<int>(get_vertex_count(first_count_commands)));

	rsx::index_array_type indexed_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
	size_t index_size = get_index_type_size(indexed_type);

	// Alloc
	size_t buffer_size = align(index_count * index_size, 64);
	size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);

	void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
	u32 min_index, max_index;

	if (indexed_type == rsx::index_array_type::u16)
	{
		gsl::span<u16> dst = { (u16*)mapped_buffer, gsl::narrow<int>(buffer_size / index_size) };
		std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, draw_mode, first_count_commands);
	}

	if (indexed_type == rsx::index_array_type::u32)
	{
		gsl::span<u32> dst = { (u32*)mapped_buffer, gsl::narrow<int>(buffer_size / index_size) };
		std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, draw_mode, first_count_commands);
	}

	m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
	D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
		m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
		(UINT)buffer_size,
		get_index_type(indexed_type)
	};
	m_timers.buffer_upload_size += buffer_size;
	command_list->IASetIndexBuffer(&index_buffer_view);

	return std::make_tuple(true, index_count, upload_vertex_attributes({ std::make_pair(0, max_index + 1) }, command_list));
}