Merge branch 'master' into linux_windowing
This commit is contained in:
@@ -120,7 +120,7 @@ VkResult BufferCache::Initialize() {
|
||||
|
||||
// Create a memory allocator for textures.
|
||||
VmaVulkanFunctions vulkan_funcs = {};
|
||||
ui::vulkan::FillVMAVulkanFunctions(&vulkan_funcs);
|
||||
ui::vulkan::FillVMAVulkanFunctions(&vulkan_funcs, *device_);
|
||||
|
||||
VmaAllocatorCreateInfo alloc_info = {
|
||||
0, *device_, *device_, 0, 0, nullptr, nullptr, 0, nullptr, &vulkan_funcs,
|
||||
@@ -144,7 +144,8 @@ VkResult BufferCache::Initialize() {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult xe::gpu::vulkan::BufferCache::CreateVertexDescriptorPool() {
|
||||
VkResult BufferCache::CreateVertexDescriptorPool() {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status;
|
||||
|
||||
std::vector<VkDescriptorPoolSize> pool_sizes;
|
||||
@@ -170,8 +171,8 @@ VkResult xe::gpu::vulkan::BufferCache::CreateVertexDescriptorPool() {
|
||||
1,
|
||||
&binding,
|
||||
};
|
||||
status = vkCreateDescriptorSetLayout(*device_, &layout_info, nullptr,
|
||||
&vertex_descriptor_set_layout_);
|
||||
status = dfn.vkCreateDescriptorSetLayout(*device_, &layout_info, nullptr,
|
||||
&vertex_descriptor_set_layout_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -179,14 +180,16 @@ VkResult xe::gpu::vulkan::BufferCache::CreateVertexDescriptorPool() {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void xe::gpu::vulkan::BufferCache::FreeVertexDescriptorPool() {
|
||||
void BufferCache::FreeVertexDescriptorPool() {
|
||||
vertex_descriptor_pool_.reset();
|
||||
|
||||
VK_SAFE_DESTROY(vkDestroyDescriptorSetLayout, *device_,
|
||||
vertex_descriptor_set_layout_, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, *device_,
|
||||
vertex_descriptor_set_layout_);
|
||||
}
|
||||
|
||||
VkResult BufferCache::CreateConstantDescriptorSet() {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
|
||||
// Descriptor pool used for all of our cached descriptors.
|
||||
@@ -204,8 +207,8 @@ VkResult BufferCache::CreateConstantDescriptorSet() {
|
||||
pool_sizes[0].descriptorCount = 2;
|
||||
transient_descriptor_pool_info.poolSizeCount = 1;
|
||||
transient_descriptor_pool_info.pPoolSizes = pool_sizes;
|
||||
status = vkCreateDescriptorPool(*device_, &transient_descriptor_pool_info,
|
||||
nullptr, &constant_descriptor_pool_);
|
||||
status = dfn.vkCreateDescriptorPool(*device_, &transient_descriptor_pool_info,
|
||||
nullptr, &constant_descriptor_pool_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -237,9 +240,9 @@ VkResult BufferCache::CreateConstantDescriptorSet() {
|
||||
descriptor_set_layout_info.bindingCount =
|
||||
static_cast<uint32_t>(xe::countof(bindings));
|
||||
descriptor_set_layout_info.pBindings = bindings;
|
||||
status =
|
||||
vkCreateDescriptorSetLayout(*device_, &descriptor_set_layout_info,
|
||||
nullptr, &constant_descriptor_set_layout_);
|
||||
status = dfn.vkCreateDescriptorSetLayout(*device_,
|
||||
&descriptor_set_layout_info, nullptr,
|
||||
&constant_descriptor_set_layout_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -253,8 +256,8 @@ VkResult BufferCache::CreateConstantDescriptorSet() {
|
||||
set_alloc_info.descriptorPool = constant_descriptor_pool_;
|
||||
set_alloc_info.descriptorSetCount = 1;
|
||||
set_alloc_info.pSetLayouts = &constant_descriptor_set_layout_;
|
||||
status = vkAllocateDescriptorSets(*device_, &set_alloc_info,
|
||||
&constant_descriptor_set_);
|
||||
status = dfn.vkAllocateDescriptorSets(*device_, &set_alloc_info,
|
||||
&constant_descriptor_set_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -286,22 +289,24 @@ VkResult BufferCache::CreateConstantDescriptorSet() {
|
||||
fragment_uniform_binding_write.descriptorType =
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
||||
fragment_uniform_binding_write.pBufferInfo = &buffer_info;
|
||||
vkUpdateDescriptorSets(*device_, 2, descriptor_writes, 0, nullptr);
|
||||
dfn.vkUpdateDescriptorSets(*device_, 2, descriptor_writes, 0, nullptr);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void BufferCache::FreeConstantDescriptorSet() {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
if (constant_descriptor_set_) {
|
||||
vkFreeDescriptorSets(*device_, constant_descriptor_pool_, 1,
|
||||
&constant_descriptor_set_);
|
||||
dfn.vkFreeDescriptorSets(*device_, constant_descriptor_pool_, 1,
|
||||
&constant_descriptor_set_);
|
||||
constant_descriptor_set_ = nullptr;
|
||||
}
|
||||
|
||||
VK_SAFE_DESTROY(vkDestroyDescriptorSetLayout, *device_,
|
||||
constant_descriptor_set_layout_, nullptr);
|
||||
VK_SAFE_DESTROY(vkDestroyDescriptorPool, *device_, constant_descriptor_pool_,
|
||||
nullptr);
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyDescriptorSetLayout, *device_,
|
||||
constant_descriptor_set_layout_);
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyDescriptorPool, *device_,
|
||||
constant_descriptor_pool_);
|
||||
}
|
||||
|
||||
void BufferCache::Shutdown() {
|
||||
@@ -314,7 +319,9 @@ void BufferCache::Shutdown() {
|
||||
FreeVertexDescriptorPool();
|
||||
|
||||
transient_buffer_->Shutdown();
|
||||
VK_SAFE_DESTROY(vkFreeMemory, *device_, gpu_memory_pool_, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkFreeMemory, *device_,
|
||||
gpu_memory_pool_);
|
||||
}
|
||||
|
||||
std::pair<VkDeviceSize, VkDeviceSize> BufferCache::UploadConstantRegisters(
|
||||
@@ -361,9 +368,10 @@ std::pair<VkDeviceSize, VkDeviceSize> BufferCache::UploadConstantRegisters(
|
||||
offset,
|
||||
kConstantRegisterUniformRange,
|
||||
};
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
|
||||
return {offset, offset};
|
||||
|
||||
@@ -476,9 +484,10 @@ std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadIndexBuffer(
|
||||
offset,
|
||||
source_length,
|
||||
};
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
|
||||
return {transient_buffer_->gpu_buffer(), offset};
|
||||
}
|
||||
@@ -543,9 +552,10 @@ std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadVertexBuffer(
|
||||
offset,
|
||||
upload_size,
|
||||
};
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
|
||||
1, &barrier, 0, nullptr);
|
||||
|
||||
CacheTransientData(upload_base, upload_size, offset);
|
||||
return {transient_buffer_->gpu_buffer(), offset + source_offset};
|
||||
@@ -687,7 +697,8 @@ VkDescriptorSet BufferCache::PrepareVertexSet(
|
||||
};
|
||||
}
|
||||
|
||||
vkUpdateDescriptorSets(*device_, 1, &descriptor_write, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkUpdateDescriptorSets(*device_, 1, &descriptor_write, 0, nullptr);
|
||||
vertex_sets_[hash] = set;
|
||||
return set;
|
||||
}
|
||||
@@ -760,13 +771,15 @@ void BufferCache::CacheTransientData(uint32_t guest_address,
|
||||
}
|
||||
|
||||
void BufferCache::Flush(VkCommandBuffer command_buffer) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// If we are flushing a big enough chunk queue up an event.
|
||||
// We don't want to do this for everything but often enough so that we won't
|
||||
// run out of space.
|
||||
if (true) {
|
||||
// VkEvent finish_event;
|
||||
// vkCmdSetEvent(cmd_buffer, finish_event,
|
||||
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
|
||||
// dfn.vkCmdSetEvent(cmd_buffer, finish_event,
|
||||
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
|
||||
}
|
||||
|
||||
// Flush memory.
|
||||
@@ -777,7 +790,7 @@ void BufferCache::Flush(VkCommandBuffer command_buffer) {
|
||||
dirty_range.memory = transient_buffer_->gpu_memory();
|
||||
dirty_range.offset = 0;
|
||||
dirty_range.size = transient_buffer_->capacity();
|
||||
vkFlushMappedMemoryRanges(*device_, 1, &dirty_range);
|
||||
dfn.vkFlushMappedMemoryRanges(*device_, 1, &dirty_range);
|
||||
}
|
||||
|
||||
void BufferCache::InvalidateCache() {
|
||||
|
||||
@@ -45,6 +45,7 @@ VkResult PipelineCache::Initialize(
|
||||
VkDescriptorSetLayout uniform_descriptor_set_layout,
|
||||
VkDescriptorSetLayout texture_descriptor_set_layout,
|
||||
VkDescriptorSetLayout vertex_descriptor_set_layout) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status;
|
||||
|
||||
// Initialize the shared driver pipeline cache.
|
||||
@@ -57,8 +58,8 @@ VkResult PipelineCache::Initialize(
|
||||
pipeline_cache_info.flags = 0;
|
||||
pipeline_cache_info.initialDataSize = 0;
|
||||
pipeline_cache_info.pInitialData = nullptr;
|
||||
status = vkCreatePipelineCache(*device_, &pipeline_cache_info, nullptr,
|
||||
&pipeline_cache_);
|
||||
status = dfn.vkCreatePipelineCache(*device_, &pipeline_cache_info, nullptr,
|
||||
&pipeline_cache_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -95,8 +96,8 @@ VkResult PipelineCache::Initialize(
|
||||
pipeline_layout_info.pushConstantRangeCount =
|
||||
static_cast<uint32_t>(xe::countof(push_constant_ranges));
|
||||
pipeline_layout_info.pPushConstantRanges = push_constant_ranges;
|
||||
status = vkCreatePipelineLayout(*device_, &pipeline_layout_info, nullptr,
|
||||
&pipeline_layout_);
|
||||
status = dfn.vkCreatePipelineLayout(*device_, &pipeline_layout_info, nullptr,
|
||||
&pipeline_layout_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -112,8 +113,8 @@ VkResult PipelineCache::Initialize(
|
||||
static_cast<uint32_t>(sizeof(line_quad_list_geom));
|
||||
shader_module_info.pCode =
|
||||
reinterpret_cast<const uint32_t*>(line_quad_list_geom);
|
||||
status = vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.line_quad_list);
|
||||
status = dfn.vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.line_quad_list);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -123,8 +124,8 @@ VkResult PipelineCache::Initialize(
|
||||
|
||||
shader_module_info.codeSize = static_cast<uint32_t>(sizeof(point_list_geom));
|
||||
shader_module_info.pCode = reinterpret_cast<const uint32_t*>(point_list_geom);
|
||||
status = vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.point_list);
|
||||
status = dfn.vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.point_list);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -134,8 +135,8 @@ VkResult PipelineCache::Initialize(
|
||||
|
||||
shader_module_info.codeSize = static_cast<uint32_t>(sizeof(quad_list_geom));
|
||||
shader_module_info.pCode = reinterpret_cast<const uint32_t*>(quad_list_geom);
|
||||
status = vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.quad_list);
|
||||
status = dfn.vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.quad_list);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -145,8 +146,8 @@ VkResult PipelineCache::Initialize(
|
||||
|
||||
shader_module_info.codeSize = static_cast<uint32_t>(sizeof(rect_list_geom));
|
||||
shader_module_info.pCode = reinterpret_cast<const uint32_t*>(rect_list_geom);
|
||||
status = vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.rect_list);
|
||||
status = dfn.vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&geometry_shaders_.rect_list);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -156,8 +157,8 @@ VkResult PipelineCache::Initialize(
|
||||
|
||||
shader_module_info.codeSize = static_cast<uint32_t>(sizeof(dummy_frag));
|
||||
shader_module_info.pCode = reinterpret_cast<const uint32_t*>(dummy_frag);
|
||||
status = vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&dummy_pixel_shader_);
|
||||
status = dfn.vkCreateShaderModule(*device_, &shader_module_info, nullptr,
|
||||
&dummy_pixel_shader_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -171,34 +172,37 @@ VkResult PipelineCache::Initialize(
|
||||
void PipelineCache::Shutdown() {
|
||||
ClearCache();
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// Destroy geometry shaders.
|
||||
if (geometry_shaders_.line_quad_list) {
|
||||
vkDestroyShaderModule(*device_, geometry_shaders_.line_quad_list, nullptr);
|
||||
dfn.vkDestroyShaderModule(*device_, geometry_shaders_.line_quad_list,
|
||||
nullptr);
|
||||
geometry_shaders_.line_quad_list = nullptr;
|
||||
}
|
||||
if (geometry_shaders_.point_list) {
|
||||
vkDestroyShaderModule(*device_, geometry_shaders_.point_list, nullptr);
|
||||
dfn.vkDestroyShaderModule(*device_, geometry_shaders_.point_list, nullptr);
|
||||
geometry_shaders_.point_list = nullptr;
|
||||
}
|
||||
if (geometry_shaders_.quad_list) {
|
||||
vkDestroyShaderModule(*device_, geometry_shaders_.quad_list, nullptr);
|
||||
dfn.vkDestroyShaderModule(*device_, geometry_shaders_.quad_list, nullptr);
|
||||
geometry_shaders_.quad_list = nullptr;
|
||||
}
|
||||
if (geometry_shaders_.rect_list) {
|
||||
vkDestroyShaderModule(*device_, geometry_shaders_.rect_list, nullptr);
|
||||
dfn.vkDestroyShaderModule(*device_, geometry_shaders_.rect_list, nullptr);
|
||||
geometry_shaders_.rect_list = nullptr;
|
||||
}
|
||||
if (dummy_pixel_shader_) {
|
||||
vkDestroyShaderModule(*device_, dummy_pixel_shader_, nullptr);
|
||||
dfn.vkDestroyShaderModule(*device_, dummy_pixel_shader_, nullptr);
|
||||
dummy_pixel_shader_ = nullptr;
|
||||
}
|
||||
|
||||
if (pipeline_layout_) {
|
||||
vkDestroyPipelineLayout(*device_, pipeline_layout_, nullptr);
|
||||
dfn.vkDestroyPipelineLayout(*device_, pipeline_layout_, nullptr);
|
||||
pipeline_layout_ = nullptr;
|
||||
}
|
||||
if (pipeline_cache_) {
|
||||
vkDestroyPipelineCache(*device_, pipeline_cache_, nullptr);
|
||||
dfn.vkDestroyPipelineCache(*device_, pipeline_cache_, nullptr);
|
||||
pipeline_cache_ = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -274,9 +278,10 @@ PipelineCache::UpdateStatus PipelineCache::ConfigurePipeline(
|
||||
}
|
||||
|
||||
void PipelineCache::ClearCache() {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
// Destroy all pipelines.
|
||||
for (auto it : cached_pipelines_) {
|
||||
vkDestroyPipeline(*device_, it.second, nullptr);
|
||||
dfn.vkDestroyPipeline(*device_, it.second, nullptr);
|
||||
}
|
||||
cached_pipelines_.clear();
|
||||
COUNT_profile_set("gpu/pipeline_cache/pipelines", 0);
|
||||
@@ -338,8 +343,9 @@ VkPipeline PipelineCache::GetPipeline(const RenderState* render_state,
|
||||
pipeline_info.basePipelineHandle = nullptr;
|
||||
pipeline_info.basePipelineIndex = -1;
|
||||
VkPipeline pipeline = nullptr;
|
||||
auto result = vkCreateGraphicsPipelines(*device_, pipeline_cache_, 1,
|
||||
&pipeline_info, nullptr, &pipeline);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto result = dfn.vkCreateGraphicsPipelines(
|
||||
*device_, pipeline_cache_, 1, &pipeline_info, nullptr, &pipeline);
|
||||
if (result != VK_SUCCESS) {
|
||||
XELOGE("vkCreateGraphicsPipelines failed with code {}", result);
|
||||
assert_always();
|
||||
@@ -415,9 +421,7 @@ static void DumpShaderStatisticsAMD(const VkShaderStatisticsInfoAMD& stats) {
|
||||
}
|
||||
|
||||
void PipelineCache::DumpShaderDisasmAMD(VkPipeline pipeline) {
|
||||
auto fn_GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)vkGetDeviceProcAddr(
|
||||
*device_, "vkGetShaderInfoAMD");
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
size_t data_size = 0;
|
||||
|
||||
@@ -425,18 +429,18 @@ void PipelineCache::DumpShaderDisasmAMD(VkPipeline pipeline) {
|
||||
data_size = sizeof(stats);
|
||||
|
||||
// Vertex shader
|
||||
status = fn_GetShaderInfoAMD(*device_, pipeline, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
VK_SHADER_INFO_TYPE_STATISTICS_AMD, &data_size,
|
||||
&stats);
|
||||
status = dfn.vkGetShaderInfoAMD(
|
||||
*device_, pipeline, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
VK_SHADER_INFO_TYPE_STATISTICS_AMD, &data_size, &stats);
|
||||
if (status == VK_SUCCESS) {
|
||||
XELOGI("AMD Vertex Shader Statistics:");
|
||||
DumpShaderStatisticsAMD(stats);
|
||||
}
|
||||
|
||||
// Fragment shader
|
||||
status = fn_GetShaderInfoAMD(*device_, pipeline, VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
VK_SHADER_INFO_TYPE_STATISTICS_AMD, &data_size,
|
||||
&stats);
|
||||
status = dfn.vkGetShaderInfoAMD(
|
||||
*device_, pipeline, VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
VK_SHADER_INFO_TYPE_STATISTICS_AMD, &data_size, &stats);
|
||||
if (status == VK_SUCCESS) {
|
||||
XELOGI("AMD Fragment Shader Statistics:");
|
||||
DumpShaderStatisticsAMD(stats);
|
||||
@@ -451,6 +455,8 @@ void PipelineCache::DumpShaderDisasmNV(
|
||||
// This code is super ugly. Update this when NVidia includes an official
|
||||
// way to dump shader disassembly.
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
VkPipelineCacheCreateInfo pipeline_cache_info;
|
||||
VkPipelineCache dummy_pipeline_cache;
|
||||
pipeline_cache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
||||
@@ -458,23 +464,24 @@ void PipelineCache::DumpShaderDisasmNV(
|
||||
pipeline_cache_info.flags = 0;
|
||||
pipeline_cache_info.initialDataSize = 0;
|
||||
pipeline_cache_info.pInitialData = nullptr;
|
||||
auto status = vkCreatePipelineCache(*device_, &pipeline_cache_info, nullptr,
|
||||
&dummy_pipeline_cache);
|
||||
auto status = dfn.vkCreatePipelineCache(*device_, &pipeline_cache_info,
|
||||
nullptr, &dummy_pipeline_cache);
|
||||
CheckResult(status, "vkCreatePipelineCache");
|
||||
|
||||
// Create a pipeline on the dummy cache and dump it.
|
||||
VkPipeline dummy_pipeline;
|
||||
status = vkCreateGraphicsPipelines(*device_, dummy_pipeline_cache, 1,
|
||||
&pipeline_info, nullptr, &dummy_pipeline);
|
||||
status =
|
||||
dfn.vkCreateGraphicsPipelines(*device_, dummy_pipeline_cache, 1,
|
||||
&pipeline_info, nullptr, &dummy_pipeline);
|
||||
|
||||
std::vector<uint8_t> pipeline_data;
|
||||
size_t data_size = 0;
|
||||
status = vkGetPipelineCacheData(*device_, dummy_pipeline_cache, &data_size,
|
||||
nullptr);
|
||||
status = dfn.vkGetPipelineCacheData(*device_, dummy_pipeline_cache,
|
||||
&data_size, nullptr);
|
||||
if (status == VK_SUCCESS) {
|
||||
pipeline_data.resize(data_size);
|
||||
vkGetPipelineCacheData(*device_, dummy_pipeline_cache, &data_size,
|
||||
pipeline_data.data());
|
||||
dfn.vkGetPipelineCacheData(*device_, dummy_pipeline_cache, &data_size,
|
||||
pipeline_data.data());
|
||||
|
||||
// Scan the data for the disassembly.
|
||||
std::string disasm_vp, disasm_fp;
|
||||
@@ -530,8 +537,8 @@ void PipelineCache::DumpShaderDisasmNV(
|
||||
disasm_fp);
|
||||
}
|
||||
|
||||
vkDestroyPipeline(*device_, dummy_pipeline, nullptr);
|
||||
vkDestroyPipelineCache(*device_, dummy_pipeline_cache, nullptr);
|
||||
dfn.vkDestroyPipeline(*device_, dummy_pipeline, nullptr);
|
||||
dfn.vkDestroyPipelineCache(*device_, dummy_pipeline_cache, nullptr);
|
||||
}
|
||||
|
||||
VkShaderModule PipelineCache::GetGeometryShader(
|
||||
@@ -575,6 +582,7 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
#endif // FINE_GRAINED_DRAW_SCOPES
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto& regs = set_dynamic_state_registers_;
|
||||
|
||||
bool window_offset_dirty = SetShadowRegister(®s.pa_sc_window_offset,
|
||||
@@ -620,7 +628,7 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
scissor_rect.offset.y = ws_y - adj_y;
|
||||
scissor_rect.extent.width = std::max(ws_w + adj_x, 0);
|
||||
scissor_rect.extent.height = std::max(ws_h + adj_y, 0);
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor_rect);
|
||||
dfn.vkCmdSetScissor(command_buffer, 0, 1, &scissor_rect);
|
||||
}
|
||||
|
||||
// VK_DYNAMIC_STATE_VIEWPORT
|
||||
@@ -713,7 +721,7 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
assert_true(viewport_rect.minDepth >= 0 && viewport_rect.minDepth <= 1);
|
||||
assert_true(viewport_rect.maxDepth >= -1 && viewport_rect.maxDepth <= 1);
|
||||
|
||||
vkCmdSetViewport(command_buffer, 0, 1, &viewport_rect);
|
||||
dfn.vkCmdSetViewport(command_buffer, 0, 1, &viewport_rect);
|
||||
}
|
||||
|
||||
// VK_DYNAMIC_STATE_DEPTH_BIAS
|
||||
@@ -767,13 +775,13 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
regs.pa_su_poly_offset_offset != depth_bias_offset_vulkan) {
|
||||
regs.pa_su_poly_offset_scale = depth_bias_scale_vulkan;
|
||||
regs.pa_su_poly_offset_offset = depth_bias_offset_vulkan;
|
||||
vkCmdSetDepthBias(command_buffer, depth_bias_offset_vulkan, 0.0f,
|
||||
depth_bias_scale_vulkan);
|
||||
dfn.vkCmdSetDepthBias(command_buffer, depth_bias_offset_vulkan, 0.0f,
|
||||
depth_bias_scale_vulkan);
|
||||
}
|
||||
} else if (full_update) {
|
||||
regs.pa_su_poly_offset_scale = 0.0f;
|
||||
regs.pa_su_poly_offset_offset = 0.0f;
|
||||
vkCmdSetDepthBias(command_buffer, 0.0f, 0.0f, 0.0f);
|
||||
dfn.vkCmdSetDepthBias(command_buffer, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
// VK_DYNAMIC_STATE_BLEND_CONSTANTS
|
||||
@@ -787,7 +795,7 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
blend_constant_state_dirty |=
|
||||
SetShadowRegister(®s.rb_blend_rgba[3], XE_GPU_REG_RB_BLEND_ALPHA);
|
||||
if (blend_constant_state_dirty) {
|
||||
vkCmdSetBlendConstants(command_buffer, regs.rb_blend_rgba);
|
||||
dfn.vkCmdSetBlendConstants(command_buffer, regs.rb_blend_rgba);
|
||||
}
|
||||
|
||||
bool stencil_state_dirty = full_update;
|
||||
@@ -799,16 +807,16 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
uint32_t stencil_write_mask = (regs.rb_stencilrefmask >> 16) & 0xFF;
|
||||
|
||||
// VK_DYNAMIC_STATE_STENCIL_REFERENCE
|
||||
vkCmdSetStencilReference(command_buffer, VK_STENCIL_FRONT_AND_BACK,
|
||||
stencil_ref);
|
||||
dfn.vkCmdSetStencilReference(command_buffer, VK_STENCIL_FRONT_AND_BACK,
|
||||
stencil_ref);
|
||||
|
||||
// VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
|
||||
vkCmdSetStencilCompareMask(command_buffer, VK_STENCIL_FRONT_AND_BACK,
|
||||
stencil_read_mask);
|
||||
dfn.vkCmdSetStencilCompareMask(command_buffer, VK_STENCIL_FRONT_AND_BACK,
|
||||
stencil_read_mask);
|
||||
|
||||
// VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
|
||||
vkCmdSetStencilWriteMask(command_buffer, VK_STENCIL_FRONT_AND_BACK,
|
||||
stencil_write_mask);
|
||||
dfn.vkCmdSetStencilWriteMask(command_buffer, VK_STENCIL_FRONT_AND_BACK,
|
||||
stencil_write_mask);
|
||||
}
|
||||
|
||||
bool push_constants_dirty = full_update || viewport_state_dirty;
|
||||
@@ -905,19 +913,19 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
push_constants.ps_param_gen =
|
||||
regs.sq_program_cntl.param_gen ? ps_param_gen : -1;
|
||||
|
||||
vkCmdPushConstants(command_buffer, pipeline_layout_,
|
||||
VK_SHADER_STAGE_VERTEX_BIT |
|
||||
VK_SHADER_STAGE_GEOMETRY_BIT |
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, kSpirvPushConstantsSize, &push_constants);
|
||||
dfn.vkCmdPushConstants(command_buffer, pipeline_layout_,
|
||||
VK_SHADER_STAGE_VERTEX_BIT |
|
||||
VK_SHADER_STAGE_GEOMETRY_BIT |
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, kSpirvPushConstantsSize, &push_constants);
|
||||
}
|
||||
|
||||
if (full_update) {
|
||||
// VK_DYNAMIC_STATE_LINE_WIDTH
|
||||
vkCmdSetLineWidth(command_buffer, 1.0f);
|
||||
dfn.vkCmdSetLineWidth(command_buffer, 1.0f);
|
||||
|
||||
// VK_DYNAMIC_STATE_DEPTH_BOUNDS
|
||||
vkCmdSetDepthBounds(command_buffer, 0.0f, 1.0f);
|
||||
dfn.vkCmdSetDepthBounds(command_buffer, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -8,7 +8,6 @@ project("xenia-gpu-vulkan")
|
||||
language("C++")
|
||||
links({
|
||||
"fmt",
|
||||
"volk",
|
||||
"xenia-base",
|
||||
"xenia-gpu",
|
||||
"xenia-ui",
|
||||
@@ -57,7 +56,6 @@ project("xenia-gpu-vulkan-trace-viewer")
|
||||
"mspack",
|
||||
"snappy",
|
||||
"spirv-tools",
|
||||
"volk",
|
||||
"xxhash",
|
||||
})
|
||||
defines({
|
||||
@@ -124,7 +122,6 @@ project("xenia-gpu-vulkan-trace-dump")
|
||||
"mspack",
|
||||
"snappy",
|
||||
"spirv-tools",
|
||||
"volk",
|
||||
"xxhash",
|
||||
})
|
||||
defines({
|
||||
|
||||
@@ -105,8 +105,9 @@ class CachedFramebuffer {
|
||||
// Associated render pass
|
||||
VkRenderPass render_pass = nullptr;
|
||||
|
||||
CachedFramebuffer(VkDevice device, VkRenderPass render_pass,
|
||||
uint32_t surface_width, uint32_t surface_height,
|
||||
CachedFramebuffer(const ui::vulkan::VulkanDevice& device,
|
||||
VkRenderPass render_pass, uint32_t surface_width,
|
||||
uint32_t surface_height,
|
||||
CachedTileView* target_color_attachments[4],
|
||||
CachedTileView* target_depth_stencil_attachment);
|
||||
~CachedFramebuffer();
|
||||
@@ -116,7 +117,7 @@ class CachedFramebuffer {
|
||||
bool IsCompatible(const RenderConfiguration& desired_config) const;
|
||||
|
||||
private:
|
||||
VkDevice device_ = nullptr;
|
||||
const ui::vulkan::VulkanDevice& device_;
|
||||
};
|
||||
|
||||
// Cached render passes based on register states.
|
||||
@@ -133,7 +134,8 @@ class CachedRenderPass {
|
||||
// Cache of framebuffers for the various tile attachments.
|
||||
std::vector<CachedFramebuffer*> cached_framebuffers;
|
||||
|
||||
CachedRenderPass(VkDevice device, const RenderConfiguration& desired_config);
|
||||
CachedRenderPass(const ui::vulkan::VulkanDevice& device,
|
||||
const RenderConfiguration& desired_config);
|
||||
~CachedRenderPass();
|
||||
|
||||
VkResult Initialize();
|
||||
@@ -141,7 +143,7 @@ class CachedRenderPass {
|
||||
bool IsCompatible(const RenderConfiguration& desired_config) const;
|
||||
|
||||
private:
|
||||
VkDevice device_ = nullptr;
|
||||
const ui::vulkan::VulkanDevice& device_;
|
||||
};
|
||||
|
||||
CachedTileView::CachedTileView(ui::vulkan::VulkanDevice* device,
|
||||
@@ -150,14 +152,19 @@ CachedTileView::CachedTileView(ui::vulkan::VulkanDevice* device,
|
||||
: device_(device), key(std::move(view_key)) {}
|
||||
|
||||
CachedTileView::~CachedTileView() {
|
||||
VK_SAFE_DESTROY(vkDestroyImageView, *device_, image_view, nullptr);
|
||||
VK_SAFE_DESTROY(vkDestroyImageView, *device_, image_view_depth, nullptr);
|
||||
VK_SAFE_DESTROY(vkDestroyImageView, *device_, image_view_stencil, nullptr);
|
||||
VK_SAFE_DESTROY(vkDestroyImage, *device_, image, nullptr);
|
||||
VK_SAFE_DESTROY(vkFreeMemory, *device_, memory, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyImageView, *device_,
|
||||
image_view);
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyImageView, *device_,
|
||||
image_view_depth);
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyImageView, *device_,
|
||||
image_view_stencil);
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkDestroyImage, *device_, image);
|
||||
ui::vulkan::DestroyAndNullHandle(dfn.vkFreeMemory, *device_, memory);
|
||||
}
|
||||
|
||||
VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
|
||||
// Map format to Vulkan.
|
||||
@@ -230,7 +237,7 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
image_info.queueFamilyIndexCount = 0;
|
||||
image_info.pQueueFamilyIndices = nullptr;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
status = vkCreateImage(*device_, &image_info, nullptr, &image);
|
||||
status = dfn.vkCreateImage(*device_, &image_info, nullptr, &image);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -244,12 +251,12 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
uint32_t(key.msaa_samples), uint32_t(key.edram_format)));
|
||||
|
||||
VkMemoryRequirements memory_requirements;
|
||||
vkGetImageMemoryRequirements(*device_, image, &memory_requirements);
|
||||
dfn.vkGetImageMemoryRequirements(*device_, image, &memory_requirements);
|
||||
|
||||
// Bind to a newly allocated chunk.
|
||||
// TODO: Alias from a really big buffer?
|
||||
memory = device_->AllocateMemory(memory_requirements, 0);
|
||||
status = vkBindImageMemory(*device_, image, memory, 0);
|
||||
status = dfn.vkBindImageMemory(*device_, image, memory, 0);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -276,7 +283,8 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
image_view_info.subresourceRange.aspectMask =
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
status = vkCreateImageView(*device_, &image_view_info, nullptr, &image_view);
|
||||
status =
|
||||
dfn.vkCreateImageView(*device_, &image_view_info, nullptr, &image_view);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -284,15 +292,15 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
// Create separate depth/stencil views.
|
||||
if (key.color_or_depth == 0) {
|
||||
image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
status = vkCreateImageView(*device_, &image_view_info, nullptr,
|
||||
&image_view_depth);
|
||||
status = dfn.vkCreateImageView(*device_, &image_view_info, nullptr,
|
||||
&image_view_depth);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
status = vkCreateImageView(*device_, &image_view_info, nullptr,
|
||||
&image_view_stencil);
|
||||
status = dfn.vkCreateImageView(*device_, &image_view_info, nullptr,
|
||||
&image_view_stencil);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -319,19 +327,20 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
image_barrier.subresourceRange.levelCount = 1;
|
||||
image_barrier.subresourceRange.baseArrayLayer = 0;
|
||||
image_barrier.subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
key.color_or_depth
|
||||
? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
: VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
key.color_or_depth
|
||||
? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
: VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &image_barrier);
|
||||
|
||||
image_layout = image_barrier.newLayout;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
CachedFramebuffer::CachedFramebuffer(
|
||||
VkDevice device, VkRenderPass render_pass, uint32_t surface_width,
|
||||
uint32_t surface_height, CachedTileView* target_color_attachments[4],
|
||||
const ui::vulkan::VulkanDevice& device, VkRenderPass render_pass,
|
||||
uint32_t surface_width, uint32_t surface_height,
|
||||
CachedTileView* target_color_attachments[4],
|
||||
CachedTileView* target_depth_stencil_attachment)
|
||||
: device_(device),
|
||||
width(surface_width),
|
||||
@@ -344,7 +353,10 @@ CachedFramebuffer::CachedFramebuffer(
|
||||
}
|
||||
|
||||
CachedFramebuffer::~CachedFramebuffer() {
|
||||
VK_SAFE_DESTROY(vkDestroyFramebuffer, device_, handle, nullptr);
|
||||
if (handle != VK_NULL_HANDLE) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_.dfn();
|
||||
dfn.vkDestroyFramebuffer(device_, handle, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult CachedFramebuffer::Initialize() {
|
||||
@@ -369,7 +381,8 @@ VkResult CachedFramebuffer::Initialize() {
|
||||
framebuffer_info.width = width;
|
||||
framebuffer_info.height = height;
|
||||
framebuffer_info.layers = 1;
|
||||
return vkCreateFramebuffer(device_, &framebuffer_info, nullptr, &handle);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_.dfn();
|
||||
return dfn.vkCreateFramebuffer(device_, &framebuffer_info, nullptr, &handle);
|
||||
}
|
||||
|
||||
bool CachedFramebuffer::IsCompatible(
|
||||
@@ -414,7 +427,7 @@ bool CachedFramebuffer::IsCompatible(
|
||||
return true;
|
||||
}
|
||||
|
||||
CachedRenderPass::CachedRenderPass(VkDevice device,
|
||||
CachedRenderPass::CachedRenderPass(const ui::vulkan::VulkanDevice& device,
|
||||
const RenderConfiguration& desired_config)
|
||||
: device_(device) {
|
||||
std::memcpy(&config, &desired_config, sizeof(config));
|
||||
@@ -426,7 +439,10 @@ CachedRenderPass::~CachedRenderPass() {
|
||||
}
|
||||
cached_framebuffers.clear();
|
||||
|
||||
VK_SAFE_DESTROY(vkDestroyRenderPass, device_, handle, nullptr);
|
||||
if (handle != VK_NULL_HANDLE) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_.dfn();
|
||||
dfn.vkDestroyRenderPass(device_, handle, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult CachedRenderPass::Initialize() {
|
||||
@@ -537,7 +553,8 @@ VkResult CachedRenderPass::Initialize() {
|
||||
|
||||
render_pass_info.dependencyCount = 1;
|
||||
render_pass_info.pDependencies = dependencies;
|
||||
return vkCreateRenderPass(device_, &render_pass_info, nullptr, &handle);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_.dfn();
|
||||
return dfn.vkCreateRenderPass(device_, &render_pass_info, nullptr, &handle);
|
||||
}
|
||||
|
||||
bool CachedRenderPass::IsCompatible(
|
||||
@@ -566,6 +583,7 @@ RenderCache::RenderCache(RegisterFile* register_file,
|
||||
RenderCache::~RenderCache() { Shutdown(); }
|
||||
|
||||
VkResult RenderCache::Initialize() {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
|
||||
// Create the buffer we'll bind to our memory.
|
||||
@@ -579,7 +597,7 @@ VkResult RenderCache::Initialize() {
|
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
buffer_info.queueFamilyIndexCount = 0;
|
||||
buffer_info.pQueueFamilyIndices = nullptr;
|
||||
status = vkCreateBuffer(*device_, &buffer_info, nullptr, &edram_buffer_);
|
||||
status = dfn.vkCreateBuffer(*device_, &buffer_info, nullptr, &edram_buffer_);
|
||||
CheckResult(status, "vkCreateBuffer");
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
@@ -588,7 +606,8 @@ VkResult RenderCache::Initialize() {
|
||||
// Query requirements for the buffer.
|
||||
// It should be 1:1.
|
||||
VkMemoryRequirements buffer_requirements;
|
||||
vkGetBufferMemoryRequirements(*device_, edram_buffer_, &buffer_requirements);
|
||||
dfn.vkGetBufferMemoryRequirements(*device_, edram_buffer_,
|
||||
&buffer_requirements);
|
||||
assert_true(buffer_requirements.size == kEdramBufferCapacity);
|
||||
|
||||
// Allocate EDRAM memory.
|
||||
@@ -600,7 +619,7 @@ VkResult RenderCache::Initialize() {
|
||||
}
|
||||
|
||||
// Bind buffer to map our entire memory.
|
||||
status = vkBindBufferMemory(*device_, edram_buffer_, edram_memory_, 0);
|
||||
status = dfn.vkBindBufferMemory(*device_, edram_buffer_, edram_memory_, 0);
|
||||
CheckResult(status, "vkBindBufferMemory");
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
@@ -609,15 +628,16 @@ VkResult RenderCache::Initialize() {
|
||||
if (status == VK_SUCCESS) {
|
||||
// For debugging, upload a grid into the EDRAM buffer.
|
||||
uint32_t* gpu_data = nullptr;
|
||||
status = vkMapMemory(*device_, edram_memory_, 0, buffer_requirements.size,
|
||||
0, reinterpret_cast<void**>(&gpu_data));
|
||||
status =
|
||||
dfn.vkMapMemory(*device_, edram_memory_, 0, buffer_requirements.size, 0,
|
||||
reinterpret_cast<void**>(&gpu_data));
|
||||
|
||||
if (status == VK_SUCCESS) {
|
||||
for (int i = 0; i < kEdramBufferCapacity / 4; i++) {
|
||||
gpu_data[i] = (i % 8) >= 4 ? 0xFF0000FF : 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
vkUnmapMemory(*device_, edram_memory_);
|
||||
dfn.vkUnmapMemory(*device_, edram_memory_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,6 +647,8 @@ VkResult RenderCache::Initialize() {
|
||||
void RenderCache::Shutdown() {
|
||||
// TODO(benvanik): wait for idle.
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// Dispose all render passes (and their framebuffers).
|
||||
for (auto render_pass : cached_render_passes_) {
|
||||
delete render_pass;
|
||||
@@ -641,11 +663,11 @@ void RenderCache::Shutdown() {
|
||||
|
||||
// Release underlying EDRAM memory.
|
||||
if (edram_buffer_) {
|
||||
vkDestroyBuffer(*device_, edram_buffer_, nullptr);
|
||||
dfn.vkDestroyBuffer(*device_, edram_buffer_, nullptr);
|
||||
edram_buffer_ = nullptr;
|
||||
}
|
||||
if (edram_memory_) {
|
||||
vkFreeMemory(*device_, edram_memory_, nullptr);
|
||||
dfn.vkFreeMemory(*device_, edram_memory_, nullptr);
|
||||
edram_memory_ = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -781,8 +803,9 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer,
|
||||
render_pass_begin_info.pClearValues = nullptr;
|
||||
|
||||
// Begin the render pass.
|
||||
vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info,
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info,
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
return ¤t_state_;
|
||||
}
|
||||
@@ -1019,6 +1042,8 @@ CachedTileView* RenderCache::FindOrCreateTileView(
|
||||
void RenderCache::UpdateTileView(VkCommandBuffer command_buffer,
|
||||
CachedTileView* view, bool load,
|
||||
bool insert_barrier) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
uint32_t tile_width =
|
||||
view->key.msaa_samples == uint16_t(xenos::MsaaSamples::k4X) ? 40 : 80;
|
||||
uint32_t tile_height =
|
||||
@@ -1043,9 +1068,9 @@ void RenderCache::UpdateTileView(VkCommandBuffer command_buffer,
|
||||
tile_height * view->key.color_or_depth
|
||||
? 4
|
||||
: 1;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr,
|
||||
1, &barrier, 0, nullptr);
|
||||
}
|
||||
|
||||
// TODO(DrChat): Stencil copies.
|
||||
@@ -1061,11 +1086,12 @@ void RenderCache::UpdateTileView(VkCommandBuffer command_buffer,
|
||||
region.imageExtent = {view->key.tile_width * tile_width,
|
||||
view->key.tile_height * tile_height, 1};
|
||||
if (load) {
|
||||
vkCmdCopyBufferToImage(command_buffer, edram_buffer_, view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, 1, ®ion);
|
||||
dfn.vkCmdCopyBufferToImage(command_buffer, edram_buffer_, view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, 1, ®ion);
|
||||
} else {
|
||||
vkCmdCopyImageToBuffer(command_buffer, view->image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
edram_buffer_, 1, ®ion);
|
||||
dfn.vkCmdCopyImageToBuffer(command_buffer, view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, edram_buffer_, 1,
|
||||
®ion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,7 +1111,8 @@ void RenderCache::EndRenderPass() {
|
||||
assert_not_null(current_command_buffer_);
|
||||
|
||||
// End the render pass.
|
||||
vkCmdEndRenderPass(current_command_buffer_);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdEndRenderPass(current_command_buffer_);
|
||||
|
||||
// Copy all render targets back into our EDRAM buffer.
|
||||
// Don't bother waiting on this command to complete, as next render pass may
|
||||
@@ -1138,6 +1165,8 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||
VkImageLayout image_layout,
|
||||
bool color_or_depth, VkOffset3D offset,
|
||||
VkExtent3D extents) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// Transition the texture into a transfer destination layout.
|
||||
VkImageMemoryBarrier image_barrier;
|
||||
image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
@@ -1157,9 +1186,9 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||
? VK_IMAGE_ASPECT_COLOR_BIT
|
||||
: VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr,
|
||||
0, nullptr, 1, &image_barrier);
|
||||
}
|
||||
|
||||
VkBufferMemoryBarrier buffer_barrier;
|
||||
@@ -1173,9 +1202,9 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||
// TODO: Calculate this accurately (need texel size)
|
||||
buffer_barrier.size = extents.width * extents.height * 4;
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
|
||||
&buffer_barrier, 0, nullptr);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
|
||||
&buffer_barrier, 0, nullptr);
|
||||
|
||||
// Issue the copy command.
|
||||
// TODO(DrChat): Stencil copies.
|
||||
@@ -1188,8 +1217,8 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||
region.imageSubresource = {0, 0, 0, 1};
|
||||
region.imageSubresource.aspectMask =
|
||||
color_or_depth ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
vkCmdCopyBufferToImage(command_buffer, edram_buffer_, image, image_layout, 1,
|
||||
®ion);
|
||||
dfn.vkCmdCopyBufferToImage(command_buffer, edram_buffer_, image, image_layout,
|
||||
1, ®ion);
|
||||
|
||||
// Transition the image back into its previous layout.
|
||||
if (image_layout != VK_IMAGE_LAYOUT_GENERAL &&
|
||||
@@ -1197,9 +1226,9 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||
image_barrier.srcAccessMask = image_barrier.dstAccessMask;
|
||||
image_barrier.dstAccessMask = 0;
|
||||
std::swap(image_barrier.oldLayout, image_barrier.newLayout);
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr,
|
||||
0, nullptr, 1, &image_barrier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,6 +1239,8 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
bool color_or_depth, uint32_t format,
|
||||
VkFilter filter, VkOffset3D offset,
|
||||
VkExtent3D extents) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
if (color_or_depth) {
|
||||
// Adjust similar formats for easier matching.
|
||||
format = static_cast<uint32_t>(
|
||||
@@ -1252,9 +1283,9 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
color_or_depth ? VK_IMAGE_ASPECT_COLOR_BIT
|
||||
: VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
|
||||
// If we overflow we'll lose the device here.
|
||||
// assert_true(extents.width <= key.tile_width * tile_width);
|
||||
@@ -1277,8 +1308,9 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
image_blit.dstOffsets[1] = {offset.x + int32_t(extents.width),
|
||||
offset.y + int32_t(extents.height),
|
||||
offset.z + int32_t(extents.depth)};
|
||||
vkCmdBlitImage(command_buffer, tile_view->image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
image, image_layout, 1, &image_blit, filter);
|
||||
dfn.vkCmdBlitImage(command_buffer, tile_view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, image, image_layout, 1,
|
||||
&image_blit, filter);
|
||||
} else {
|
||||
VkImageResolve image_resolve;
|
||||
image_resolve.srcSubresource = {0, 0, 0, 1};
|
||||
@@ -1292,8 +1324,9 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
image_resolve.dstOffset = offset;
|
||||
|
||||
image_resolve.extent = extents;
|
||||
vkCmdResolveImage(command_buffer, tile_view->image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
image, image_layout, 1, &image_resolve);
|
||||
dfn.vkCmdResolveImage(command_buffer, tile_view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, image, image_layout, 1,
|
||||
&image_resolve);
|
||||
}
|
||||
|
||||
// Add another barrier on the tile view.
|
||||
@@ -1302,9 +1335,9 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
color_or_depth ? VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
||||
: VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
std::swap(image_barrier.oldLayout, image_barrier.newLayout);
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
}
|
||||
|
||||
void RenderCache::ClearEDRAMColor(VkCommandBuffer command_buffer,
|
||||
@@ -1339,8 +1372,9 @@ void RenderCache::ClearEDRAMColor(VkCommandBuffer command_buffer,
|
||||
std::memcpy(clear_value.float32, color, sizeof(float) * 4);
|
||||
|
||||
// Issue a clear command
|
||||
vkCmdClearColorImage(command_buffer, tile_view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdClearColorImage(command_buffer, tile_view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
|
||||
|
||||
// Copy image back into EDRAM buffer
|
||||
// UpdateTileView(command_buffer, tile_view, false, false);
|
||||
@@ -1378,16 +1412,19 @@ void RenderCache::ClearEDRAMDepthStencil(VkCommandBuffer command_buffer,
|
||||
clear_value.stencil = stencil;
|
||||
|
||||
// Issue a clear command
|
||||
vkCmdClearDepthStencilImage(command_buffer, tile_view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdClearDepthStencilImage(command_buffer, tile_view->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
|
||||
&range);
|
||||
|
||||
// Copy image back into EDRAM buffer
|
||||
// UpdateTileView(command_buffer, tile_view, false, false);
|
||||
}
|
||||
|
||||
void RenderCache::FillEDRAM(VkCommandBuffer command_buffer, uint32_t value) {
|
||||
vkCmdFillBuffer(command_buffer, edram_buffer_, 0, kEdramBufferCapacity,
|
||||
value);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdFillBuffer(command_buffer, edram_buffer_, 0, kEdramBufferCapacity,
|
||||
value);
|
||||
}
|
||||
|
||||
bool RenderCache::SetShadowRegister(uint32_t* dest, uint32_t register_name) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "xenia/gpu/texture_info.h"
|
||||
#include "xenia/gpu/vulkan/texture_config.h"
|
||||
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
|
||||
#include "xenia/ui/vulkan/vulkan_instance.h"
|
||||
#include "xenia/ui/vulkan/vulkan_mem_alloc.h"
|
||||
|
||||
DECLARE_bool(texture_dump);
|
||||
@@ -67,6 +68,7 @@ TextureCache::TextureCache(Memory* memory, RegisterFile* register_file,
|
||||
TextureCache::~TextureCache() { Shutdown(); }
|
||||
|
||||
VkResult TextureCache::Initialize() {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
|
||||
// Descriptor pool used for all of our cached descriptors.
|
||||
@@ -115,8 +117,8 @@ VkResult TextureCache::Initialize() {
|
||||
static_cast<uint32_t>(xe::countof(bindings));
|
||||
descriptor_set_layout_info.pBindings = bindings;
|
||||
status =
|
||||
vkCreateDescriptorSetLayout(*device_, &descriptor_set_layout_info,
|
||||
nullptr, &texture_descriptor_set_layout_);
|
||||
dfn.vkCreateDescriptorSetLayout(*device_, &descriptor_set_layout_info,
|
||||
nullptr, &texture_descriptor_set_layout_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -133,15 +135,15 @@ VkResult TextureCache::Initialize() {
|
||||
|
||||
// Create a memory allocator for textures.
|
||||
VmaVulkanFunctions vulkan_funcs = {};
|
||||
ui::vulkan::FillVMAVulkanFunctions(&vulkan_funcs);
|
||||
ui::vulkan::FillVMAVulkanFunctions(&vulkan_funcs, *device_);
|
||||
|
||||
VmaAllocatorCreateInfo alloc_info = {
|
||||
0, *device_, *device_, 0, 0, nullptr, nullptr, 0, nullptr, &vulkan_funcs,
|
||||
};
|
||||
status = vmaCreateAllocator(&alloc_info, &mem_allocator_);
|
||||
if (status != VK_SUCCESS) {
|
||||
vkDestroyDescriptorSetLayout(*device_, texture_descriptor_set_layout_,
|
||||
nullptr);
|
||||
dfn.vkDestroyDescriptorSetLayout(*device_, texture_descriptor_set_layout_,
|
||||
nullptr);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -177,8 +179,9 @@ void TextureCache::Shutdown() {
|
||||
vmaDestroyAllocator(mem_allocator_);
|
||||
mem_allocator_ = nullptr;
|
||||
}
|
||||
vkDestroyDescriptorSetLayout(*device_, texture_descriptor_set_layout_,
|
||||
nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkDestroyDescriptorSetLayout(*device_, texture_descriptor_set_layout_,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
@@ -229,9 +232,12 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
image_info.usage =
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
const ui::vulkan::VulkanInstance* instance = device_->instance();
|
||||
const ui::vulkan::VulkanInstance::InstanceFunctions& ifn = instance->ifn();
|
||||
|
||||
// Check the device limits for the format before we create it.
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(*device_, format, &props);
|
||||
ifn.vkGetPhysicalDeviceFormatProperties(*device_, format, &props);
|
||||
if ((props.optimalTilingFeatures & required_flags) != required_flags) {
|
||||
// Texture needs conversion on upload to a native format.
|
||||
XELOGE(
|
||||
@@ -257,7 +263,7 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
}
|
||||
|
||||
VkImageFormatProperties image_props;
|
||||
vkGetPhysicalDeviceImageFormatProperties(
|
||||
ifn.vkGetPhysicalDeviceImageFormatProperties(
|
||||
*device_, format, image_info.imageType, image_info.tiling,
|
||||
image_info.usage, image_info.flags, &image_props);
|
||||
|
||||
@@ -308,8 +314,10 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
}
|
||||
|
||||
bool TextureCache::FreeTexture(Texture* texture) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
if (texture->in_flight_fence) {
|
||||
VkResult status = vkGetFenceStatus(*device_, texture->in_flight_fence);
|
||||
VkResult status = dfn.vkGetFenceStatus(*device_, texture->in_flight_fence);
|
||||
if (status != VK_SUCCESS && status != VK_ERROR_DEVICE_LOST) {
|
||||
// Texture still in flight.
|
||||
return false;
|
||||
@@ -317,11 +325,11 @@ bool TextureCache::FreeTexture(Texture* texture) {
|
||||
}
|
||||
|
||||
if (texture->framebuffer) {
|
||||
vkDestroyFramebuffer(*device_, texture->framebuffer, nullptr);
|
||||
dfn.vkDestroyFramebuffer(*device_, texture->framebuffer, nullptr);
|
||||
}
|
||||
|
||||
for (auto it = texture->views.begin(); it != texture->views.end();) {
|
||||
vkDestroyImageView(*device_, (*it)->view, nullptr);
|
||||
dfn.vkDestroyImageView(*device_, (*it)->view, nullptr);
|
||||
it = texture->views.erase(it);
|
||||
}
|
||||
|
||||
@@ -692,7 +700,8 @@ TextureCache::TextureView* TextureCache::DemandView(Texture* texture,
|
||||
!is_cube ? 1 : 1 + texture->texture_info.depth;
|
||||
|
||||
VkImageView view;
|
||||
auto status = vkCreateImageView(*device_, &view_info, nullptr, &view);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto status = dfn.vkCreateImageView(*device_, &view_info, nullptr, &view);
|
||||
CheckResult(status, "vkCreateImageView");
|
||||
if (status == VK_SUCCESS) {
|
||||
auto texture_view = new TextureView();
|
||||
@@ -832,8 +841,9 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
sampler_create_info.unnormalizedCoordinates = VK_FALSE;
|
||||
VkSampler vk_sampler;
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
status =
|
||||
vkCreateSampler(*device_, &sampler_create_info, nullptr, &vk_sampler);
|
||||
dfn.vkCreateSampler(*device_, &sampler_create_info, nullptr, &vk_sampler);
|
||||
CheckResult(status, "vkCreateSampler");
|
||||
if (status != VK_SUCCESS) {
|
||||
return nullptr;
|
||||
@@ -947,7 +957,8 @@ TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
|
||||
|
||||
void TextureCache::FlushPendingCommands(VkCommandBuffer command_buffer,
|
||||
VkFence completion_fence) {
|
||||
auto status = vkEndCommandBuffer(command_buffer);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto status = dfn.vkEndCommandBuffer(command_buffer);
|
||||
CheckResult(status, "vkEndCommandBuffer");
|
||||
|
||||
VkSubmitInfo submit_info;
|
||||
@@ -958,27 +969,27 @@ void TextureCache::FlushPendingCommands(VkCommandBuffer command_buffer,
|
||||
|
||||
if (device_queue_) {
|
||||
auto status =
|
||||
vkQueueSubmit(device_queue_, 1, &submit_info, completion_fence);
|
||||
dfn.vkQueueSubmit(device_queue_, 1, &submit_info, completion_fence);
|
||||
CheckResult(status, "vkQueueSubmit");
|
||||
} else {
|
||||
std::lock_guard<std::mutex> lock(device_->primary_queue_mutex());
|
||||
|
||||
auto status = vkQueueSubmit(device_->primary_queue(), 1, &submit_info,
|
||||
completion_fence);
|
||||
auto status = dfn.vkQueueSubmit(device_->primary_queue(), 1, &submit_info,
|
||||
completion_fence);
|
||||
CheckResult(status, "vkQueueSubmit");
|
||||
}
|
||||
|
||||
vkWaitForFences(*device_, 1, &completion_fence, VK_TRUE, -1);
|
||||
dfn.vkWaitForFences(*device_, 1, &completion_fence, VK_TRUE, -1);
|
||||
staging_buffer_.Scavenge();
|
||||
vkResetFences(*device_, 1, &completion_fence);
|
||||
dfn.vkResetFences(*device_, 1, &completion_fence);
|
||||
|
||||
// Reset the command buffer and put it back into the recording state.
|
||||
vkResetCommandBuffer(command_buffer, 0);
|
||||
dfn.vkResetCommandBuffer(command_buffer, 0);
|
||||
VkCommandBufferBeginInfo begin_info;
|
||||
std::memset(&begin_info, 0, sizeof(begin_info));
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||
dfn.vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||
}
|
||||
|
||||
bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
|
||||
@@ -1155,6 +1166,8 @@ bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
|
||||
TextureDump(src, unpack_buffer, unpack_length);
|
||||
}
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// Transition the texture into a transfer destination layout.
|
||||
VkImageMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
@@ -1181,9 +1194,9 @@ bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
|
||||
barrier.subresourceRange.layerCount =
|
||||
copy_regions[0].imageSubresource.layerCount;
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
|
||||
// Now move the converted texture into the destination.
|
||||
if (dest->format == VK_FORMAT_D16_UNORM_S8_UINT ||
|
||||
@@ -1195,19 +1208,19 @@ bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
|
||||
copy_regions[0].imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
|
||||
vkCmdCopyBufferToImage(command_buffer, staging_buffer_.gpu_buffer(),
|
||||
dest->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
copy_region_count, copy_regions.data());
|
||||
dfn.vkCmdCopyBufferToImage(command_buffer, staging_buffer_.gpu_buffer(),
|
||||
dest->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
copy_region_count, copy_regions.data());
|
||||
|
||||
// Now transition the texture into a shader readonly source.
|
||||
barrier.srcAccessMask = barrier.dstAccessMask;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
barrier.oldLayout = barrier.newLayout;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
dest->image_layout = barrier.newLayout;
|
||||
return true;
|
||||
@@ -1297,6 +1310,7 @@ uint32_t TextureCache::ComputeTextureStorage(const TextureInfo& src) {
|
||||
}
|
||||
|
||||
void TextureCache::WritebackTexture(Texture* texture) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
VkFence fence = wb_command_pool_->BeginBatch();
|
||||
auto alloc = wb_staging_buffer_.Acquire(texture->alloc_info.size, fence);
|
||||
@@ -1313,7 +1327,7 @@ void TextureCache::WritebackTexture(Texture* texture) {
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
nullptr,
|
||||
};
|
||||
vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||
dfn.vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||
|
||||
// TODO: Transition the texture to a transfer source.
|
||||
// TODO: copy depth/layers?
|
||||
@@ -1333,13 +1347,13 @@ void TextureCache::WritebackTexture(Texture* texture) {
|
||||
region.imageExtent.height = texture->texture_info.height + 1;
|
||||
region.imageExtent.depth = 1;
|
||||
|
||||
vkCmdCopyImageToBuffer(command_buffer, texture->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
wb_staging_buffer_.gpu_buffer(), 1, ®ion);
|
||||
dfn.vkCmdCopyImageToBuffer(command_buffer, texture->image,
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
wb_staging_buffer_.gpu_buffer(), 1, ®ion);
|
||||
|
||||
// TODO: Transition the texture back to a shader resource.
|
||||
|
||||
vkEndCommandBuffer(command_buffer);
|
||||
dfn.vkEndCommandBuffer(command_buffer);
|
||||
|
||||
// Submit the command buffer.
|
||||
// Submit commands and wait.
|
||||
@@ -1356,11 +1370,12 @@ void TextureCache::WritebackTexture(Texture* texture) {
|
||||
0,
|
||||
nullptr,
|
||||
};
|
||||
status = vkQueueSubmit(device_->primary_queue(), 1, &submit_info, fence);
|
||||
status =
|
||||
dfn.vkQueueSubmit(device_->primary_queue(), 1, &submit_info, fence);
|
||||
CheckResult(status, "vkQueueSubmit");
|
||||
|
||||
if (status == VK_SUCCESS) {
|
||||
status = vkQueueWaitIdle(device_->primary_queue());
|
||||
status = dfn.vkQueueWaitIdle(device_->primary_queue());
|
||||
CheckResult(status, "vkQueueWaitIdle");
|
||||
}
|
||||
}
|
||||
@@ -1453,8 +1468,9 @@ VkDescriptorSet TextureCache::PrepareTextureSet(
|
||||
|
||||
// Update the descriptor set.
|
||||
if (update_set_info->image_write_count > 0) {
|
||||
vkUpdateDescriptorSets(*device_, update_set_info->image_write_count,
|
||||
update_set_info->image_writes, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkUpdateDescriptorSets(*device_, update_set_info->image_write_count,
|
||||
update_set_info->image_writes, 0, nullptr);
|
||||
}
|
||||
|
||||
texture_sets_[hash] = descriptor_set;
|
||||
@@ -1613,8 +1629,9 @@ void TextureCache::ClearCache() {
|
||||
textures_.clear();
|
||||
COUNT_profile_set("gpu/texture_cache/textures", 0);
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
for (auto it = samplers_.begin(); it != samplers_.end(); ++it) {
|
||||
vkDestroySampler(*device_, it->second->sampler, nullptr);
|
||||
dfn.vkDestroySampler(*device_, it->second->sampler, nullptr);
|
||||
delete it->second;
|
||||
}
|
||||
samplers_.clear();
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
#ifndef XENIA_GPU_VULKAN_TEXTURE_CONFIG_H_
|
||||
#define XENIA_GPU_VULKAN_TEXTURE_CONFIG_H_
|
||||
|
||||
#include "third_party/volk/volk.h"
|
||||
#include "xenia/gpu/texture_info.h"
|
||||
#include "xenia/gpu/xenos.h"
|
||||
#include "xenia/ui/vulkan/vulkan.h"
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
@@ -237,6 +237,8 @@ void VulkanCommandProcessor::WriteRegister(uint32_t index, uint32_t value) {
|
||||
|
||||
void VulkanCommandProcessor::CreateSwapImage(VkCommandBuffer setup_buffer,
|
||||
VkExtent2D extents) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
VkImageCreateInfo image_info;
|
||||
std::memset(&image_info, 0, sizeof(VkImageCreateInfo));
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
@@ -255,16 +257,16 @@ void VulkanCommandProcessor::CreateSwapImage(VkCommandBuffer setup_buffer,
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
VkImage image_fb;
|
||||
auto status = vkCreateImage(*device_, &image_info, nullptr, &image_fb);
|
||||
auto status = dfn.vkCreateImage(*device_, &image_info, nullptr, &image_fb);
|
||||
CheckResult(status, "vkCreateImage");
|
||||
|
||||
// Bind memory to image.
|
||||
VkMemoryRequirements mem_requirements;
|
||||
vkGetImageMemoryRequirements(*device_, image_fb, &mem_requirements);
|
||||
dfn.vkGetImageMemoryRequirements(*device_, image_fb, &mem_requirements);
|
||||
fb_memory_ = device_->AllocateMemory(mem_requirements, 0);
|
||||
assert_not_null(fb_memory_);
|
||||
|
||||
status = vkBindImageMemory(*device_, image_fb, fb_memory_, 0);
|
||||
status = dfn.vkBindImageMemory(*device_, image_fb, fb_memory_, 0);
|
||||
CheckResult(status, "vkBindImageMemory");
|
||||
|
||||
std::lock_guard<std::mutex> lock(swap_state_.mutex);
|
||||
@@ -281,8 +283,8 @@ void VulkanCommandProcessor::CreateSwapImage(VkCommandBuffer setup_buffer,
|
||||
VK_COMPONENT_SWIZZLE_A},
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
|
||||
};
|
||||
status =
|
||||
vkCreateImageView(*device_, &view_create_info, nullptr, &fb_image_view_);
|
||||
status = dfn.vkCreateImageView(*device_, &view_create_info, nullptr,
|
||||
&fb_image_view_);
|
||||
CheckResult(status, "vkCreateImageView");
|
||||
|
||||
VkFramebufferCreateInfo framebuffer_create_info = {
|
||||
@@ -296,8 +298,8 @@ void VulkanCommandProcessor::CreateSwapImage(VkCommandBuffer setup_buffer,
|
||||
extents.height,
|
||||
1,
|
||||
};
|
||||
status = vkCreateFramebuffer(*device_, &framebuffer_create_info, nullptr,
|
||||
&fb_framebuffer_);
|
||||
status = dfn.vkCreateFramebuffer(*device_, &framebuffer_create_info, nullptr,
|
||||
&fb_framebuffer_);
|
||||
CheckResult(status, "vkCreateFramebuffer");
|
||||
|
||||
// Transition image to general layout.
|
||||
@@ -313,20 +315,22 @@ void VulkanCommandProcessor::CreateSwapImage(VkCommandBuffer setup_buffer,
|
||||
barrier.image = image_fb;
|
||||
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
|
||||
vkCmdPipelineBarrier(setup_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(setup_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &barrier);
|
||||
}
|
||||
|
||||
void VulkanCommandProcessor::DestroySwapImage() {
|
||||
vkDestroyFramebuffer(*device_, fb_framebuffer_, nullptr);
|
||||
vkDestroyImageView(*device_, fb_image_view_, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
dfn.vkDestroyFramebuffer(*device_, fb_framebuffer_, nullptr);
|
||||
dfn.vkDestroyImageView(*device_, fb_image_view_, nullptr);
|
||||
|
||||
std::lock_guard<std::mutex> lock(swap_state_.mutex);
|
||||
vkDestroyImage(*device_,
|
||||
reinterpret_cast<VkImage>(swap_state_.front_buffer_texture),
|
||||
nullptr);
|
||||
vkFreeMemory(*device_, fb_memory_, nullptr);
|
||||
dfn.vkDestroyImage(
|
||||
*device_, reinterpret_cast<VkImage>(swap_state_.front_buffer_texture),
|
||||
nullptr);
|
||||
dfn.vkFreeMemory(*device_, fb_memory_, nullptr);
|
||||
|
||||
swap_state_.front_buffer_texture = 0;
|
||||
fb_memory_ = nullptr;
|
||||
@@ -345,17 +349,19 @@ void VulkanCommandProcessor::BeginFrame() {
|
||||
current_command_buffer_ = command_buffer_pool_->AcquireEntry();
|
||||
current_setup_buffer_ = command_buffer_pool_->AcquireEntry();
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
VkCommandBufferBeginInfo command_buffer_begin_info;
|
||||
command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
command_buffer_begin_info.pNext = nullptr;
|
||||
command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
command_buffer_begin_info.pInheritanceInfo = nullptr;
|
||||
auto status =
|
||||
vkBeginCommandBuffer(current_command_buffer_, &command_buffer_begin_info);
|
||||
auto status = dfn.vkBeginCommandBuffer(current_command_buffer_,
|
||||
&command_buffer_begin_info);
|
||||
CheckResult(status, "vkBeginCommandBuffer");
|
||||
|
||||
status =
|
||||
vkBeginCommandBuffer(current_setup_buffer_, &command_buffer_begin_info);
|
||||
status = dfn.vkBeginCommandBuffer(current_setup_buffer_,
|
||||
&command_buffer_begin_info);
|
||||
CheckResult(status, "vkBeginCommandBuffer");
|
||||
|
||||
// Flag renderdoc down to start a capture if requested.
|
||||
@@ -385,10 +391,11 @@ void VulkanCommandProcessor::EndFrame() {
|
||||
current_render_state_ = nullptr;
|
||||
}
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
status = vkEndCommandBuffer(current_setup_buffer_);
|
||||
status = dfn.vkEndCommandBuffer(current_setup_buffer_);
|
||||
CheckResult(status, "vkEndCommandBuffer");
|
||||
status = vkEndCommandBuffer(current_command_buffer_);
|
||||
status = dfn.vkEndCommandBuffer(current_command_buffer_);
|
||||
CheckResult(status, "vkEndCommandBuffer");
|
||||
|
||||
current_command_buffer_ = nullptr;
|
||||
@@ -403,6 +410,8 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
uint32_t frontbuffer_height) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// Build a final command buffer that copies the game's frontbuffer texture
|
||||
// into our backbuffer texture.
|
||||
VkCommandBuffer copy_commands = nullptr;
|
||||
@@ -420,7 +429,7 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
std::memset(&begin_info, 0, sizeof(begin_info));
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
auto status = vkBeginCommandBuffer(copy_commands, &begin_info);
|
||||
auto status = dfn.vkBeginCommandBuffer(copy_commands, &begin_info);
|
||||
CheckResult(status, "vkBeginCommandBuffer");
|
||||
|
||||
if (!frontbuffer_ptr) {
|
||||
@@ -463,20 +472,20 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
barrier.image = texture->image;
|
||||
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
|
||||
vkCmdPipelineBarrier(copy_commands,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr,
|
||||
0, nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(copy_commands,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barrier.image = swap_fb;
|
||||
vkCmdPipelineBarrier(copy_commands, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(copy_commands, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
|
||||
0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
// Part of the source image that we want to blit from.
|
||||
VkRect2D src_rect = {
|
||||
@@ -502,7 +511,7 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
std::swap(barrier.oldLayout, barrier.newLayout);
|
||||
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
vkCmdPipelineBarrier(
|
||||
dfn.vkCmdPipelineBarrier(
|
||||
copy_commands, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
@@ -511,7 +520,7 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
swap_state_.height = frontbuffer_height;
|
||||
}
|
||||
|
||||
status = vkEndCommandBuffer(copy_commands);
|
||||
status = dfn.vkEndCommandBuffer(copy_commands);
|
||||
CheckResult(status, "vkEndCommandBuffer");
|
||||
|
||||
// Queue up current command buffers.
|
||||
@@ -549,7 +558,7 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
submit_info.signalSemaphoreCount = 0;
|
||||
submit_info.pSignalSemaphores = nullptr;
|
||||
|
||||
status = vkQueueSubmit(queue_, 1, &submit_info, current_batch_fence_);
|
||||
status = dfn.vkQueueSubmit(queue_, 1, &submit_info, current_batch_fence_);
|
||||
if (device_->is_renderdoc_attached() && capturing_) {
|
||||
device_->EndRenderDocFrameCapture();
|
||||
capturing_ = false;
|
||||
@@ -559,7 +568,7 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
vkWaitForFences(*device_, 1, ¤t_batch_fence_, VK_TRUE, -1);
|
||||
dfn.vkWaitForFences(*device_, 1, ¤t_batch_fence_, VK_TRUE, -1);
|
||||
if (cache_clear_requested_) {
|
||||
cache_clear_requested_ = false;
|
||||
|
||||
@@ -664,6 +673,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
}
|
||||
}
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
|
||||
// Configure the pipeline for drawing.
|
||||
// This encodes all render state (blend, depth, etc), our shader stages,
|
||||
// and our vertex input layout.
|
||||
@@ -675,8 +686,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
return false;
|
||||
} else if (pipeline_status == PipelineCache::UpdateStatus::kMismatch ||
|
||||
full_update) {
|
||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline);
|
||||
dfn.vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline);
|
||||
}
|
||||
pipeline_cache_->SetDynamicState(command_buffer, full_update);
|
||||
|
||||
@@ -710,8 +721,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
uint32_t first_vertex =
|
||||
register_file_->values[XE_GPU_REG_VGT_INDX_OFFSET].u32;
|
||||
uint32_t first_instance = 0;
|
||||
vkCmdDraw(command_buffer, index_count, instance_count, first_vertex,
|
||||
first_instance);
|
||||
dfn.vkCmdDraw(command_buffer, index_count, instance_count, first_vertex,
|
||||
first_instance);
|
||||
} else {
|
||||
// Index buffer draw.
|
||||
uint32_t instance_count = 1;
|
||||
@@ -719,8 +730,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
uint32_t vertex_offset =
|
||||
register_file_->values[XE_GPU_REG_VGT_INDX_OFFSET].u32;
|
||||
uint32_t first_instance = 0;
|
||||
vkCmdDrawIndexed(command_buffer, index_count, instance_count, first_index,
|
||||
vertex_offset, first_instance);
|
||||
dfn.vkCmdDrawIndexed(command_buffer, index_count, instance_count,
|
||||
first_index, vertex_offset, first_instance);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -754,7 +765,8 @@ bool VulkanCommandProcessor::PopulateConstants(VkCommandBuffer command_buffer,
|
||||
uint32_t set_constant_offsets[2] = {
|
||||
static_cast<uint32_t>(constant_offsets.first),
|
||||
static_cast<uint32_t>(constant_offsets.second)};
|
||||
vkCmdBindDescriptorSets(
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdBindDescriptorSets(
|
||||
command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
|
||||
&constant_descriptor_set,
|
||||
static_cast<uint32_t>(xe::countof(set_constant_offsets)),
|
||||
@@ -806,8 +818,9 @@ bool VulkanCommandProcessor::PopulateIndexBuffer(
|
||||
VkIndexType index_type = info.format == xenos::IndexFormat::kInt32
|
||||
? VK_INDEX_TYPE_UINT32
|
||||
: VK_INDEX_TYPE_UINT16;
|
||||
vkCmdBindIndexBuffer(command_buffer, buffer_ref.first, buffer_ref.second,
|
||||
index_type);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdBindIndexBuffer(command_buffer, buffer_ref.first, buffer_ref.second,
|
||||
index_type);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -835,9 +848,10 @@ bool VulkanCommandProcessor::PopulateVertexBuffers(
|
||||
return false;
|
||||
}
|
||||
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline_cache_->pipeline_layout(), 2, 1,
|
||||
&descriptor_set, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline_cache_->pipeline_layout(), 2, 1,
|
||||
&descriptor_set, 0, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -859,9 +873,10 @@ bool VulkanCommandProcessor::PopulateSamplers(VkCommandBuffer command_buffer,
|
||||
return false;
|
||||
}
|
||||
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline_cache_->pipeline_layout(), 1, 1,
|
||||
&descriptor_set, 0, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline_cache_->pipeline_layout(), 1, 1,
|
||||
&descriptor_set, 0, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1066,6 +1081,7 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
render_cache_->EndRenderPass();
|
||||
current_render_state_ = nullptr;
|
||||
}
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto command_buffer = current_command_buffer_;
|
||||
|
||||
if (texture->image_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
|
||||
@@ -1087,9 +1103,9 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
: VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
texture->image_layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &image_barrier);
|
||||
}
|
||||
|
||||
// Transition the image into a transfer destination layout, if needed.
|
||||
@@ -1113,9 +1129,9 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
is_color_source ? VK_IMAGE_ASPECT_COLOR_BIT
|
||||
: VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &image_barrier);
|
||||
|
||||
// Ask the render cache to copy to the resolve texture.
|
||||
auto edram_base = is_color_source ? color_edram_base : depth_edram_base;
|
||||
@@ -1176,10 +1192,11 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
is_color_source
|
||||
? VK_IMAGE_ASPECT_COLOR_BIT
|
||||
: VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &tile_image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(
|
||||
command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &tile_image_barrier);
|
||||
|
||||
auto render_pass =
|
||||
blitter_->GetRenderPass(texture->format, is_color_source);
|
||||
@@ -1200,8 +1217,8 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
1,
|
||||
};
|
||||
|
||||
VkResult res = vkCreateFramebuffer(*device_, &fb_create_info, nullptr,
|
||||
&texture->framebuffer);
|
||||
VkResult res = dfn.vkCreateFramebuffer(*device_, &fb_create_info,
|
||||
nullptr, &texture->framebuffer);
|
||||
CheckResult(res, "vkCreateFramebuffer");
|
||||
}
|
||||
|
||||
@@ -1268,11 +1285,11 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
std::swap(tile_image_barrier.srcAccessMask,
|
||||
tile_image_barrier.dstAccessMask);
|
||||
std::swap(tile_image_barrier.oldLayout, tile_image_barrier.newLayout);
|
||||
vkCmdPipelineBarrier(command_buffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &tile_image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0,
|
||||
nullptr, 0, nullptr, 1, &tile_image_barrier);
|
||||
} break;
|
||||
|
||||
case CopyCommand::kConstantOne:
|
||||
@@ -1286,14 +1303,14 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
image_barrier.dstAccessMask =
|
||||
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT;
|
||||
std::swap(image_barrier.newLayout, image_barrier.oldLayout);
|
||||
vkCmdPipelineBarrier(command_buffer,
|
||||
is_color_source
|
||||
? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
: VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &image_barrier);
|
||||
dfn.vkCmdPipelineBarrier(command_buffer,
|
||||
is_color_source
|
||||
? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
: VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &image_barrier);
|
||||
|
||||
// Perform any requested clears.
|
||||
uint32_t copy_depth_clear = regs[XE_GPU_REG_RB_DEPTH_CLEAR].u32;
|
||||
|
||||
@@ -59,8 +59,9 @@ X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
|
||||
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
||||
device_->queue_family_index(),
|
||||
};
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto status =
|
||||
vkCreateCommandPool(*device_, &create_info, nullptr, &command_pool_);
|
||||
dfn.vkCreateCommandPool(*device_, &create_info, nullptr, &command_pool_);
|
||||
CheckResult(status, "vkCreateCommandPool");
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
@@ -69,7 +70,11 @@ X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
|
||||
void VulkanGraphicsSystem::Shutdown() {
|
||||
GraphicsSystem::Shutdown();
|
||||
|
||||
vkDestroyCommandPool(*device_, command_pool_, nullptr);
|
||||
if (command_pool_ != VK_NULL_HANDLE) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkDestroyCommandPool(*device_, command_pool_, nullptr);
|
||||
command_pool_ = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
@@ -79,6 +84,7 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
|
||||
VkCommandBufferAllocateInfo alloc_info = {
|
||||
@@ -90,7 +96,7 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
};
|
||||
|
||||
VkCommandBuffer cmd = nullptr;
|
||||
status = vkAllocateCommandBuffers(*device_, &alloc_info, &cmd);
|
||||
status = dfn.vkAllocateCommandBuffers(*device_, &alloc_info, &cmd);
|
||||
CheckResult(status, "vkAllocateCommandBuffers");
|
||||
if (status != VK_SUCCESS) {
|
||||
return nullptr;
|
||||
@@ -102,14 +108,14 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
nullptr,
|
||||
};
|
||||
vkBeginCommandBuffer(cmd, &begin_info);
|
||||
dfn.vkBeginCommandBuffer(cmd, &begin_info);
|
||||
|
||||
auto front_buffer =
|
||||
reinterpret_cast<VkImage>(swap_state.front_buffer_texture);
|
||||
|
||||
status = CreateCaptureBuffer(cmd, {swap_state.width, swap_state.height});
|
||||
if (status != VK_SUCCESS) {
|
||||
vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
|
||||
dfn.vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -124,9 +130,9 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = front_buffer;
|
||||
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
|
||||
// Copy front buffer into capture image.
|
||||
VkBufferImageCopy region = {
|
||||
@@ -135,8 +141,8 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
{0, 0, 0}, {swap_state.width, swap_state.height, 1},
|
||||
};
|
||||
|
||||
vkCmdCopyImageToBuffer(cmd, front_buffer, VK_IMAGE_LAYOUT_GENERAL,
|
||||
capture_buffer_, 1, ®ion);
|
||||
dfn.vkCmdCopyImageToBuffer(cmd, front_buffer, VK_IMAGE_LAYOUT_GENERAL,
|
||||
capture_buffer_, 1, ®ion);
|
||||
|
||||
VkBufferMemoryBarrier memory_barrier = {
|
||||
VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
@@ -149,11 +155,11 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
0,
|
||||
VK_WHOLE_SIZE,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 1,
|
||||
&memory_barrier, 0, nullptr);
|
||||
dfn.vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr,
|
||||
1, &memory_barrier, 0, nullptr);
|
||||
|
||||
status = vkEndCommandBuffer(cmd);
|
||||
status = dfn.vkEndCommandBuffer(cmd);
|
||||
|
||||
// Submit commands and wait.
|
||||
if (status == VK_SUCCESS) {
|
||||
@@ -169,21 +175,22 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
0,
|
||||
nullptr,
|
||||
};
|
||||
status = vkQueueSubmit(device_->primary_queue(), 1, &submit_info, nullptr);
|
||||
status =
|
||||
dfn.vkQueueSubmit(device_->primary_queue(), 1, &submit_info, nullptr);
|
||||
CheckResult(status, "vkQueueSubmit");
|
||||
|
||||
if (status == VK_SUCCESS) {
|
||||
status = vkQueueWaitIdle(device_->primary_queue());
|
||||
status = dfn.vkQueueWaitIdle(device_->primary_queue());
|
||||
CheckResult(status, "vkQueueWaitIdle");
|
||||
}
|
||||
}
|
||||
|
||||
vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
|
||||
dfn.vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
|
||||
|
||||
void* data;
|
||||
if (status == VK_SUCCESS) {
|
||||
status = vkMapMemory(*device_, capture_buffer_memory_, 0, VK_WHOLE_SIZE, 0,
|
||||
&data);
|
||||
status = dfn.vkMapMemory(*device_, capture_buffer_memory_, 0, VK_WHOLE_SIZE,
|
||||
0, &data);
|
||||
CheckResult(status, "vkMapMemory");
|
||||
}
|
||||
|
||||
@@ -197,7 +204,7 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
std::memcpy(raw_image->data.data(), data,
|
||||
raw_image->stride * raw_image->height);
|
||||
|
||||
vkUnmapMemory(*device_, capture_buffer_memory_);
|
||||
dfn.vkUnmapMemory(*device_, capture_buffer_memory_);
|
||||
DestroyCaptureBuffer();
|
||||
return raw_image;
|
||||
}
|
||||
@@ -208,6 +215,7 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
|
||||
|
||||
VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
|
||||
VkExtent2D extents) {
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
VkResult status = VK_SUCCESS;
|
||||
|
||||
VkBufferCreateInfo buffer_info = {
|
||||
@@ -220,7 +228,8 @@ VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
|
||||
0,
|
||||
nullptr,
|
||||
};
|
||||
status = vkCreateBuffer(*device_, &buffer_info, nullptr, &capture_buffer_);
|
||||
status =
|
||||
dfn.vkCreateBuffer(*device_, &buffer_info, nullptr, &capture_buffer_);
|
||||
if (status != VK_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -229,17 +238,18 @@ VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
|
||||
|
||||
// Bind memory to buffer.
|
||||
VkMemoryRequirements mem_requirements;
|
||||
vkGetBufferMemoryRequirements(*device_, capture_buffer_, &mem_requirements);
|
||||
dfn.vkGetBufferMemoryRequirements(*device_, capture_buffer_,
|
||||
&mem_requirements);
|
||||
capture_buffer_memory_ = device_->AllocateMemory(
|
||||
mem_requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
assert_not_null(capture_buffer_memory_);
|
||||
|
||||
status =
|
||||
vkBindBufferMemory(*device_, capture_buffer_, capture_buffer_memory_, 0);
|
||||
status = dfn.vkBindBufferMemory(*device_, capture_buffer_,
|
||||
capture_buffer_memory_, 0);
|
||||
CheckResult(status, "vkBindImageMemory");
|
||||
if (status != VK_SUCCESS) {
|
||||
vkDestroyBuffer(*device_, capture_buffer_, nullptr);
|
||||
dfn.vkDestroyBuffer(*device_, capture_buffer_, nullptr);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -247,8 +257,9 @@ VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
|
||||
}
|
||||
|
||||
void VulkanGraphicsSystem::DestroyCaptureBuffer() {
|
||||
vkDestroyBuffer(*device_, capture_buffer_, nullptr);
|
||||
vkFreeMemory(*device_, capture_buffer_memory_, nullptr);
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
dfn.vkDestroyBuffer(*device_, capture_buffer_, nullptr);
|
||||
dfn.vkFreeMemory(*device_, capture_buffer_memory_, nullptr);
|
||||
capture_buffer_ = nullptr;
|
||||
capture_buffer_memory_ = nullptr;
|
||||
capture_buffer_size_ = 0;
|
||||
@@ -286,6 +297,7 @@ void VulkanGraphicsSystem::Swap(xe::ui::UIEvent* e) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device_->dfn();
|
||||
auto swap_chain = display_context_->swap_chain();
|
||||
auto copy_cmd_buffer = swap_chain->copy_cmd_buffer();
|
||||
auto front_buffer =
|
||||
@@ -302,9 +314,9 @@ void VulkanGraphicsSystem::Swap(xe::ui::UIEvent* e) {
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = front_buffer;
|
||||
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
||||
vkCmdPipelineBarrier(copy_cmd_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
dfn.vkCmdPipelineBarrier(copy_cmd_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
||||
nullptr, 1, &barrier);
|
||||
|
||||
VkImageBlit region;
|
||||
region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
|
||||
@@ -317,10 +329,10 @@ void VulkanGraphicsSystem::Swap(xe::ui::UIEvent* e) {
|
||||
region.dstOffsets[1] = {static_cast<int32_t>(swap_chain->surface_width()),
|
||||
static_cast<int32_t>(swap_chain->surface_height()),
|
||||
1};
|
||||
vkCmdBlitImage(copy_cmd_buffer, front_buffer, VK_IMAGE_LAYOUT_GENERAL,
|
||||
swap_chain->surface_image(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion,
|
||||
VK_FILTER_LINEAR);
|
||||
dfn.vkCmdBlitImage(copy_cmd_buffer, front_buffer, VK_IMAGE_LAYOUT_GENERAL,
|
||||
swap_chain->surface_image(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion,
|
||||
VK_FILTER_LINEAR);
|
||||
}
|
||||
|
||||
} // namespace vulkan
|
||||
|
||||
@@ -30,7 +30,9 @@ VulkanShader::VulkanShader(ui::vulkan::VulkanDevice* device,
|
||||
VulkanShader::VulkanTranslation::~VulkanTranslation() {
|
||||
if (shader_module_) {
|
||||
const VulkanShader& vulkan_shader = static_cast<VulkanShader&>(shader());
|
||||
vkDestroyShaderModule(*vulkan_shader.device_, shader_module_, nullptr);
|
||||
const ui::vulkan::VulkanDevice* device = vulkan_shader.device_;
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device->dfn();
|
||||
dfn.vkDestroyShaderModule(*device, shader_module_, nullptr);
|
||||
shader_module_ = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -40,7 +42,8 @@ bool VulkanShader::VulkanTranslation::Prepare() {
|
||||
assert_true(is_valid());
|
||||
|
||||
const VulkanShader& vulkan_shader = static_cast<VulkanShader&>(shader());
|
||||
ui::vulkan::VulkanDevice* device = vulkan_shader.device_;
|
||||
const ui::vulkan::VulkanDevice* device = vulkan_shader.device_;
|
||||
const ui::vulkan::VulkanDevice::DeviceFunctions& dfn = device->dfn();
|
||||
|
||||
// Create the shader module.
|
||||
VkShaderModuleCreateInfo shader_info;
|
||||
@@ -51,7 +54,7 @@ bool VulkanShader::VulkanTranslation::Prepare() {
|
||||
shader_info.pCode =
|
||||
reinterpret_cast<const uint32_t*>(translated_binary().data());
|
||||
auto status =
|
||||
vkCreateShaderModule(*device, &shader_info, nullptr, &shader_module_);
|
||||
dfn.vkCreateShaderModule(*device, &shader_info, nullptr, &shader_module_);
|
||||
CheckResult(status, "vkCreateShaderModule");
|
||||
|
||||
char type_char;
|
||||
|
||||
Reference in New Issue
Block a user