diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index c42a8efe7..ae2a37aca 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -49,23 +49,27 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor, // Initialize display and rendering context. // This must happen on the UI thread. - std::unique_ptr processor_context; - target_window_->loop()->PostSynchronous([&]() { - // Create the context used for presentation. - assert_null(target_window->context()); - target_window_->set_context(provider_->CreateContext(target_window_)); + std::unique_ptr processor_context = nullptr; + if (provider_) { + target_window_->loop()->PostSynchronous([&]() { + // Create the context used for presentation. + assert_null(target_window->context()); + target_window_->set_context(provider_->CreateContext(target_window_)); - // Setup the GL context the command processor will do all its drawing in. - // It's shared with the display context so that we can resolve framebuffers - // from it. - processor_context = provider()->CreateOffscreenContext(); - }); - if (!processor_context) { - xe::FatalError( - "Unable to initialize GL context. Xenia requires OpenGL 4.5. Ensure " - "you have the latest drivers for your GPU and that it supports OpenGL " - "4.5. See http://xenia.jp/faq/ for more information."); - return X_STATUS_UNSUCCESSFUL; + // Setup the GL context the command processor will do all its drawing in. + // It's shared with the display context so that we can resolve + // framebuffers + // from it. + processor_context = provider()->CreateOffscreenContext(); + }); + if (!processor_context) { + xe::FatalError( + "Unable to initialize GL context. Xenia requires OpenGL 4.5. Ensure " + "you have the latest drivers for your GPU and that it supports " + "OpenGL " + "4.5. See http://xenia.jp/faq/ for more information."); + return X_STATUS_UNSUCCESSFUL; + } } // Create command processor. This will spin up a thread to process all @@ -148,18 +152,24 @@ uint32_t GraphicsSystem::ReadRegister(uint32_t addr) { switch (r) { case 0x3C00: // ? return 0x08100748; - case 0x3C04: // ? + case 0x3C04: // RB_BC_CONTROL return 0x0000200E; - case 0x6530: // Scanline? + case 0x6530: // R500_D1MODE_V_COUNTER(?) / scanline(?) return 0x000002D0; case 0x6544: // ? vblank pending? return 1; - case 0x6584: // Screen res - 1280x720 + case 0x6584: // AVIVO_D1MODE_VIEWPORT_SIZE + // Screen res - 1280x720 + // [width(0x0FFF), height(0x0FFF)] return 0x050002D0; + default: + if (!register_file_.GetRegisterInfo(r)) { + XELOGE("GPU: Read from unknown register (%.4X)", r); + } } - assert_true(r < RegisterFile::kRegisterCount); - return register_file_.values[r].u32; + assert_true((r / 4) < RegisterFile::kRegisterCount); + return register_file_.values[r / 4].u32; } void GraphicsSystem::WriteRegister(uint32_t addr, uint32_t value) { @@ -169,16 +179,15 @@ void GraphicsSystem::WriteRegister(uint32_t addr, uint32_t value) { case 0x0714: // CP_RB_WPTR command_processor_->UpdateWritePointer(value); break; - case 0x6110: // ? swap related? - XELOGW("Unimplemented GPU register %.4X write: %.8X", r, value); - return; + case 0x6110: // AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + break; default: XELOGW("Unknown GPU register %.4X write: %.8X", r, value); break; } - assert_true(r < RegisterFile::kRegisterCount); - register_file_.values[r].u32 = value; + assert_true((r / 4) < RegisterFile::kRegisterCount); + register_file_.values[r / 4].u32 = value; } void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t log2_size) { diff --git a/src/xenia/gpu/register_table.inc b/src/xenia/gpu/register_table.inc index 856b7c832..e1e6b7bc7 100644 --- a/src/xenia/gpu/register_table.inc +++ b/src/xenia/gpu/register_table.inc @@ -18,6 +18,8 @@ XE_GPU_REGISTER(0x01DD, kDword, SCRATCH_ADDR) XE_GPU_REGISTER(0x01DC, kDword, SCRATCH_UMSK) +XE_GPU_REGISTER(0x045E, kDword, CALLBACK_ACK) + XE_GPU_REGISTER(0x0578, kDword, SCRATCH_REG0) // interrupt sync XE_GPU_REGISTER(0x0579, kDword, SCRATCH_REG1) // present interval XE_GPU_REGISTER(0x057A, kDword, SCRATCH_REG2) @@ -48,6 +50,7 @@ XE_GPU_REGISTER(0x0C85, kDword, PA_CL_ENHANCE) XE_GPU_REGISTER(0x0E42, kDword, UNKNOWN_0E42) XE_GPU_REGISTER(0x0F01, kDword, RB_BC_CONTROL) +XE_GPU_REGISTER(0x0F02, kDword, RB_EDRAM_INFO) // D1*, LUT, and AVIVO registers taken from libxenon and https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf XE_GPU_REGISTER(0x1838, kDword, D1MODE_MASTER_UPDATE_LOCK) @@ -62,6 +65,7 @@ XE_GPU_REGISTER(0x1925, kDword, DC_LUT_30_COLOR) XE_GPU_REGISTER(0x1927, kDword, DC_LUT_WRITE_EN_MASK) XE_GPU_REGISTER(0x1930, kDword, DC_LUTA_CONTROL) +XE_GPU_REGISTER(0x1961, kDword, AVIVO_D1MODE_VIEWPORT_SIZE) XE_GPU_REGISTER(0x1964, kDword, AVIVO_D1SCL_SCALER_ENABLE) XE_GPU_REGISTER(0x1973, kDword, AVIVO_D1SCL_UPDATE) @@ -119,7 +123,7 @@ XE_GPU_REGISTER(0x21F9, kDword, VGT_EVENT_INITIATOR) XE_GPU_REGISTER(0x2200, kDword, RB_DEPTHCONTROL) XE_GPU_REGISTER(0x2201, kDword, RB_BLENDCONTROL_0) XE_GPU_REGISTER(0x2202, kDword, RB_COLORCONTROL) -XE_GPU_REGISTER(0x2203, kDword, RB_TILECONTROL) +XE_GPU_REGISTER(0x2203, kDword, RB_HIZCONTROL) XE_GPU_REGISTER(0x2204, kDword, PA_CL_CLIP_CNTL) XE_GPU_REGISTER(0x2205, kDword, PA_SU_SC_MODE_CNTL) XE_GPU_REGISTER(0x2206, kDword, PA_CL_VTE_CNTL) @@ -2507,9 +2511,9 @@ XE_GPU_REGISTER(0x4925, kDword, SHADER_CONSTANT_LOOP_29) XE_GPU_REGISTER(0x4926, kDword, SHADER_CONSTANT_LOOP_30) XE_GPU_REGISTER(0x4927, kDword, SHADER_CONSTANT_LOOP_31) -XE_GPU_REGISTER(0x5000, kDword, UNKNOWN_5000) -XE_GPU_REGISTER(0x5001, kDword, UNKNOWN_5001) -XE_GPU_REGISTER(0x5002, kDword, UNKNOWN_5002) +XE_GPU_REGISTER(0x5000, kDword, SHADER_CONSTANT_FLUSH_FETCH_0) +XE_GPU_REGISTER(0x5001, kDword, SHADER_CONSTANT_FLUSH_FETCH_1) +XE_GPU_REGISTER(0x5002, kDword, SHADER_CONSTANT_FLUSH_FETCH_2) // Ignored because I have no clue what these are. // XE_GPU_REGISTER(0x8D00, kDword, UNKNOWN_8D00)