Merge branch 'master' into vulkan

This commit is contained in:
Triang3l
2022-05-03 00:13:17 +03:00
112 changed files with 26403 additions and 1451 deletions

View File

@@ -199,8 +199,8 @@ bool VulkanCommandProcessor::SetupContext() {
return false;
}
render_target_cache_ =
std::make_unique<VulkanRenderTargetCache>(*this, *register_file_);
render_target_cache_ = std::make_unique<VulkanRenderTargetCache>(
*register_file_, *memory_, &trace_writer_, *this);
if (!render_target_cache_->Initialize()) {
XELOGE("Failed to initialize the render target cache");
return false;
@@ -1383,6 +1383,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType prim_type,
return false;
}
reg::RB_DEPTHCONTROL normalized_depth_control =
draw_util::GetNormalizedDepthControl(regs);
uint32_t normalized_color_mask =
pixel_shader ? draw_util::GetNormalizedColorMask(
regs, pixel_shader->writes_color_targets())
@@ -1399,7 +1401,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType prim_type,
// Set up the render targets - this may perform dispatches and draws.
if (!render_target_cache_->Update(is_rasterization_done,
normalized_color_mask)) {
normalized_depth_control,
normalized_color_mask, *vertex_shader)) {
return false;
}
@@ -1421,7 +1424,8 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType prim_type,
const VulkanPipelineCache::PipelineLayoutProvider* pipeline_layout_provider;
if (!pipeline_cache_->ConfigurePipeline(
vertex_shader_translation, pixel_shader_translation,
primitive_processing_result, normalized_color_mask,
primitive_processing_result, normalized_depth_control,
normalized_color_mask,
render_target_cache_->last_update_render_pass_key(), pipeline,
pipeline_layout_provider)) {
return false;
@@ -1485,13 +1489,14 @@ bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType prim_type,
// life. Or even disregard the viewport bounds range in the fragment shader
// interlocks case completely - apply the viewport and the scissor offset
// directly to pixel address and to things like ps_param_gen.
draw_util::GetHostViewportInfo(regs, 1, 1, false,
device_limits.maxViewportDimensions[0],
device_limits.maxViewportDimensions[1], true,
false, false, false, viewport_info);
draw_util::GetHostViewportInfo(
regs, 1, 1, false, device_limits.maxViewportDimensions[0],
device_limits.maxViewportDimensions[1], true, normalized_depth_control,
false, false, false, viewport_info);
// Update dynamic graphics pipeline state.
UpdateDynamicState(viewport_info, primitive_polygonal);
UpdateDynamicState(viewport_info, primitive_polygonal,
normalized_depth_control);
// Update system constants before uploading them.
UpdateSystemConstantValues(primitive_processing_result.host_index_endian,
@@ -2133,7 +2138,8 @@ VkShaderStageFlags VulkanCommandProcessor::GetGuestVertexShaderStageFlags()
}
void VulkanCommandProcessor::UpdateDynamicState(
const draw_util::ViewportInfo& viewport_info, bool primitive_polygonal) {
const draw_util::ViewportInfo& viewport_info, bool primitive_polygonal,
reg::RB_DEPTHCONTROL normalized_depth_control) {
#if XE_UI_VULKAN_FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu");
#endif // XE_UI_VULKAN_FINE_GRAINED_DRAW_SCOPES
@@ -2234,10 +2240,9 @@ void VulkanCommandProcessor::UpdateDynamicState(
// effect on drawing, and because the masks and the references are always
// dynamic in Xenia guest pipelines, they must be set in the command buffer
// before any draw.
auto rb_depthcontrol = draw_util::GetDepthControlForCurrentEdramMode(regs);
if (rb_depthcontrol.stencil_enable) {
if (normalized_depth_control.stencil_enable) {
Register stencil_ref_mask_front_reg, stencil_ref_mask_back_reg;
if (primitive_polygonal && rb_depthcontrol.backface_enable) {
if (primitive_polygonal && normalized_depth_control.backface_enable) {
const ui::vulkan::VulkanProvider& provider = GetVulkanProvider();
const VkPhysicalDevicePortabilitySubsetFeaturesKHR*
device_portability_subset_features =

View File

@@ -21,6 +21,7 @@
#include "xenia/gpu/command_processor.h"
#include "xenia/gpu/draw_util.h"
#include "xenia/gpu/registers.h"
#include "xenia/gpu/spirv_shader_translator.h"
#include "xenia/gpu/vulkan/deferred_command_buffer.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
@@ -242,7 +243,8 @@ class VulkanCommandProcessor : public CommandProcessor {
VkShaderStageFlags GetGuestVertexShaderStageFlags() const;
void UpdateDynamicState(const draw_util::ViewportInfo& viewport_info,
bool primitive_polygonal);
bool primitive_polygonal,
reg::RB_DEPTHCONTROL normalized_depth_control);
void UpdateSystemConstantValues(xenos::Endian index_endian,
const draw_util::ViewportInfo& viewport_info);
bool UpdateBindings(const VulkanShader* vertex_shader,

View File

@@ -121,8 +121,8 @@ VulkanShader* VulkanPipelineCache::LoadShader(xenos::ShaderType shader_type,
// We need to track it even if it fails translation so we know not to try
// again.
VulkanShader* shader =
new VulkanShader(shader_type, data_hash, host_address, dword_count,
command_processor_.GetVulkanProvider());
new VulkanShader(command_processor_.GetVulkanProvider(), shader_type,
data_hash, host_address, dword_count);
shaders_.emplace(data_hash, shader);
return shader;
}
@@ -188,6 +188,7 @@ bool VulkanPipelineCache::ConfigurePipeline(
VulkanShader::VulkanTranslation* vertex_shader,
VulkanShader::VulkanTranslation* pixel_shader,
const PrimitiveProcessor::ProcessingResult& primitive_processing_result,
reg::RB_DEPTHCONTROL normalized_depth_control,
uint32_t normalized_color_mask,
VulkanRenderTargetCache::RenderPassKey render_pass_key,
VkPipeline& pipeline_out,
@@ -231,7 +232,8 @@ bool VulkanPipelineCache::ConfigurePipeline(
PipelineDescription description;
if (!GetCurrentStateDescription(
vertex_shader, pixel_shader, primitive_processing_result,
normalized_color_mask, render_pass_key, description)) {
normalized_depth_control, normalized_color_mask, render_pass_key,
description)) {
return false;
}
if (last_pipeline_ && last_pipeline_->first == description) {
@@ -360,6 +362,7 @@ bool VulkanPipelineCache::GetCurrentStateDescription(
const VulkanShader::VulkanTranslation* vertex_shader,
const VulkanShader::VulkanTranslation* pixel_shader,
const PrimitiveProcessor::ProcessingResult& primitive_processing_result,
reg::RB_DEPTHCONTROL normalized_depth_control,
uint32_t normalized_color_mask,
VulkanRenderTargetCache::RenderPassKey render_pass_key,
PipelineDescription& description_out) const {
@@ -484,27 +487,32 @@ bool VulkanPipelineCache::GetCurrentStateDescription(
// shader interlock RB implementation.
if (render_pass_key.depth_and_color_used & 1) {
auto rb_depthcontrol = draw_util::GetDepthControlForCurrentEdramMode(regs);
if (rb_depthcontrol.z_enable) {
description_out.depth_write_enable = rb_depthcontrol.z_write_enable;
description_out.depth_compare_op = rb_depthcontrol.zfunc;
if (normalized_depth_control.z_enable) {
description_out.depth_write_enable =
normalized_depth_control.z_write_enable;
description_out.depth_compare_op = normalized_depth_control.zfunc;
} else {
description_out.depth_compare_op = xenos::CompareFunction::kAlways;
}
if (rb_depthcontrol.stencil_enable) {
if (normalized_depth_control.stencil_enable) {
description_out.stencil_test_enable = 1;
description_out.stencil_front_fail_op = rb_depthcontrol.stencilfail;
description_out.stencil_front_pass_op = rb_depthcontrol.stencilzpass;
description_out.stencil_front_fail_op =
normalized_depth_control.stencilfail;
description_out.stencil_front_pass_op =
normalized_depth_control.stencilzpass;
description_out.stencil_front_depth_fail_op =
rb_depthcontrol.stencilzfail;
description_out.stencil_front_compare_op = rb_depthcontrol.stencilfunc;
if (primitive_polygonal && rb_depthcontrol.backface_enable) {
description_out.stencil_back_fail_op = rb_depthcontrol.stencilfail_bf;
description_out.stencil_back_pass_op = rb_depthcontrol.stencilzpass_bf;
normalized_depth_control.stencilzfail;
description_out.stencil_front_compare_op =
normalized_depth_control.stencilfunc;
if (primitive_polygonal && normalized_depth_control.backface_enable) {
description_out.stencil_back_fail_op =
normalized_depth_control.stencilfail_bf;
description_out.stencil_back_pass_op =
normalized_depth_control.stencilzpass_bf;
description_out.stencil_back_depth_fail_op =
rb_depthcontrol.stencilzfail_bf;
normalized_depth_control.stencilzfail_bf;
description_out.stencil_back_compare_op =
rb_depthcontrol.stencilfunc_bf;
normalized_depth_control.stencilfunc_bf;
} else {
description_out.stencil_back_fail_op =
description_out.stencil_front_fail_op;

View File

@@ -76,6 +76,7 @@ class VulkanPipelineCache {
VulkanShader::VulkanTranslation* vertex_shader,
VulkanShader::VulkanTranslation* pixel_shader,
const PrimitiveProcessor::ProcessingResult& primitive_processing_result,
reg::RB_DEPTHCONTROL normalized_depth_control,
uint32_t normalized_color_mask,
VulkanRenderTargetCache::RenderPassKey render_pass_key,
VkPipeline& pipeline_out,
@@ -218,6 +219,7 @@ class VulkanPipelineCache {
const VulkanShader::VulkanTranslation* vertex_shader,
const VulkanShader::VulkanTranslation* pixel_shader,
const PrimitiveProcessor::ProcessingResult& primitive_processing_result,
reg::RB_DEPTHCONTROL normalized_depth_control,
uint32_t normalized_color_mask,
VulkanRenderTargetCache::RenderPassKey render_pass_key,
PipelineDescription& description_out) const;

View File

@@ -114,9 +114,10 @@ const VulkanRenderTargetCache::TransferModeInfo
};
VulkanRenderTargetCache::VulkanRenderTargetCache(
VulkanCommandProcessor& command_processor,
const RegisterFile& register_file)
: RenderTargetCache(register_file), command_processor_(command_processor) {}
const RegisterFile& register_file, const Memory& memory,
TraceWriter* trace_writer, VulkanCommandProcessor& command_processor)
: RenderTargetCache(register_file, memory, trace_writer),
command_processor_(command_processor) {}
VulkanRenderTargetCache::~VulkanRenderTargetCache() { Shutdown(true); }
@@ -574,10 +575,12 @@ void VulkanRenderTargetCache::EndSubmission() {
}
}
bool VulkanRenderTargetCache::Update(bool is_rasterization_done,
uint32_t shader_writes_color_targets) {
bool VulkanRenderTargetCache::Update(
bool is_rasterization_done, reg::RB_DEPTHCONTROL normalized_depth_control,
uint32_t normalized_color_mask, const Shader& vertex_shader) {
if (!RenderTargetCache::Update(is_rasterization_done,
shader_writes_color_targets)) {
normalized_depth_control,
normalized_color_mask, vertex_shader)) {
return false;
}

View File

@@ -85,8 +85,9 @@ class VulkanRenderTargetCache final : public RenderTargetCache {
: framebuffer(framebuffer), host_extent(host_extent) {}
};
VulkanRenderTargetCache(VulkanCommandProcessor& command_processor,
const RegisterFile& register_file);
VulkanRenderTargetCache(const RegisterFile& register_file,
const Memory& memory, TraceWriter* trace_writer,
VulkanCommandProcessor& command_processor);
~VulkanRenderTargetCache();
bool Initialize();
@@ -103,7 +104,9 @@ class VulkanRenderTargetCache final : public RenderTargetCache {
uint32_t GetResolutionScaleY() const override { return resolution_scale_y_; }
bool Update(bool is_rasterization_done,
uint32_t shader_writes_color_targets) override;
reg::RB_DEPTHCONTROL normalized_depth_control,
uint32_t normalized_color_mask,
const Shader& vertex_shader) override;
// Binding information for the last successful update.
RenderPassKey last_update_render_pass_key() const {
return last_update_render_pass_key_;

View File

@@ -51,10 +51,14 @@ VkShaderModule VulkanShader::VulkanTranslation::GetOrCreateShaderModule() {
return shader_module_;
}
VulkanShader::VulkanShader(xenos::ShaderType shader_type, uint64_t data_hash,
const uint32_t* dword_ptr, uint32_t dword_count,
const ui::vulkan::VulkanProvider& provider)
: Shader(shader_type, data_hash, dword_ptr, dword_count),
VulkanShader::VulkanShader(const ui::vulkan::VulkanProvider& provider,
xenos::ShaderType shader_type,
uint64_t ucode_data_hash,
const uint32_t* ucode_dwords,
size_t ucode_dword_count,
std::endian ucode_source_endian)
: Shader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count,
ucode_source_endian),
provider_(provider) {}
Shader::Translation* VulkanShader::CreateTranslationInstance(

View File

@@ -35,9 +35,10 @@ class VulkanShader : public Shader {
VkShaderModule shader_module_ = VK_NULL_HANDLE;
};
VulkanShader(xenos::ShaderType shader_type, uint64_t data_hash,
const uint32_t* dword_ptr, uint32_t dword_count,
const ui::vulkan::VulkanProvider& provider);
VulkanShader(const ui::vulkan::VulkanProvider& provider,
xenos::ShaderType shader_type, uint64_t ucode_data_hash,
const uint32_t* ucode_dwords, size_t ucode_dword_count,
std::endian ucode_source_endian = std::endian::big);
protected:
Translation* CreateTranslationInstance(uint64_t modification) override;