ReXGlue SDK
Loading...
Searching...
No Matches
register.h
Go to the documentation of this file.
1
16
17#pragma once
18
19#include <cstdint>
20#include <cstdlib>
21#include <utility>
22#include <bit>
23#include <cstddef>
24#include <cstring>
25#include <algorithm>
26#include <optional>
27
28#include <rex/platform.h>
29#include <rex/assert.h>
30#include <rex/types.h>
31#include <rex/xenos/format.h>
32#include <rex/xenos/state.h>
33#include <rex/xenos/fetch.h>
34#include <rex/title.h>
35
36namespace rex::xenos {
37
38enum class Register : u16 {
46#define REXGPU_REGISTER(index, type, name) name = (index),
47#include <rex/xenos/register_table.inc>
48#undef REXGPU_REGISTER
49};
50
56namespace reg {
57
62union alignas(u32) COHER_STATUS_HOST {
63 u32 value;
64 struct {
65 u32 matching_contexts : 8;
66 u32 rb_copy_dest_base_ena : 1;
67 u32 dest_base_0_ena : 1;
68 u32 dest_base_1_ena : 1;
69 u32 dest_base_2_ena : 1;
70 u32 dest_base_3_ena : 1;
71 u32 dest_base_4_ena : 1;
72 u32 dest_base_5_ena : 1;
73 u32 dest_base_6_ena : 1;
74 u32 dest_base_7_ena : 1;
75 u32 pad_17 : 7;
76 u32 vc_action_ena : 1;
77 u32 tc_action_ena : 1;
78 u32 pglb_action_ena : 1;
79 u32 pad_27 : 4;
80 u32 status : 1;
81 };
82 static constexpr Register kRegisterIndex = xenos::Register::COHER_STATUS_HOST;
83};
84REX_STATIC_ASSERT_SIZE(COHER_STATUS_HOST, sizeof(u32));
85
87union alignas(u32) WAIT_UNTIL {
88 u32 value;
89 struct {
90 u32 pad_0 : 1;
91 u32 wait_re_vsync : 1;
92 u32 wait_fe_vsync : 1;
93 u32 wait_vsync : 1;
94 u32 wait_dsply_id0 : 1;
95 u32 wait_dsply_id1 : 1;
96 u32 wait_dsply_id2 : 1;
97 u32 pad_7 : 3;
98 u32 wait_cmdfifo : 1;
99 u32 pad_11 : 3;
100 u32 wait_2d_idle : 1;
101 u32 wait_3d_idle : 1;
102 u32 wait_2d_idleclean : 1;
103 u32 wait_3d_idleclean : 1;
104 u32 pad_18 : 2;
105 u32 cmdfifo_entries : 4;
106 u32 pad_24 : 8;
107 };
108 static constexpr Register kRegisterIndex = xenos::Register::WAIT_UNTIL;
109};
110REX_STATIC_ASSERT_SIZE(WAIT_UNTIL, sizeof(u32));
111
113union alignas(u32) SQ_PROGRAM_CNTL {
114 u32 value;
115 struct {
116 u32 vs_num_reg : 6;
117 u32 pad_6 : 2;
118 u32 ps_num_reg : 6;
119 u32 pad_14 : 2;
120 u32 vs_resource : 1;
121 u32 ps_resource : 1;
123 u32 param_gen : 1;
124 u32 gen_index_pix : 1;
125 u32 vs_export_count : 4;
126 xenos::VertexShaderExportMode vs_export_mode : 3;
127 u32 ps_export_mode : 4;
128 u32 gen_index_vtx : 1;
129 };
130 static constexpr Register kRegisterIndex = xenos::Register::SQ_PROGRAM_CNTL;
131};
132REX_STATIC_ASSERT_SIZE(SQ_PROGRAM_CNTL, sizeof(u32));
133
135union alignas(u32) SQ_CONTEXT_MISC {
136 u32 value;
137 struct {
138 u32 inst_pred_optimize : 1;
139 u32 sc_output_screen_xy : 1;
140 xenos::SampleControl sc_sample_cntl : 2;
141 u32 pad_4 : 4;
149 u32 param_gen_pos : 8;
150 u32 perfcounter_ref : 1;
151 u32 yield_optimize : 1;
152 u32 tx_cache_sel : 1;
153 u32 pad_19 : 13;
154 };
155 static constexpr Register kRegisterIndex = xenos::Register::SQ_CONTEXT_MISC;
156};
157REX_STATIC_ASSERT_SIZE(SQ_CONTEXT_MISC, sizeof(u32));
158
160union alignas(u32) SQ_INTERPOLATOR_CNTL {
161 u32 value;
162 struct {
163 u32 param_shade : 16;
165 u32 sampling_pattern : 16;
166 };
167 static constexpr Register kRegisterIndex = xenos::Register::SQ_INTERPOLATOR_CNTL;
168};
169REX_STATIC_ASSERT_SIZE(SQ_INTERPOLATOR_CNTL, sizeof(u32));
170
172union alignas(u32) SQ_VS_CONST {
173 u32 value;
174 struct {
175 u32 base : 9;
176 u32 pad_9 : 3;
177 u32 size : 9;
178 u32 pad_21 : 11;
179 };
180 static constexpr Register kRegisterIndex = xenos::Register::SQ_VS_CONST;
181};
182REX_STATIC_ASSERT_SIZE(SQ_VS_CONST, sizeof(u32));
183
185union alignas(u32) SQ_PS_CONST {
186 u32 value;
187 struct {
188 u32 base : 9;
189 u32 pad_9 : 3;
190 u32 size : 9;
191 u32 pad_21 : 11;
192 };
193 static constexpr Register kRegisterIndex = xenos::Register::SQ_PS_CONST;
194};
195REX_STATIC_ASSERT_SIZE(SQ_PS_CONST, sizeof(u32));
196
198union alignas(u32) VGT_DMA_SIZE {
199 u32 value;
200 struct {
201 u32 num_words : 24;
202 u32 pad_24 : 6;
203 xenos::Endian swap_mode : 2;
204 };
205 static constexpr Register kRegisterIndex = xenos::Register::VGT_DMA_SIZE;
206};
207
209union alignas(u32) VGT_DRAW_INITIATOR {
210 u32 value;
211 struct {
212 xenos::PrimitiveType prim_type : 6;
213 xenos::SourceSelect source_select : 2;
216 u32 pad_10 : 1;
217 xenos::IndexFormat index_size : 1;
218 u32 not_eop : 1;
219 u32 pad_13 : 3;
220 u32 num_indices : 16;
221 };
222 static constexpr Register kRegisterIndex = xenos::Register::VGT_DRAW_INITIATOR;
223};
224REX_STATIC_ASSERT_SIZE(VGT_DRAW_INITIATOR, sizeof(u32));
225
228 u32 value;
229 struct {
230 u32 reset_indx : 24;
231 u32 pad_24 : 8;
232 };
233 static constexpr Register kRegisterIndex = xenos::Register::VGT_MULTI_PRIM_IB_RESET_INDX;
234};
235REX_STATIC_ASSERT_SIZE(VGT_MULTI_PRIM_IB_RESET_INDX, sizeof(u32));
236
237union alignas(u32) VGT_INDX_OFFSET {
238 u32 value;
239 struct {
240 u32 indx_offset : 24;
241 u32 pad_24 : 8;
242 };
243 static constexpr Register kRegisterIndex = xenos::Register::VGT_INDX_OFFSET;
244};
245REX_STATIC_ASSERT_SIZE(VGT_INDX_OFFSET, sizeof(u32));
246
248union alignas(u32) VGT_MIN_VTX_INDX {
249 u32 value;
250 struct {
251 u32 min_indx : 24;
252 u32 pad_24 : 8;
253 };
254 static constexpr Register kRegisterIndex = xenos::Register::VGT_MIN_VTX_INDX;
255};
256REX_STATIC_ASSERT_SIZE(VGT_MIN_VTX_INDX, sizeof(u32));
257
259union alignas(u32) VGT_MAX_VTX_INDX {
260 u32 value;
261 struct {
262 u32 max_indx : 24;
263 u32 pad_24 : 8;
264 };
265 static constexpr Register kRegisterIndex = xenos::Register::VGT_MAX_VTX_INDX;
266};
267REX_STATIC_ASSERT_SIZE(VGT_MAX_VTX_INDX, sizeof(u32));
268
270union alignas(u32) VGT_OUTPUT_PATH_CNTL {
271 u32 value;
272 struct {
273 xenos::VGTOutputPath path_select : 2;
274 u32 pad_2 : 30;
275 };
276 static constexpr Register kRegisterIndex = xenos::Register::VGT_OUTPUT_PATH_CNTL;
277};
278REX_STATIC_ASSERT_SIZE(VGT_OUTPUT_PATH_CNTL, sizeof(u32));
279
280union alignas(u32) VGT_HOS_CNTL {
281 u32 value;
282 struct {
283 xenos::TessellationMode tess_mode : 2;
284 u32 pad_2 : 30;
285 };
286 static constexpr Register kRegisterIndex = xenos::Register::VGT_HOS_CNTL;
287};
288REX_STATIC_ASSERT_SIZE(VGT_HOS_CNTL, sizeof(u32));
289
291union alignas(u32) PA_SU_POINT_MINMAX {
292 u32 value;
293 struct {
294 u32 min_size : 16;
295 u32 max_size : 16;
296 };
297 static constexpr Register kRegisterIndex = xenos::Register::PA_SU_POINT_MINMAX;
298};
299REX_STATIC_ASSERT_SIZE(PA_SU_POINT_MINMAX, sizeof(u32));
300
302union alignas(u32) PA_SU_POINT_SIZE {
303 u32 value;
304 struct {
305 u32 height : 16;
306 u32 width : 16;
307 };
308 static constexpr Register kRegisterIndex = xenos::Register::PA_SU_POINT_SIZE;
309};
310REX_STATIC_ASSERT_SIZE(PA_SU_POINT_SIZE, sizeof(u32));
311
313union alignas(u32) PA_SU_SC_MODE_CNTL {
314 u32 value;
315 struct {
316 u32 cull_front : 1;
317 u32 cull_back : 1;
318 u32 face : 1;
321 xenos::PolygonType polymode_front_ptype : 3;
322 xenos::PolygonType polymode_back_ptype : 3;
329 u32 pad_14 : 1;
330 u32 msaa_enable : 1;
333 u32 pad_17 : 2;
334 u32 provoking_vtx_last : 1;
335 u32 persp_corr_dis : 1;
336 u32 multi_prim_ib_ena : 1;
337 u32 pad_22 : 1;
338 u32 quad_order_enable : 1;
339 u32 sc_one_quad_per_clock : 1;
340 u32 pad_25 : 7;
341 };
342 static constexpr Register kRegisterIndex = xenos::Register::PA_SU_SC_MODE_CNTL;
343};
344REX_STATIC_ASSERT_SIZE(PA_SU_SC_MODE_CNTL, sizeof(u32));
345
346union alignas(u32) PA_SU_VTX_CNTL {
347 u32 value;
348 struct {
350 xenos::VertexRounding round_mode : 2;
351 xenos::VertexQuantization quant_mode : 3;
352 u32 pad_6 : 26;
353 };
354 static constexpr Register kRegisterIndex = xenos::Register::PA_SU_VTX_CNTL;
355};
356REX_STATIC_ASSERT_SIZE(PA_SU_VTX_CNTL, sizeof(u32));
357
359union alignas(u32) PA_SC_MPASS_PS_CNTL {
360 u32 value;
361 struct {
362 u32 mpass_pix_vec_per_pass : 20;
363 u32 pad_20 : 11;
364 u32 mpass_ps_ena : 1;
365 };
366 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_MPASS_PS_CNTL;
367};
368REX_STATIC_ASSERT_SIZE(PA_SC_MPASS_PS_CNTL, sizeof(u32));
369
371union alignas(u32) PA_SC_VIZ_QUERY {
372 u32 value;
373 struct {
374 u32 viz_query_ena : 1;
375 u32 viz_query_id : 6;
376 u32 kill_pix_post_hi_z : 1;
378 u32 pad_9 : 23;
379 };
380 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_VIZ_QUERY;
381};
382REX_STATIC_ASSERT_SIZE(PA_SC_VIZ_QUERY, sizeof(u32));
383
384union alignas(u32) PA_CL_CLIP_CNTL {
385 u32 value;
386 struct {
387 u32 ucp_ena_0 : 1;
388 u32 ucp_ena_1 : 1;
389 u32 ucp_ena_2 : 1;
390 u32 ucp_ena_3 : 1;
391 u32 ucp_ena_4 : 1;
392 u32 ucp_ena_5 : 1;
393 u32 pad_6 : 8;
394 u32 ps_ucp_mode : 2;
395 u32 clip_disable : 1;
396 u32 ucp_cull_only_ena : 1;
397 u32 boundary_edge_flag_ena : 1;
398 u32 dx_clip_space_def : 1;
399 u32 dis_clip_err_detect : 1;
400 u32 vtx_kill_or : 1;
401 u32 xy_nan_retain : 1;
402 u32 z_nan_retain : 1;
403 u32 w_nan_retain : 1;
404 u32 pad_25 : 7;
405 };
406 struct {
407 u32 ucp_ena : 6;
408 };
409 static constexpr Register kRegisterIndex = xenos::Register::PA_CL_CLIP_CNTL;
410};
411REX_STATIC_ASSERT_SIZE(PA_CL_CLIP_CNTL, sizeof(u32));
412
413union alignas(u32) PA_CL_VTE_CNTL {
414 u32 value;
415 struct {
416 u32 vport_x_scale_ena : 1;
417 u32 vport_x_offset_ena : 1;
418 u32 vport_y_scale_ena : 1;
419 u32 vport_y_offset_ena : 1;
420 u32 vport_z_scale_ena : 1;
421 u32 vport_z_offset_ena : 1;
422 u32 pad_6 : 2;
423 u32 vtx_xy_fmt : 1;
424 u32 vtx_z_fmt : 1;
425 u32 vtx_w0_fmt : 1;
426 u32 perfcounter_ref : 1;
427 u32 pad_12 : 20;
428 };
429 static constexpr Register kRegisterIndex = xenos::Register::PA_CL_VTE_CNTL;
430};
431REX_STATIC_ASSERT_SIZE(PA_CL_VTE_CNTL, sizeof(u32));
432
434union alignas(u32) PA_SC_SCREEN_SCISSOR_TL {
435 u32 value;
436 struct {
437 i32 tl_x : 15;
438 u32 pad_15 : 1;
439 i32 tl_y : 15;
440 u32 pad_31 : 1;
441 };
442 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_SCREEN_SCISSOR_TL;
443};
444REX_STATIC_ASSERT_SIZE(PA_SC_SCREEN_SCISSOR_TL, sizeof(u32));
445
447union alignas(u32) PA_SC_SCREEN_SCISSOR_BR {
448 u32 value;
449 struct {
450 i32 br_x : 15;
451 u32 pad_15 : 1;
452 i32 br_y : 15;
453 u32 pad_31 : 1;
454 };
455 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_SCREEN_SCISSOR_BR;
456};
457REX_STATIC_ASSERT_SIZE(PA_SC_SCREEN_SCISSOR_BR, sizeof(u32));
458
460union alignas(u32) PA_SC_WINDOW_OFFSET {
461 u32 value;
462 struct {
463 i32 window_x_offset : 15;
464 u32 pad_15 : 1;
465 i32 window_y_offset : 15;
466 u32 pad_31 : 1;
467 };
468 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_WINDOW_OFFSET;
469};
470REX_STATIC_ASSERT_SIZE(PA_SC_WINDOW_OFFSET, sizeof(u32));
471
473union alignas(u32) PA_SC_WINDOW_SCISSOR_TL {
474 u32 value;
475 struct {
476 u32 tl_x : 14;
477 u32 pad_14 : 2;
478 u32 tl_y : 14;
479 u32 pad_30 : 1;
480 u32 window_offset_disable : 1;
481 };
482 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_WINDOW_SCISSOR_TL;
483};
484REX_STATIC_ASSERT_SIZE(PA_SC_WINDOW_SCISSOR_TL, sizeof(u32));
485
487union alignas(u32) PA_SC_WINDOW_SCISSOR_BR {
488 u32 value;
489 struct {
490 u32 br_x : 14;
491 u32 pad_14 : 2;
492 u32 br_y : 14;
493 u32 pad_30 : 2;
494 };
495 static constexpr Register kRegisterIndex = xenos::Register::PA_SC_WINDOW_SCISSOR_BR;
496};
497REX_STATIC_ASSERT_SIZE(PA_SC_WINDOW_SCISSOR_BR, sizeof(u32));
498
500union alignas(u32) RB_MODECONTROL {
501 u32 value;
502 struct {
503 xenos::EDRAMMode edram_mode : 3;
504 u32 pad_3 : 29;
505 };
506 static constexpr Register kRegisterIndex = xenos::Register::RB_MODECONTROL;
507};
508REX_STATIC_ASSERT_SIZE(RB_MODECONTROL, sizeof(u32));
509
511union alignas(u32) RB_SURFACE_INFO {
512 u32 value;
513 struct {
514 u32 surface_pitch : 14;
515 u32 pad_14 : 2;
516 xenos::MSAASamples msaa_samples : 2;
517 u32 hiz_pitch : 14;
518 };
519 static constexpr Register kRegisterIndex = xenos::Register::RB_SURFACE_INFO;
520};
521REX_STATIC_ASSERT_SIZE(RB_SURFACE_INFO, sizeof(u32));
522
524union alignas(u32) RB_COLORCONTROL {
525 u32 value;
526 struct {
527 xenos::CompareFunction alpha_func : 3;
528 u32 alpha_test_enable : 1;
530 u32 alpha_to_mask_enable : 1;
531 u32 pad_5 : 19;
538 u32 alpha_to_mask_offset0 : 2;
539 u32 alpha_to_mask_offset1 : 2;
540 u32 alpha_to_mask_offset2 : 2;
541 u32 alpha_to_mask_offset3 : 2;
542 };
543 static constexpr Register kRegisterIndex = xenos::Register::RB_COLORCONTROL;
544};
545REX_STATIC_ASSERT_SIZE(RB_COLORCONTROL, sizeof(u32));
546
548union alignas(u32) RB_COLOR_INFO {
549 u32 value;
550 struct {
552 u32 color_base : 11;
553 u32 color_base_bit_11 : 1;
554 u32 pad_12 : 4;
555 xenos::ColorRenderTargetFormat color_format : 4;
556 i32 color_exp_bias : 6;
557 u32 pad_26 : 6;
558 };
559 static constexpr Register kRegisterIndex = xenos::Register::RB_COLOR_INFO;
561 static const Register kRTRegisterIndices[4];
562};
563REX_STATIC_ASSERT_SIZE(RB_COLOR_INFO, sizeof(u32));
564
566union alignas(u32) RB_COLOR_MASK {
567 u32 value;
568 struct {
570 u32 write_red0 : 1;
571 u32 write_green0 : 1;
572 u32 write_blue0 : 1;
573 u32 write_alpha0 : 1;
574 u32 write_red1 : 1;
575 u32 write_green1 : 1;
576 u32 write_blue1 : 1;
577 u32 write_alpha1 : 1;
578 u32 write_red2 : 1;
579 u32 write_green2 : 1;
580 u32 write_blue2 : 1;
581 u32 write_alpha2 : 1;
582 u32 write_red3 : 1;
583 u32 write_green3 : 1;
584 u32 write_blue3 : 1;
585 u32 write_alpha3 : 1;
586 u32 pad_16 : 16;
587 };
588 static constexpr Register kRegisterIndex = xenos::Register::RB_COLOR_MASK;
589};
590REX_STATIC_ASSERT_SIZE(RB_COLOR_MASK, sizeof(u32));
591
593union alignas(u32) RB_BLENDCONTROL {
594 u32 value;
595 struct {
596 xenos::BlendFactor color_srcblend : 5;
597 xenos::BlendOp color_comb_fcn : 3;
598 xenos::BlendFactor color_destblend : 5;
599 u32 pad_13 : 3;
600 xenos::BlendFactor alpha_srcblend : 5;
601 xenos::BlendOp alpha_comb_fcn : 3;
602 xenos::BlendFactor alpha_destblend : 5;
603 u32 pad_29 : 3;
604 };
605 static constexpr Register kRegisterIndex = xenos::Register::RB_BLENDCONTROL0;
607 static const Register kRTRegisterIndices[4];
608};
609REX_STATIC_ASSERT_SIZE(RB_BLENDCONTROL, sizeof(u32));
610
612union alignas(u32) RB_DEPTHCONTROL {
613 u32 value;
614 struct {
615 u32 stencil_enable : 1;
616 u32 z_enable : 1;
617 u32 z_write_enable : 1;
618 u32 pad_3 : 1;
619 xenos::CompareFunction zfunc : 3;
620 u32 backface_enable : 1;
621 xenos::CompareFunction stencilfunc : 3;
622 xenos::StencilOp stencilfail : 3;
623 xenos::StencilOp stencilzpass : 3;
624 xenos::StencilOp stencilzfail : 3;
625 xenos::CompareFunction stencilfunc_bf : 3;
626 xenos::StencilOp stencilfail_bf : 3;
627 xenos::StencilOp stencilzpass_bf : 3;
628 xenos::StencilOp stencilzfail_bf : 3;
629 };
630 static constexpr Register kRegisterIndex = xenos::Register::RB_DEPTHCONTROL;
631};
632REX_STATIC_ASSERT_SIZE(RB_DEPTHCONTROL, sizeof(u32));
633
635union alignas(u32) RB_STENCILREFMASK {
636 u32 value;
637 struct {
638 u32 stencilref : 8;
639 u32 stencilmask : 8;
640 u32 stencilwritemask : 8;
641 u32 pad_24 : 8;
642 };
643 static constexpr Register kRegisterIndex = xenos::Register::RB_STENCILREFMASK;
644};
645REX_STATIC_ASSERT_SIZE(RB_STENCILREFMASK, sizeof(u32));
646
648union alignas(u32) RB_DEPTH_INFO {
649 u32 value;
650 struct {
652 u32 depth_base : 11;
653 u32 depth_base_bit_11 : 1;
654 u32 pad_12 : 4;
655 xenos::DepthRenderTargetFormat depth_format : 1;
656 u32 pad_17 : 15;
657 };
658 static constexpr Register kRegisterIndex = xenos::Register::RB_DEPTH_INFO;
659};
660REX_STATIC_ASSERT_SIZE(RB_DEPTH_INFO, sizeof(u32));
661
663union alignas(u32) RB_COPY_CONTROL {
664 u32 value;
665 struct {
666 u32 copy_src_select : 3;
667 u32 pad_3 : 1;
668 xenos::CopySampleSelect copy_sample_select : 3;
669 u32 pad_7 : 1;
670 u32 color_clear_enable : 1;
671 u32 depth_clear_enable : 1;
672 u32 pad_10 : 10;
673 xenos::CopyCommand copy_command : 2;
674 u32 pad_22 : 10;
675 };
676 static constexpr Register kRegisterIndex = xenos::Register::RB_COPY_CONTROL;
677};
678REX_STATIC_ASSERT_SIZE(RB_COPY_CONTROL, sizeof(u32));
679
681union alignas(u32) RB_COPY_DEST_INFO {
682 u32 value;
683 struct {
684 xenos::Endian128 copy_dest_endian : 3;
685 u32 copy_dest_array : 1;
686 u32 copy_dest_layer : 3;
687 xenos::ColorFormat copy_dest_format : 6;
688 xenos::SurfaceNumberFormat copy_dest_number : 3;
689 i32 copy_dest_exp_bias : 6;
690 u32 pad_22 : 2;
691 u32 copy_dest_swap : 1;
692 u32 pad_25 : 7;
693 };
694 static constexpr Register kRegisterIndex = xenos::Register::RB_COPY_DEST_INFO;
695};
696REX_STATIC_ASSERT_SIZE(RB_COPY_DEST_INFO, sizeof(u32));
697
699union alignas(u32) RB_COPY_DEST_PITCH {
700 u32 value;
701 struct {
702 u32 copy_dest_pitch : 14;
703 u32 pad_14 : 2;
704 u32 copy_dest_height : 14;
705 u32 pad_30 : 2;
706 };
707 static constexpr Register kRegisterIndex = xenos::Register::RB_COPY_DEST_PITCH;
708};
709REX_STATIC_ASSERT_SIZE(RB_COPY_DEST_PITCH, sizeof(u32));
710
712union alignas(u32) DC_LUT_RW_INDEX {
713 u32 value;
714 struct {
715 u32 rw_index : 8;
716 u32 pad_8 : 24;
717 };
718 static constexpr Register kRegisterIndex = xenos::Register::DC_LUT_RW_INDEX;
719};
720REX_STATIC_ASSERT_SIZE(DC_LUT_RW_INDEX, sizeof(u32));
721
723union alignas(u32) DC_LUT_SEQ_COLOR {
724 u32 value;
725 struct {
726 u32 seq_color : 16;
727 u32 pad_16 : 16;
728 };
729 static constexpr Register kRegisterIndex = xenos::Register::DC_LUT_SEQ_COLOR;
730};
731REX_STATIC_ASSERT_SIZE(DC_LUT_SEQ_COLOR, sizeof(u32));
732
734union alignas(u32) DC_LUT_PWL_DATA {
735 u32 value;
736 struct {
742 u32 base : 16;
743 u32 delta : 16;
744 };
745 static constexpr Register kRegisterIndex = xenos::Register::DC_LUT_PWL_DATA;
746};
747REX_STATIC_ASSERT_SIZE(DC_LUT_PWL_DATA, sizeof(u32));
748
750union alignas(u32) DC_LUT_30_COLOR {
751 u32 value;
752 struct {
753 u32 color_10_blue : 10;
754 u32 color_10_green : 10;
755 u32 color_10_red : 10;
756 u32 pad_30 : 2;
757 };
758 static constexpr Register kRegisterIndex = xenos::Register::DC_LUT_30_COLOR;
759};
760REX_STATIC_ASSERT_SIZE(DC_LUT_30_COLOR, sizeof(u32));
761
762} // namespace reg
763
764} // namespace rex::xenos
765
766namespace rex::xenos {
767
769 enum class Type : u8 {
770 kDword,
771 kFloat,
772 };
773 Type type;
774 const char* name;
775};
776
778 public:
785 static const RegisterInfo* GetRegisterInfo(u32 index);
786
788 static constexpr size_t kRegisterCount = 0x5003;
789 u32 values[kRegisterCount]{};
790
792 const u32& operator[](u32 reg) const { return values[reg]; }
793 u32& operator[](u32 reg) { return values[reg]; }
794 const u32& operator[](Register reg) const { return values[std::to_underlying(reg)]; }
795 u32& operator[](Register reg) { return values[std::to_underlying(reg)]; }
797
805 template <typename T>
806 T Get(u32 reg) const {
807 return std::bit_cast<T>(values[reg]);
808 }
809
815 template <typename T>
816 T Get(Register reg) const {
817 return Get<T>(std::to_underlying(reg));
818 }
819
825 template <typename T>
826 T Get() const {
827 return Get<T>(T::kRegisterIndex);
828 }
829
837 REX_ASSERT(index < 96);
838 xenos::VertexFetch fetch;
839 std::memcpy(&fetch,
840 &values[std::to_underlying(xenos::Register::SHADER_CONSTANT_FETCH_00_0) +
841 (sizeof(fetch) / sizeof(u32)) * index],
842 sizeof(fetch));
843 return fetch;
844 }
845
853 REX_ASSERT(index < 32);
855 std::memcpy(&fetch,
856 &values[std::to_underlying(xenos::Register::SHADER_CONSTANT_FETCH_00_0) +
857 (sizeof(fetch) / sizeof(u32)) * index],
858 sizeof(fetch));
859 return fetch;
860 }
861
868 xenos::MemExportStream GetMemExportStream(u32 float_constant_index) const {
869 REX_ASSERT(float_constant_index < 512);
871 std::memcpy(&stream,
872 &values[std::to_underlying(xenos::Register::SHADER_CONSTANT_000_X) +
873 4 * float_constant_index],
874 sizeof(stream));
875 return stream;
876 }
877};
878
880inline constexpr u32 kViewportLimit = 0x0FFF;
881
886inline std::optional<u32> ReadFixedRegister(u32 index, const VideoMode& mode) {
887 switch (index) {
888 case static_cast<u32>(Register::RB_EDRAM_TIMING):
889 return 0x08100748;
890 case static_cast<u32>(Register::RB_BC_CONTROL):
891 return 0x0000200E;
892 case static_cast<u32>(Register::D1MODE_V_COUNTER):
893 return std::min(mode.height, kViewportLimit);
894 case static_cast<u32>(Register::D1MODE_VBLANK_VLINE_STATUS):
895 return 1;
896 case static_cast<u32>(Register::AVIVO_D1MODE_VIEWPORT_SIZE):
897 return (std::min(mode.width, kViewportLimit) << 16) | std::min(mode.height, kViewportLimit);
898 default:
899 return std::nullopt;
900 }
901}
902
903} // namespace rex::xenos
#define REX_ASSERT(cond,...)
Definition assert.h:84
Definition register.h:777
u32 & operator[](u32 reg)
Definition register.h:793
u32 & operator[](Register reg)
Definition register.h:795
T Get() const
Definition register.h:826
T Get(Register reg) const
Definition register.h:816
xenos::MemExportStream GetMemExportStream(u32 float_constant_index) const
Definition register.h:868
const u32 & operator[](Register reg) const
Definition register.h:794
xenos::TextureFetch GetTextureFetch(u32 index) const
Definition register.h:852
T Get(u32 reg) const
Definition register.h:806
const u32 & operator[](u32 reg) const
Definition register.h:792
static const RegisterInfo * GetRegisterInfo(u32 index)
xenos::VertexFetch GetVertexFetch(u32 index) const
Definition register.h:836
static constexpr size_t kRegisterCount
Definition register.h:788
Fetch constant layouts, texture sampling enums and limits.
Data, texture, vertex and render target formats and conversions.
SurfaceNumberFormat
Definition format.h:52
DepthRenderTargetFormat
Definition format.h:135
Endian
Definition format.h:27
Endian128
Definition format.h:36
ColorRenderTargetFormat
Definition format.h:61
ColorFormat
Definition format.h:267
Definition register.h:56
Platform flags, packing macros and export markers.
std::optional< u32 > ReadFixedRegister(u32 index, const VideoMode &mode)
Definition register.h:886
constexpr u32 kViewportLimit
Definition register.h:880
Xenos pipeline state, shader and EDRAM enums.
PolygonModeEnable
Definition state.h:280
SampleControl
Definition state.h:238
PrimitiveType
Definition state.h:35
BlendFactor
Definition state.h:142
MSAASamples
Definition state.h:69
BlendOp
Definition state.h:161
CopySampleSelect
Definition state.h:341
SourceSelect
Definition state.h:177
VGTOutputPath
Definition state.h:265
PixelCenter
Definition state.h:294
VertexRounding
Definition state.h:300
VertexShaderExportMode
Definition state.h:224
EDRAMMode
Definition state.h:317
MajorMode
Definition state.h:185
Definition title.h:26
Definition register.h:768
Integer types, byte order wrappers and size literals.
Definition fetch.h:358
Definition fetch.h:237
Definition fetch.h:175
Definition register.h:62
Definition register.h:750
Definition register.h:734
Definition register.h:712
Definition register.h:723
Definition register.h:384
Definition register.h:413
Definition register.h:359
Definition register.h:371
Definition register.h:460
Definition register.h:291
Definition register.h:302
Definition register.h:313
Definition register.h:346
Definition register.h:593
static const Register kRTRegisterIndices[4]
Definition register.h:607
Definition register.h:524
Definition register.h:548
static const Register kRTRegisterIndices[4]
Definition register.h:561
Definition register.h:566
Definition register.h:663
Definition register.h:681
Definition register.h:699
Definition register.h:612
Definition register.h:648
Definition register.h:500
Definition register.h:635
Definition register.h:511
Definition register.h:135
Definition register.h:160
Definition register.h:113
Definition register.h:185
Definition register.h:172
Definition register.h:198
Definition register.h:209
Definition register.h:280
Definition register.h:237
Definition register.h:259
Definition register.h:248
Definition register.h:270
Definition register.h:87