206 lines
6.1 KiB
C++
206 lines
6.1 KiB
C++
/* Copyright (c) 2019-2025, Arm Limited and Contributors
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 the "License";
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "resource_replay.h"
|
|
|
|
#include "common/vk_common.h"
|
|
#include "core/util/logging.hpp"
|
|
#include "rendering/pipeline_state.h"
|
|
#include "resource_cache.h"
|
|
|
|
namespace vkb
|
|
{
|
|
namespace
|
|
{
|
|
inline void read_subpass_info(std::istringstream &is, std::vector<SubpassInfo> &value)
|
|
{
|
|
std::size_t size;
|
|
read(is, size);
|
|
value.resize(size);
|
|
for (SubpassInfo &subpass : value)
|
|
{
|
|
read(is, subpass.input_attachments);
|
|
read(is, subpass.output_attachments);
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ResourceReplay::ResourceReplay()
|
|
{
|
|
stream_resources[ResourceType::ShaderModule] = std::bind(&ResourceReplay::create_shader_module, this, std::placeholders::_1, std::placeholders::_2);
|
|
stream_resources[ResourceType::PipelineLayout] = std::bind(&ResourceReplay::create_pipeline_layout, this, std::placeholders::_1, std::placeholders::_2);
|
|
stream_resources[ResourceType::RenderPass] = std::bind(&ResourceReplay::create_render_pass, this, std::placeholders::_1, std::placeholders::_2);
|
|
stream_resources[ResourceType::GraphicsPipeline] = std::bind(&ResourceReplay::create_graphics_pipeline, this, std::placeholders::_1, std::placeholders::_2);
|
|
}
|
|
|
|
void ResourceReplay::play(ResourceCache &resource_cache, ResourceRecord &recorder)
|
|
{
|
|
std::istringstream stream{recorder.get_stream().str()};
|
|
|
|
while (true)
|
|
{
|
|
// Read command id
|
|
ResourceType resource_type;
|
|
read(stream, resource_type);
|
|
|
|
if (stream.eof())
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Find command function for the given command id
|
|
auto cmd_it = stream_resources.find(resource_type);
|
|
|
|
// Check if command replayer supports the given command
|
|
if (cmd_it != stream_resources.end())
|
|
{
|
|
// Run command function
|
|
cmd_it->second(resource_cache, stream);
|
|
}
|
|
else
|
|
{
|
|
LOGE("Replay command not supported.");
|
|
}
|
|
}
|
|
}
|
|
|
|
void ResourceReplay::create_shader_module(ResourceCache &resource_cache, std::istringstream &stream)
|
|
{
|
|
VkShaderStageFlagBits stage{};
|
|
std::string glsl_source;
|
|
std::string entry_point;
|
|
|
|
read(stream,
|
|
stage,
|
|
glsl_source,
|
|
entry_point);
|
|
|
|
ShaderSource shader_source{};
|
|
shader_source.set_source(std::move(glsl_source));
|
|
ShaderVariant shader_variant;
|
|
|
|
auto &shader_module = resource_cache.request_shader_module(stage, shader_source, shader_variant);
|
|
|
|
shader_modules.push_back(&shader_module);
|
|
}
|
|
|
|
void ResourceReplay::create_pipeline_layout(ResourceCache &resource_cache, std::istringstream &stream)
|
|
{
|
|
std::vector<size_t> shader_indices;
|
|
|
|
read(stream,
|
|
shader_indices);
|
|
|
|
std::vector<ShaderModule *> shader_stages(shader_indices.size());
|
|
std::transform(shader_indices.begin(),
|
|
shader_indices.end(),
|
|
shader_stages.begin(),
|
|
[&](size_t shader_index) {
|
|
assert(shader_index < shader_modules.size());
|
|
return shader_modules[shader_index];
|
|
});
|
|
|
|
auto &pipeline_layout = resource_cache.request_pipeline_layout(shader_stages);
|
|
|
|
pipeline_layouts.push_back(&pipeline_layout);
|
|
}
|
|
|
|
void ResourceReplay::create_render_pass(ResourceCache &resource_cache, std::istringstream &stream)
|
|
{
|
|
std::vector<Attachment> attachments;
|
|
std::vector<LoadStoreInfo> load_store_infos;
|
|
std::vector<SubpassInfo> subpasses;
|
|
|
|
read(stream,
|
|
attachments,
|
|
load_store_infos);
|
|
|
|
read_subpass_info(stream, subpasses);
|
|
|
|
auto &render_pass = resource_cache.request_render_pass(attachments, load_store_infos, subpasses);
|
|
|
|
render_passes.push_back(&render_pass);
|
|
}
|
|
|
|
void ResourceReplay::create_graphics_pipeline(ResourceCache &resource_cache, std::istringstream &stream)
|
|
{
|
|
size_t pipeline_layout_index{};
|
|
size_t render_pass_index{};
|
|
uint32_t subpass_index{};
|
|
|
|
read(stream,
|
|
pipeline_layout_index,
|
|
render_pass_index,
|
|
subpass_index);
|
|
|
|
std::map<uint32_t, std::vector<uint8_t>> specialization_constant_state{};
|
|
read(stream,
|
|
specialization_constant_state);
|
|
|
|
VertexInputState vertex_input_state{};
|
|
|
|
read(stream,
|
|
vertex_input_state.attributes,
|
|
vertex_input_state.bindings);
|
|
|
|
InputAssemblyState input_assembly_state{};
|
|
RasterizationState rasterization_state{};
|
|
ViewportState viewport_state{};
|
|
MultisampleState multisample_state{};
|
|
DepthStencilState depth_stencil_state{};
|
|
|
|
read(stream,
|
|
input_assembly_state,
|
|
rasterization_state,
|
|
viewport_state,
|
|
multisample_state,
|
|
depth_stencil_state);
|
|
|
|
ColorBlendState color_blend_state{};
|
|
|
|
read(stream,
|
|
color_blend_state.logic_op,
|
|
color_blend_state.logic_op_enable,
|
|
color_blend_state.attachments);
|
|
|
|
PipelineState pipeline_state{};
|
|
assert(pipeline_layout_index < pipeline_layouts.size());
|
|
pipeline_state.set_pipeline_layout(*pipeline_layouts[pipeline_layout_index]);
|
|
assert(render_pass_index < render_passes.size());
|
|
pipeline_state.set_render_pass(*render_passes[render_pass_index]);
|
|
|
|
for (auto &item : specialization_constant_state)
|
|
{
|
|
pipeline_state.set_specialization_constant(item.first, item.second);
|
|
}
|
|
|
|
pipeline_state.set_subpass_index(subpass_index);
|
|
pipeline_state.set_vertex_input_state(vertex_input_state);
|
|
pipeline_state.set_input_assembly_state(input_assembly_state);
|
|
pipeline_state.set_rasterization_state(rasterization_state);
|
|
pipeline_state.set_viewport_state(viewport_state);
|
|
pipeline_state.set_multisample_state(multisample_state);
|
|
pipeline_state.set_depth_stencil_state(depth_stencil_state);
|
|
pipeline_state.set_color_blend_state(color_blend_state);
|
|
|
|
auto &graphics_pipeline = resource_cache.request_graphics_pipeline(pipeline_state);
|
|
|
|
graphics_pipelines.push_back(&graphics_pipeline);
|
|
}
|
|
} // namespace vkb
|