RenderCache: Update to register bitfield structs

This commit is contained in:
Dr. Chat 2017-03-13 17:54:41 -05:00
parent 3cae25f36f
commit 0c2e0e4119
3 changed files with 133 additions and 52 deletions

View File

@ -30,6 +30,27 @@ namespace reg {
***************************************************/
union COHER_STATUS_HOST {
xe::bf<uint32_t, 0, 8> matching_contexts;
xe::bf<uint32_t, 8, 1> rb_copy_dest_base_ena;
xe::bf<uint32_t, 9, 1> dest_base_0_ena;
xe::bf<uint32_t, 10, 1> dest_base_1_ena;
xe::bf<uint32_t, 11, 1> dest_base_2_ena;
xe::bf<uint32_t, 12, 1> dest_base_3_ena;
xe::bf<uint32_t, 13, 1> dest_base_4_ena;
xe::bf<uint32_t, 14, 1> dest_base_5_ena;
xe::bf<uint32_t, 15, 1> dest_base_6_ena;
xe::bf<uint32_t, 16, 1> dest_base_7_ena;
xe::bf<uint32_t, 24, 1> vc_action_ena;
xe::bf<uint32_t, 25, 1> tc_action_ena;
xe::bf<uint32_t, 26, 1> pglb_action_ena;
xe::bf<uint32_t, 31, 1> status;
uint32_t value;
};
union WAIT_UNTIL {
xe::bf<uint32_t, 1, 1> wait_re_vsync;
xe::bf<uint32_t, 2, 1> wait_fe_vsync;
@ -91,10 +112,26 @@ union PA_SU_SC_MODE_CNTL {
uint32_t value;
};
// Setup Unit Vertex Control
union PA_SU_VTX_CNTL {
xe::bf<uint32_t, 0, 1> pix_center; // 1 = half pixel offset
xe::bf<uint32_t, 1, 2> round_mode;
xe::bf<uint32_t, 3, 3> quant_mode;
uint32_t value;
};
union PA_SC_MPASS_PS_CNTL {
xe::bf<uint32_t, 0, 20> mpass_pix_vec_per_pass;
xe::bf<uint32_t, 31, 1> mpass_ps_ena;
uint32_t value;
};
// Scanline converter viz query
union PA_SC_VIZ_QUERY {
xe::bf<uint32_t, 0, 1> viz_query_ena;
xe::bf<uint32_t, 1, 5> viz_query_id;
xe::bf<uint32_t, 1, 6> viz_query_id;
xe::bf<uint32_t, 7, 1> kill_pix_post_early_z;
uint32_t value;
@ -111,7 +148,9 @@ union PA_CL_CLIP_CNTL {
xe::bf<uint32_t, 4, 1> ucp_ena_4;
xe::bf<uint32_t, 5, 1> ucp_ena_5;
xe::bf<uint32_t, 14, 2> ps_ucp_mode;
xe::bf<uint32_t, 16, 1> clip_disable;
xe::bf<uint32_t, 17, 1> ucp_cull_only_ena;
xe::bf<uint32_t, 18, 1> boundary_edge_flag_ena;
xe::bf<uint32_t, 19, 1> dx_clip_space_def;
xe::bf<uint32_t, 20, 1> dis_clip_err_detect;
@ -156,8 +195,8 @@ union RB_MODECONTROL {
union RB_SURFACE_INFO {
xe::bf<uint32_t, 0, 14> surface_pitch;
xe::bf<MsaaSamples, 14, 2> msaa_samples;
xe::bf<uint32_t, 16, 14> hiz_pitch;
xe::bf<MsaaSamples, 16, 2> msaa_samples;
xe::bf<uint32_t, 18, 14> hiz_pitch;
uint32_t value;
};
@ -166,13 +205,6 @@ union RB_COLORCONTROL {
xe::bf<uint32_t, 0, 3> alpha_func;
xe::bf<uint32_t, 3, 1> alpha_test_enable;
xe::bf<uint32_t, 4, 1> alpha_to_mask_enable;
xe::bf<uint32_t, 5, 1> blend_disable;
xe::bf<uint32_t, 6, 1> fog_enable;
xe::bf<uint32_t, 7, 1> vs_exports_fog;
xe::bf<uint32_t, 8, 4> rop_code;
xe::bf<uint32_t, 12, 2> dither_mode;
xe::bf<uint32_t, 14, 2> dither_type;
xe::bf<uint32_t, 16, 1> pixel_fog;
xe::bf<uint32_t, 24, 2> alpha_to_mask_offset0;
xe::bf<uint32_t, 26, 2> alpha_to_mask_offset1;
@ -185,7 +217,7 @@ union RB_COLORCONTROL {
union RB_COLOR_INFO {
xe::bf<uint32_t, 0, 12> color_base;
xe::bf<ColorRenderTargetFormat, 16, 4> color_format;
xe::bf<uint32_t, 22, 1> unk_22;
xe::bf<uint32_t, 20, 6> color_exp_bias;
uint32_t value;
};
@ -197,6 +229,29 @@ union RB_DEPTH_INFO {
uint32_t value;
};
union RB_COPY_CONTROL {
xe::bf<uint32_t, 0, 3> copy_src_select;
xe::bf<uint32_t, 4, 3> copy_sample_select;
xe::bf<uint32_t, 8, 1> color_clear_enable;
xe::bf<uint32_t, 9, 1> depth_clear_enable;
xe::bf<xenos::CopyCommand, 20, 2> copy_command;
uint32_t value;
};
union RB_COPY_DEST_INFO {
xe::bf<Endian128, 0, 3> copy_dest_endian;
xe::bf<uint32_t, 3, 1> copy_dest_array;
xe::bf<uint32_t, 4, 3> copy_dest_slice;
xe::bf<ColorFormat, 7, 6> copy_dest_format;
xe::bf<uint32_t, 13, 3> copy_dest_number;
xe::bf<uint32_t, 16, 6> copy_dest_exp_bias;
xe::bf<uint32_t, 24, 1> copy_dest_swap;
uint32_t value;
};
} // namespace reg
} // namespace gpu
} // namespace xe

View File

@ -16,6 +16,7 @@
#include "xenia/base/memory.h"
#include "xenia/base/profiling.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/gpu/registers.h"
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
namespace xe {
@ -63,8 +64,7 @@ VkFormat DepthRenderTargetFormatToVkFormat(DepthRenderTargetFormat format) {
case DepthRenderTargetFormat::kD24S8:
return VK_FORMAT_D24_UNORM_S8_UINT;
case DepthRenderTargetFormat::kD24FS8:
// TODO(benvanik): some way to emulate? resolve-time flag?
XELOGW("Unsupported EDRAM format kD24FS8 used");
// Vulkan doesn't support 24-bit floats, so just promote it to 32-bit
return VK_FORMAT_D32_SFLOAT_S8_UINT;
default:
return VK_FORMAT_UNDEFINED;
@ -296,6 +296,7 @@ CachedFramebuffer::CachedFramebuffer(
VkFramebufferCreateInfo framebuffer_info;
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebuffer_info.pNext = nullptr;
framebuffer_info.flags = 0;
framebuffer_info.renderPass = render_pass;
framebuffer_info.attachmentCount = image_view_count;
framebuffer_info.pAttachments = image_views;
@ -422,6 +423,8 @@ CachedRenderPass::CachedRenderPass(VkDevice device,
DepthRenderTargetFormatToVkFormat(depth_config.format);
// Single subpass that writes to our attachments.
// FIXME: "Multiple attachments that alias the same memory must not be used in
// a single subpass"
VkSubpassDescription subpass_info;
subpass_info.flags = 0;
subpass_info.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
@ -567,13 +570,14 @@ bool RenderCache::dirty() const {
auto& cur_regs = shadow_registers_;
bool dirty = false;
dirty |= cur_regs.rb_modecontrol != regs[XE_GPU_REG_RB_MODECONTROL].u32;
dirty |= cur_regs.rb_surface_info != regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
dirty |= cur_regs.rb_color_info != regs[XE_GPU_REG_RB_COLOR_INFO].u32;
dirty |= cur_regs.rb_color1_info != regs[XE_GPU_REG_RB_COLOR1_INFO].u32;
dirty |= cur_regs.rb_color2_info != regs[XE_GPU_REG_RB_COLOR2_INFO].u32;
dirty |= cur_regs.rb_color3_info != regs[XE_GPU_REG_RB_COLOR3_INFO].u32;
dirty |= cur_regs.rb_depth_info != regs[XE_GPU_REG_RB_DEPTH_INFO].u32;
dirty |= cur_regs.rb_modecontrol.value != regs[XE_GPU_REG_RB_MODECONTROL].u32;
dirty |=
cur_regs.rb_surface_info.value != regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
dirty |= cur_regs.rb_color_info.value != regs[XE_GPU_REG_RB_COLOR_INFO].u32;
dirty |= cur_regs.rb_color1_info.value != regs[XE_GPU_REG_RB_COLOR1_INFO].u32;
dirty |= cur_regs.rb_color2_info.value != regs[XE_GPU_REG_RB_COLOR2_INFO].u32;
dirty |= cur_regs.rb_color3_info.value != regs[XE_GPU_REG_RB_COLOR3_INFO].u32;
dirty |= cur_regs.rb_depth_info.value != regs[XE_GPU_REG_RB_DEPTH_INFO].u32;
dirty |= cur_regs.pa_sc_window_scissor_tl !=
regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32;
dirty |= cur_regs.pa_sc_window_scissor_br !=
@ -597,13 +601,20 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer,
CachedFramebuffer* framebuffer = nullptr;
auto& regs = shadow_registers_;
bool dirty = false;
dirty |= SetShadowRegister(&regs.rb_modecontrol, XE_GPU_REG_RB_MODECONTROL);
dirty |= SetShadowRegister(&regs.rb_surface_info, XE_GPU_REG_RB_SURFACE_INFO);
dirty |= SetShadowRegister(&regs.rb_color_info, XE_GPU_REG_RB_COLOR_INFO);
dirty |= SetShadowRegister(&regs.rb_color1_info, XE_GPU_REG_RB_COLOR1_INFO);
dirty |= SetShadowRegister(&regs.rb_color2_info, XE_GPU_REG_RB_COLOR2_INFO);
dirty |= SetShadowRegister(&regs.rb_color3_info, XE_GPU_REG_RB_COLOR3_INFO);
dirty |= SetShadowRegister(&regs.rb_depth_info, XE_GPU_REG_RB_DEPTH_INFO);
dirty |=
SetShadowRegister(&regs.rb_modecontrol.value, XE_GPU_REG_RB_MODECONTROL);
dirty |= SetShadowRegister(&regs.rb_surface_info.value,
XE_GPU_REG_RB_SURFACE_INFO);
dirty |=
SetShadowRegister(&regs.rb_color_info.value, XE_GPU_REG_RB_COLOR_INFO);
dirty |=
SetShadowRegister(&regs.rb_color1_info.value, XE_GPU_REG_RB_COLOR1_INFO);
dirty |=
SetShadowRegister(&regs.rb_color2_info.value, XE_GPU_REG_RB_COLOR2_INFO);
dirty |=
SetShadowRegister(&regs.rb_color3_info.value, XE_GPU_REG_RB_COLOR3_INFO);
dirty |=
SetShadowRegister(&regs.rb_depth_info.value, XE_GPU_REG_RB_DEPTH_INFO);
dirty |= SetShadowRegister(&regs.pa_sc_window_scissor_tl,
XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL);
dirty |= SetShadowRegister(&regs.pa_sc_window_scissor_br,
@ -696,13 +707,12 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
// RB_MODECONTROL
// Rough mode control (color, color+depth, etc).
config->mode_control = static_cast<ModeControl>(regs.rb_modecontrol & 0x7);
config->mode_control = regs.rb_modecontrol.edram_mode;
// RB_SURFACE_INFO
// http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html
config->surface_pitch_px = regs.rb_surface_info & 0x3FFF;
config->surface_msaa =
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
config->surface_pitch_px = regs.rb_surface_info.surface_pitch;
config->surface_msaa = regs.rb_surface_info.msaa_samples;
// TODO(benvanik): verify min/max so we don't go out of bounds.
// TODO(benvanik): has to be a good way to get height.
@ -721,14 +731,13 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
// Color attachment configuration.
if (config->mode_control == ModeControl::kColorDepth) {
uint32_t color_info[4] = {
reg::RB_COLOR_INFO color_info[4] = {
regs.rb_color_info, regs.rb_color1_info, regs.rb_color2_info,
regs.rb_color3_info,
};
for (int i = 0; i < 4; ++i) {
config->color[i].edram_base = color_info[i] & 0xFFF;
config->color[i].format =
static_cast<ColorRenderTargetFormat>((color_info[i] >> 16) & 0xF);
config->color[i].edram_base = color_info[i].color_base;
config->color[i].format = color_info[i].color_format;
// We don't support GAMMA formats, so switch them to what we do support.
switch (config->color[i].format) {
case ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
@ -741,10 +750,6 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
config->color[i].format = ColorRenderTargetFormat::k_2_10_10_10_FLOAT;
break;
}
// Make sure all unknown bits are unset.
// RDR sets bit 0x00400000
// assert_zero(color_info[i] & ~0x000F0FFF);
}
} else {
for (int i = 0; i < 4; ++i) {
@ -757,12 +762,8 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
// Depth/stencil attachment configuration.
if (config->mode_control == ModeControl::kColorDepth ||
config->mode_control == ModeControl::kDepth) {
config->depth_stencil.edram_base = regs.rb_depth_info & 0xFFF;
config->depth_stencil.format =
static_cast<DepthRenderTargetFormat>((regs.rb_depth_info >> 16) & 0x1);
// Make sure all unknown bits are unset.
// assert_zero(regs.rb_depth_info & ~0x00010FFF);
config->depth_stencil.edram_base = regs.rb_depth_info.depth_base;
config->depth_stencil.format = regs.rb_depth_info.depth_format;
} else {
config->depth_stencil.edram_base = 0;
config->depth_stencil.format = DepthRenderTargetFormat::kD24S8;
@ -872,6 +873,27 @@ bool RenderCache::ConfigureRenderPass(VkCommandBuffer command_buffer,
return true;
}
VkImageView RenderCache::FindTileView(uint32_t base, uint32_t pitch,
MsaaSamples samples, bool color_or_depth,
uint32_t format) {
uint32_t tile_width = samples == MsaaSamples::k4X ? 40 : 80;
uint32_t tile_height = samples != MsaaSamples::k1X ? 8 : 16;
TileViewKey key;
key.tile_offset = base;
key.tile_width = xe::round_up(pitch, tile_width) / tile_width;
key.tile_height = 160;
key.color_or_depth = color_or_depth ? 1 : 0;
key.msaa_samples = 0;
key.edram_format = static_cast<uint16_t>(format);
auto view = FindTileView(key);
if (view) {
return view->image_view;
}
return nullptr;
}
CachedTileView* RenderCache::FindOrCreateTileView(
VkCommandBuffer command_buffer, const TileViewKey& view_key) {
auto tile_view = FindTileView(view_key);

View File

@ -11,6 +11,7 @@
#define XENIA_GPU_VULKAN_RENDER_CACHE_H_
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/registers.h"
#include "xenia/gpu/shader.h"
#include "xenia/gpu/texture_info.h"
#include "xenia/gpu/vulkan/vulkan_shader.h"
@ -268,6 +269,9 @@ class RenderCache {
// with an already open pass.
bool dirty() const;
VkImageView FindTileView(uint32_t base, uint32_t pitch, MsaaSamples samples,
bool color_or_depth, uint32_t format);
// Begins a render pass targeting the state-specified framebuffer formats.
// The command buffer will be transitioned into the render pass phase.
const RenderState* BeginRenderPass(VkCommandBuffer command_buffer,
@ -353,13 +357,13 @@ class RenderCache {
// If the registers don't change between passes we can quickly reuse the
// previous one.
struct ShadowRegisters {
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;
uint32_t rb_depth_info;
reg::RB_MODECONTROL rb_modecontrol;
reg::RB_SURFACE_INFO rb_surface_info;
reg::RB_COLOR_INFO rb_color_info;
reg::RB_COLOR_INFO rb_color1_info;
reg::RB_COLOR_INFO rb_color2_info;
reg::RB_COLOR_INFO rb_color3_info;
reg::RB_DEPTH_INFO rb_depth_info;
uint32_t pa_sc_window_scissor_tl;
uint32_t pa_sc_window_scissor_br;