void thread::capture_frame(const std::string &name) { frame_capture_data::draw_state draw_state = {}; int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; rsx::surface_info surface = {}; surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]); draw_state.width = clip_w; draw_state.height = clip_h; draw_state.color_format = surface.color_format; draw_state.color_buffer = std::move(copy_render_targets_to_memory()); draw_state.depth_format = surface.depth_format; draw_state.depth_stencil = std::move(copy_depth_stencil_buffer_to_memory()); if (draw_command == rsx::draw_command::indexed) { draw_state.vertex_count = 0; for (const auto &range : first_count_commands) { draw_state.vertex_count += range.second; } draw_state.index_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); if (draw_state.index_type == rsx::index_array_type::u16) { draw_state.index.resize(2 * draw_state.vertex_count); } if (draw_state.index_type == rsx::index_array_type::u32) { draw_state.index.resize(4 * draw_state.vertex_count); } gsl::span<gsl::byte> dst = { (gsl::byte*)draw_state.index.data(), gsl::narrow<int>(draw_state.index.size()) }; write_index_array_data_to_buffer(dst, draw_state.index_type, draw_mode, first_count_commands); }
void thread::capture_frame(const std::string &name) { frame_capture_data::draw_state draw_state = {}; int clip_w = rsx::method_registers.surface_clip_width(); int clip_h = rsx::method_registers.surface_clip_height(); draw_state.width = clip_w; draw_state.height = clip_h; draw_state.color_format = rsx::method_registers.surface_color(); draw_state.color_buffer = std::move(copy_render_targets_to_memory()); draw_state.depth_format = rsx::method_registers.surface_depth_fmt(); draw_state.depth_stencil = std::move(copy_depth_stencil_buffer_to_memory()); if (draw_command == rsx::draw_command::indexed) { draw_state.vertex_count = 0; for (const auto &range : first_count_commands) { draw_state.vertex_count += range.second; } draw_state.index_type = rsx::method_registers.index_type(); if (draw_state.index_type == rsx::index_array_type::u16) { draw_state.index.resize(2 * draw_state.vertex_count); } if (draw_state.index_type == rsx::index_array_type::u32) { draw_state.index.resize(4 * draw_state.vertex_count); } gsl::span<gsl::byte> dst = { (gsl::byte*)draw_state.index.data(), gsl::narrow<int>(draw_state.index.size()) }; write_index_array_data_to_buffer(dst, draw_state.index_type, draw_mode, first_count_commands); } draw_state.programs = get_programs(); draw_state.name = name; frame_debug.draw_calls.push_back(draw_state); }
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)); }