RenderCache: Update to register bitfield structs
This commit is contained in:
parent
3cae25f36f
commit
0c2e0e4119
|
@ -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
|
||||
|
|
|
@ -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(®s.rb_modecontrol, XE_GPU_REG_RB_MODECONTROL);
|
||||
dirty |= SetShadowRegister(®s.rb_surface_info, XE_GPU_REG_RB_SURFACE_INFO);
|
||||
dirty |= SetShadowRegister(®s.rb_color_info, XE_GPU_REG_RB_COLOR_INFO);
|
||||
dirty |= SetShadowRegister(®s.rb_color1_info, XE_GPU_REG_RB_COLOR1_INFO);
|
||||
dirty |= SetShadowRegister(®s.rb_color2_info, XE_GPU_REG_RB_COLOR2_INFO);
|
||||
dirty |= SetShadowRegister(®s.rb_color3_info, XE_GPU_REG_RB_COLOR3_INFO);
|
||||
dirty |= SetShadowRegister(®s.rb_depth_info, XE_GPU_REG_RB_DEPTH_INFO);
|
||||
dirty |=
|
||||
SetShadowRegister(®s.rb_modecontrol.value, XE_GPU_REG_RB_MODECONTROL);
|
||||
dirty |= SetShadowRegister(®s.rb_surface_info.value,
|
||||
XE_GPU_REG_RB_SURFACE_INFO);
|
||||
dirty |=
|
||||
SetShadowRegister(®s.rb_color_info.value, XE_GPU_REG_RB_COLOR_INFO);
|
||||
dirty |=
|
||||
SetShadowRegister(®s.rb_color1_info.value, XE_GPU_REG_RB_COLOR1_INFO);
|
||||
dirty |=
|
||||
SetShadowRegister(®s.rb_color2_info.value, XE_GPU_REG_RB_COLOR2_INFO);
|
||||
dirty |=
|
||||
SetShadowRegister(®s.rb_color3_info.value, XE_GPU_REG_RB_COLOR3_INFO);
|
||||
dirty |=
|
||||
SetShadowRegister(®s.rb_depth_info.value, XE_GPU_REG_RB_DEPTH_INFO);
|
||||
dirty |= SetShadowRegister(®s.pa_sc_window_scissor_tl,
|
||||
XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL);
|
||||
dirty |= SetShadowRegister(®s.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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue