summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrChat <arkolbed@gmail.com>2017-12-22 23:16:20 -0600
committerDrChat <arkolbed@gmail.com>2017-12-22 23:33:27 -0600
commit26100c586f1c3512f539cf1269d4acbd638928b4 (patch)
tree582e56a375ec4c962c5e8fbb5170b5b9b4998d54
parent516c113423a4c2e61839858347e0137f81cd365f (diff)
[Vulkan] Track render target state with the pipeline cache
-rw-r--r--src/xenia/gpu/vulkan/pipeline_cache.cc57
-rw-r--r--src/xenia/gpu/vulkan/pipeline_cache.h15
2 files changed, 66 insertions, 6 deletions
diff --git a/src/xenia/gpu/vulkan/pipeline_cache.cc b/src/xenia/gpu/vulkan/pipeline_cache.cc
index ca8806085..1214fe0e0 100644
--- a/src/xenia/gpu/vulkan/pipeline_cache.cc
+++ b/src/xenia/gpu/vulkan/pipeline_cache.cc
@@ -791,6 +791,22 @@ bool PipelineCache::SetShadowRegister(float* dest, uint32_t register_name) {
return true;
}
+bool PipelineCache::SetShadowRegisterArray(uint32_t* dest, uint32_t num,
+ uint32_t register_name) {
+ bool dirty = false;
+ for (uint32_t i = 0; i < num; i++) {
+ uint32_t value = register_file_->values[register_name + i].u32;
+ if (dest[i] == value) {
+ continue;
+ }
+
+ dest[i] = value;
+ dirty |= true;
+ }
+
+ return dirty;
+}
+
PipelineCache::UpdateStatus PipelineCache::UpdateState(
VulkanShader* vertex_shader, VulkanShader* pixel_shader,
PrimitiveType primitive_type) {
@@ -810,6 +826,8 @@ PipelineCache::UpdateStatus PipelineCache::UpdateState(
}
UpdateStatus status;
+ status = UpdateRenderTargetState();
+ CHECK_UPDATE_STATUS(status, mismatch, "Unable to update render target state");
status = UpdateShaderStages(vertex_shader, pixel_shader, primitive_type);
CHECK_UPDATE_STATUS(status, mismatch, "Unable to update shader stages");
status = UpdateVertexInputState(vertex_shader);
@@ -831,6 +849,45 @@ PipelineCache::UpdateStatus PipelineCache::UpdateState(
return mismatch ? UpdateStatus::kMismatch : UpdateStatus::kCompatible;
}
+PipelineCache::UpdateStatus PipelineCache::UpdateRenderTargetState() {
+ auto& regs = update_render_targets_regs_;
+ bool dirty = false;
+
+ // Check the render target formats
+ struct {
+ reg::RB_COLOR_INFO rb_color_info;
+ reg::RB_DEPTH_INFO rb_depth_info;
+ reg::RB_COLOR_INFO rb_color1_info;
+ reg::RB_COLOR_INFO rb_color2_info;
+ reg::RB_COLOR_INFO rb_color3_info;
+ }* cur_regs = reinterpret_cast<decltype(cur_regs)>(
+ &register_file_->values[XE_GPU_REG_RB_COLOR_INFO].u32);
+
+ dirty |=
+ regs.rb_color_info.color_format != cur_regs->rb_color_info.color_format;
+ dirty |=
+ regs.rb_depth_info.depth_format != cur_regs->rb_depth_info.depth_format;
+ dirty |=
+ regs.rb_color1_info.color_format != cur_regs->rb_color1_info.color_format;
+ dirty |=
+ regs.rb_color2_info.color_format != cur_regs->rb_color2_info.color_format;
+ dirty |=
+ regs.rb_color3_info.color_format != cur_regs->rb_color3_info.color_format;
+
+ // And copy the regs over.
+ regs.rb_color_info.color_format = cur_regs->rb_color_info.color_format;
+ regs.rb_depth_info.depth_format = cur_regs->rb_depth_info.depth_format;
+ regs.rb_color1_info.color_format = cur_regs->rb_color1_info.color_format;
+ regs.rb_color2_info.color_format = cur_regs->rb_color2_info.color_format;
+ regs.rb_color3_info.color_format = cur_regs->rb_color3_info.color_format;
+ XXH64_update(&hash_state_, &regs, sizeof(regs));
+ if (!dirty) {
+ return UpdateStatus::kCompatible;
+ }
+
+ return UpdateStatus::kMismatch;
+}
+
PipelineCache::UpdateStatus PipelineCache::UpdateShaderStages(
VulkanShader* vertex_shader, VulkanShader* pixel_shader,
PrimitiveType primitive_type) {
diff --git a/src/xenia/gpu/vulkan/pipeline_cache.h b/src/xenia/gpu/vulkan/pipeline_cache.h
index b3fbcdcc0..914f8ac4c 100644
--- a/src/xenia/gpu/vulkan/pipeline_cache.h
+++ b/src/xenia/gpu/vulkan/pipeline_cache.h
@@ -131,6 +131,7 @@ class PipelineCache {
VulkanShader* pixel_shader,
PrimitiveType primitive_type);
+ UpdateStatus UpdateRenderTargetState();
UpdateStatus UpdateShaderStages(VulkanShader* vertex_shader,
VulkanShader* pixel_shader,
PrimitiveType primitive_type);
@@ -144,18 +145,20 @@ class PipelineCache {
bool SetShadowRegister(uint32_t* dest, uint32_t register_name);
bool SetShadowRegister(float* dest, uint32_t register_name);
+ bool SetShadowRegisterArray(uint32_t* dest, uint32_t num,
+ uint32_t register_name);
struct UpdateRenderTargetsRegisters {
uint32_t rb_modecontrol;
- uint32_t rb_surface_info;
- uint32_t rb_color_info;
- uint32_t rb_color1_info;
- uint32_t rb_color2_info;
- uint32_t rb_color3_info;
+ reg::RB_SURFACE_INFO rb_surface_info;
+ reg::RB_COLOR_INFO rb_color_info;
+ reg::RB_DEPTH_INFO rb_depth_info;
+ reg::RB_COLOR_INFO rb_color1_info;
+ reg::RB_COLOR_INFO rb_color2_info;
+ reg::RB_COLOR_INFO rb_color3_info;
uint32_t rb_color_mask;
uint32_t rb_depthcontrol;
uint32_t rb_stencilrefmask;
- uint32_t rb_depth_info;
UpdateRenderTargetsRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }