diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc index 14e381b6d..4d960b226 100644 --- a/src/xenia/gpu/command_processor.cc +++ b/src/xenia/gpu/command_processor.cc @@ -129,7 +129,7 @@ void CommandProcessor::WorkerThreadMain() { uint32_t write_ptr_index = write_ptr_index_.load(); if (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index) { - SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::CommandProcessor::Stall"); + SCOPE_profile_cpu_i("gpu", "xe::gpu::CommandProcessor::Stall"); // We've run out of commands to execute. // We spin here waiting for new ones, as the overhead of waiting on our // event is too high. @@ -223,12 +223,9 @@ bool CommandProcessor::SetupContext() { return true; } void CommandProcessor::ShutdownContext() { context_.reset(); } -void CommandProcessor::InitializeRingBuffer(uint32_t ptr, uint32_t page_count) { +void CommandProcessor::InitializeRingBuffer(uint32_t ptr, uint32_t log2_size) { primary_buffer_ptr_ = ptr; - // Not sure this is correct, but it's a way to take the page_count back to - // the number of bytes allocated by the physical alloc. - uint32_t original_size = 1 << (0x1C - page_count - 1); - primary_buffer_size_ = original_size; + primary_buffer_size_ = uint32_t(std::pow(2u, log2_size)); } void CommandProcessor::EnableReadPointerWriteBack(uint32_t ptr, @@ -1280,6 +1277,8 @@ bool CommandProcessor::ExecutePacketType3_VIZ_QUERY(RingBuffer* reader, // Some sort of ID? // This appears to reset a viz query context. // This ID matches the ID in conditional draw commands. + // Patent says the driver sets the viz_query register with info about the + // context ID. uint32_t dword0 = reader->Read(true); return true; diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index 5eadcd0bc..c42a8efe7 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -181,8 +181,8 @@ void GraphicsSystem::WriteRegister(uint32_t addr, uint32_t value) { register_file_.values[r].u32 = value; } -void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t page_count) { - command_processor_->InitializeRingBuffer(ptr, page_count); +void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t log2_size) { + command_processor_->InitializeRingBuffer(ptr, (log2_size | 0x2) + 1); } void GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr, diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 06360a3a8..5b30c2cf7 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -49,7 +49,7 @@ class GraphicsSystem { return command_processor_.get(); } - void InitializeRingBuffer(uint32_t ptr, uint32_t page_count); + void InitializeRingBuffer(uint32_t ptr, uint32_t log2_size); void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size); void SetInterruptCallback(uint32_t callback, uint32_t user_data); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc index 208473cf2..b66304752 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc @@ -200,15 +200,18 @@ void VdSetGraphicsInterruptCallback(function_t callback, lpvoid_t user_data) { } DECLARE_XBOXKRNL_EXPORT(VdSetGraphicsInterruptCallback, ExportTag::kVideo); -void VdInitializeRingBuffer(lpvoid_t ptr, int_t page_count) { +void VdInitializeRingBuffer(lpvoid_t ptr, int_t log2_size) { // r3 = result of MmGetPhysicalAddress - // r4 = number of pages? page size? - // 0x8000 -> cntlzw=16 -> 0x1C - 16 = 12 + // r4 = log2(size) + // r4 is or'd with 0x802 and then stuffed into CP_RB_CNTL + // according to AMD docs, this corresponds with RB_BUFSZ, which is log2 + // actual size. + // 0x8 is RB_BLKSZ, or number of words gpu will read before updating the + // host read pointer. + // So being or'd with 0x2 makes the ring buffer size always a multiple of 4. // Buffer pointers are from MmAllocatePhysicalMemory with WRITE_COMBINE. - // Sizes could be zero? XBLA games seem to do this. Default sizes? - // D3D does size / region_count - must be > 1024 auto graphics_system = kernel_state()->emulator()->graphics_system(); - graphics_system->InitializeRingBuffer(ptr, page_count); + graphics_system->InitializeRingBuffer(ptr, log2_size); } DECLARE_XBOXKRNL_EXPORT(VdInitializeRingBuffer, ExportTag::kVideo);