Merge branch 'master' of https://github.com/xenia-project/xenia into canary_experimental
This commit is contained in:
@@ -919,9 +919,7 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingBuffer* reader,
|
||||
uint32_t frontbuffer_height = reader->ReadAndSwap<uint32_t>();
|
||||
reader->AdvanceRead((count - 4) * sizeof(uint32_t));
|
||||
|
||||
if (!ignore_swap_) {
|
||||
IssueSwap(frontbuffer_ptr, frontbuffer_width, frontbuffer_height);
|
||||
}
|
||||
IssueSwap(frontbuffer_ptr, frontbuffer_width, frontbuffer_height);
|
||||
|
||||
++counter_;
|
||||
return true;
|
||||
|
||||
@@ -90,7 +90,6 @@ class CommandProcessor {
|
||||
|
||||
virtual void ClearCaches();
|
||||
|
||||
void SetIgnoreSwap(bool ignore_swap) { ignore_swap_ = ignore_swap; }
|
||||
// "Desired" is for the external thread managing the post-processing effect.
|
||||
SwapPostEffect GetDesiredSwapPostEffect() const {
|
||||
return swap_post_effect_desired_;
|
||||
@@ -265,8 +264,6 @@ class CommandProcessor {
|
||||
std::atomic<bool> worker_running_;
|
||||
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
||||
|
||||
bool ignore_swap_ = false;
|
||||
|
||||
std::queue<std::function<void()>> pending_fns_;
|
||||
|
||||
// MicroEngine binary from PM4_ME_INIT
|
||||
|
||||
@@ -1722,10 +1722,6 @@ void D3D12CommandProcessor::OnGammaRampPWLValueWritten() {
|
||||
void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
|
||||
uint32_t frontbuffer_width,
|
||||
uint32_t frontbuffer_height) {
|
||||
// FIXME(Triang3l): frontbuffer_ptr is currently unreliable, in the trace
|
||||
// player it's set to 0, but it's not needed anyway since the fetch constant
|
||||
// contains the address.
|
||||
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
ui::Presenter* presenter = graphics_system_->presenter();
|
||||
@@ -1749,12 +1745,9 @@ void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
|
||||
}
|
||||
D3D12_RESOURCE_DESC swap_texture_desc = swap_texture_resource->GetDesc();
|
||||
|
||||
uint32_t draw_resolution_scale_max =
|
||||
std::max(texture_cache_->draw_resolution_scale_x(),
|
||||
texture_cache_->draw_resolution_scale_y());
|
||||
presenter->RefreshGuestOutput(
|
||||
uint32_t(swap_texture_desc.Width), uint32_t(swap_texture_desc.Height),
|
||||
1280 * draw_resolution_scale_max, 720 * draw_resolution_scale_max,
|
||||
1280, 720,
|
||||
[this, &swap_texture_srv_desc, frontbuffer_format, swap_texture_resource,
|
||||
&swap_texture_desc](
|
||||
ui::Presenter::GuestOutputRefreshContext& context) -> bool {
|
||||
|
||||
@@ -1147,7 +1147,8 @@ bool D3D12TextureCache::ClampDrawResolutionScaleToMaxSupported(
|
||||
}
|
||||
|
||||
bool D3D12TextureCache::EnsureScaledResolveMemoryCommitted(
|
||||
uint32_t start_unscaled, uint32_t length_unscaled) {
|
||||
uint32_t start_unscaled, uint32_t length_unscaled,
|
||||
uint32_t length_scaled_alignment_log2) {
|
||||
assert_true(IsDrawResolutionScaled());
|
||||
|
||||
if (length_unscaled == 0) {
|
||||
@@ -1162,8 +1163,12 @@ bool D3D12TextureCache::EnsureScaledResolveMemoryCommitted(
|
||||
uint32_t draw_resolution_scale_area =
|
||||
draw_resolution_scale_x() * draw_resolution_scale_y();
|
||||
uint64_t first_scaled = uint64_t(start_unscaled) * draw_resolution_scale_area;
|
||||
uint64_t last_scaled = uint64_t(start_unscaled + (length_unscaled - 1)) *
|
||||
draw_resolution_scale_area;
|
||||
uint64_t length_scaled_alignment_bits =
|
||||
(UINT64_C(1) << length_scaled_alignment_log2) - 1;
|
||||
uint64_t last_scaled = (uint64_t(start_unscaled + (length_unscaled - 1)) *
|
||||
draw_resolution_scale_area +
|
||||
length_scaled_alignment_bits) &
|
||||
~length_scaled_alignment_bits;
|
||||
|
||||
const ui::d3d12::D3D12Provider& provider =
|
||||
command_processor_.GetD3D12Provider();
|
||||
@@ -1273,7 +1278,8 @@ bool D3D12TextureCache::EnsureScaledResolveMemoryCommitted(
|
||||
}
|
||||
|
||||
bool D3D12TextureCache::MakeScaledResolveRangeCurrent(
|
||||
uint32_t start_unscaled, uint32_t length_unscaled) {
|
||||
uint32_t start_unscaled, uint32_t length_unscaled,
|
||||
uint32_t length_scaled_alignment_log2) {
|
||||
assert_true(IsDrawResolutionScaled());
|
||||
|
||||
if (!length_unscaled || start_unscaled >= SharedMemory::kBufferSize ||
|
||||
@@ -1286,8 +1292,12 @@ bool D3D12TextureCache::MakeScaledResolveRangeCurrent(
|
||||
uint32_t draw_resolution_scale_area =
|
||||
draw_resolution_scale_x() * draw_resolution_scale_y();
|
||||
uint64_t start_scaled = uint64_t(start_unscaled) * draw_resolution_scale_area;
|
||||
uint64_t length_scaled_alignment_bits =
|
||||
(UINT64_C(1) << length_scaled_alignment_log2) - 1;
|
||||
uint64_t length_scaled =
|
||||
uint64_t(length_unscaled) * draw_resolution_scale_area;
|
||||
(uint64_t(length_unscaled) * draw_resolution_scale_area +
|
||||
length_scaled_alignment_bits) &
|
||||
~length_scaled_alignment_bits;
|
||||
uint64_t last_scaled = start_scaled + (length_scaled - 1);
|
||||
|
||||
// Get one or two buffers that can hold the whole range.
|
||||
@@ -1855,7 +1865,8 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
|
||||
if (texture_resolution_scaled && (is_base || !scaled_mips_source_set_up)) {
|
||||
uint32_t guest_size_unscaled = is_base ? d3d12_texture.GetGuestBaseSize()
|
||||
: d3d12_texture.GetGuestMipsSize();
|
||||
if (!MakeScaledResolveRangeCurrent(guest_address, guest_size_unscaled)) {
|
||||
if (!MakeScaledResolveRangeCurrent(guest_address, guest_size_unscaled,
|
||||
load_shader_info.source_bpe_log2)) {
|
||||
command_processor_.ReleaseScratchGPUBuffer(copy_buffer,
|
||||
copy_buffer_state);
|
||||
return false;
|
||||
|
||||
@@ -130,14 +130,16 @@ class D3D12TextureCache final : public TextureCache {
|
||||
uint32_t& scale_x, uint32_t& scale_y,
|
||||
const ui::d3d12::D3D12Provider& provider);
|
||||
// Ensures the tiles backing the range in the buffers are allocated.
|
||||
bool EnsureScaledResolveMemoryCommitted(uint32_t start_unscaled,
|
||||
uint32_t length_unscaled) override;
|
||||
bool EnsureScaledResolveMemoryCommitted(
|
||||
uint32_t start_unscaled, uint32_t length_unscaled,
|
||||
uint32_t length_scaled_alignment_log2 = 0) override;
|
||||
// Makes the specified range of up to 1-2 GB currently accessible on the GPU.
|
||||
// One draw call can access only at most one range - the same memory is
|
||||
// accessible through different buffers based on the range needed, so aliasing
|
||||
// barriers are required.
|
||||
bool MakeScaledResolveRangeCurrent(uint32_t start_unscaled,
|
||||
uint32_t length_unscaled);
|
||||
uint32_t length_unscaled,
|
||||
uint32_t length_scaled_alignment_log2 = 0);
|
||||
// These functions create a view of the range specified in the last successful
|
||||
// MakeScaledResolveRangeCurrent call because that function must be called
|
||||
// before this.
|
||||
|
||||
@@ -3012,31 +3012,43 @@ void DxbcShaderTranslator::CompletePixelShader() {
|
||||
// checked, but let's assume this means "always", not "less, equal or
|
||||
// greater".
|
||||
// TODO(Triang3l): Check how alpha test works with NaN on Direct3D 9.
|
||||
a_.OpINE(alpha_test_op_dest, alpha_test_mask_src, dxbc::Src::LU(0b111));
|
||||
a_.OpINE(alpha_test_op_dest, alpha_test_mask_src,
|
||||
dxbc::Src::LU(uint32_t(xenos::CompareFunction::kAlways)));
|
||||
// Don't do the test if the mode is "always".
|
||||
a_.OpIf(true, alpha_test_op_src);
|
||||
{
|
||||
// Do the test. Can't use subtraction and sign because of float specials.
|
||||
// Do the test.
|
||||
dxbc::Src alpha_src(
|
||||
dxbc::Src::R(system_temps_color_[0], dxbc::Src::kWWWW));
|
||||
dxbc::Src alpha_test_reference_src(LoadSystemConstant(
|
||||
SystemConstants::Index::kAlphaTestReference,
|
||||
offsetof(SystemConstants, alpha_test_reference), dxbc::Src::kXXXX));
|
||||
// Less than.
|
||||
a_.OpLT(alpha_test_op_dest, alpha_src, alpha_test_reference_src);
|
||||
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
|
||||
dxbc::Src::LU(~uint32_t(1 << 0)));
|
||||
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
|
||||
// Equals to.
|
||||
a_.OpEq(alpha_test_op_dest, alpha_src, alpha_test_reference_src);
|
||||
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
|
||||
dxbc::Src::LU(~uint32_t(1 << 1)));
|
||||
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
|
||||
// Greater than.
|
||||
a_.OpLT(alpha_test_op_dest, alpha_test_reference_src, alpha_src);
|
||||
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
|
||||
dxbc::Src::LU(~uint32_t(1 << 2)));
|
||||
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
|
||||
// Handle "not equal" specially (specifically as "not equal" so it's true
|
||||
// for NaN, not "less or greater" which is false for NaN).
|
||||
a_.OpIEq(alpha_test_op_dest, alpha_test_mask_src,
|
||||
dxbc::Src::LU(uint32_t(xenos::CompareFunction::kNotEqual)));
|
||||
a_.OpIf(true, alpha_test_op_src);
|
||||
{ a_.OpNE(alpha_test_mask_dest, alpha_src, alpha_test_reference_src); }
|
||||
a_.OpElse();
|
||||
{
|
||||
// Less than.
|
||||
a_.OpLT(alpha_test_op_dest, alpha_src, alpha_test_reference_src);
|
||||
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
|
||||
dxbc::Src::LU(~uint32_t(1 << 0)));
|
||||
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
|
||||
// Equals to.
|
||||
a_.OpEq(alpha_test_op_dest, alpha_src, alpha_test_reference_src);
|
||||
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
|
||||
dxbc::Src::LU(~uint32_t(1 << 1)));
|
||||
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
|
||||
// Greater than.
|
||||
a_.OpLT(alpha_test_op_dest, alpha_test_reference_src, alpha_src);
|
||||
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
|
||||
dxbc::Src::LU(~uint32_t(1 << 2)));
|
||||
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
|
||||
}
|
||||
// Close the "not equal" check.
|
||||
a_.OpEndIf();
|
||||
// Discard the pixel if it has failed the test.
|
||||
if (edram_rov_used_) {
|
||||
a_.OpRetC(false, alpha_test_mask_src);
|
||||
|
||||
@@ -656,6 +656,13 @@ bool TextureCache::LoadTextureData(Texture& texture) {
|
||||
|
||||
TextureKey texture_key = texture.key();
|
||||
|
||||
// Implementation may load multiple blocks at once via accesses of up to 128
|
||||
// bits (R32G32B32A32_UINT), so aligning the size to this value to make sure
|
||||
// if the texture is small (especially if it's linear), the last blocks won't
|
||||
// be cut off (hosts may return 0, 0, 0, 0 for the whole R32G32B32A32_UINT
|
||||
// access for the non-16-aligned tail even if 1...15 bytes are actually
|
||||
// provided for it).
|
||||
|
||||
// Request uploading of the texture data to the shared memory.
|
||||
// This is also necessary when resolution scaling is used - the texture cache
|
||||
// relies on shared memory for invalidation of both unscaled and scaled
|
||||
@@ -666,7 +673,8 @@ bool TextureCache::LoadTextureData(Texture& texture) {
|
||||
bool base_resolved = texture.GetBaseResolved();
|
||||
if (base_outdated) {
|
||||
if (!shared_memory().RequestRange(
|
||||
texture_key.base_page << 12, texture.GetGuestBaseSize(),
|
||||
texture_key.base_page << 12,
|
||||
xe::align(texture.GetGuestBaseSize(), UINT32_C(16)),
|
||||
texture_key.scaled_resolve ? nullptr : &base_resolved)) {
|
||||
return false;
|
||||
}
|
||||
@@ -674,7 +682,8 @@ bool TextureCache::LoadTextureData(Texture& texture) {
|
||||
bool mips_resolved = texture.GetMipsResolved();
|
||||
if (mips_outdated) {
|
||||
if (!shared_memory().RequestRange(
|
||||
texture_key.mip_page << 12, texture.GetGuestMipsSize(),
|
||||
texture_key.mip_page << 12,
|
||||
xe::align(texture.GetGuestMipsSize(), UINT32_C(16)),
|
||||
texture_key.scaled_resolve ? nullptr : &mips_resolved)) {
|
||||
return false;
|
||||
}
|
||||
@@ -685,11 +694,11 @@ bool TextureCache::LoadTextureData(Texture& texture) {
|
||||
// by an actual resolve, but is still included in the texture size, so the
|
||||
// GPU won't be trying to access unmapped memory.
|
||||
if (!EnsureScaledResolveMemoryCommitted(texture_key.base_page << 12,
|
||||
texture.GetGuestBaseSize())) {
|
||||
texture.GetGuestBaseSize(), 4)) {
|
||||
return false;
|
||||
}
|
||||
if (!EnsureScaledResolveMemoryCommitted(texture_key.mip_page << 12,
|
||||
texture.GetGuestMipsSize())) {
|
||||
texture.GetGuestMipsSize(), 4)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,8 +82,9 @@ class TextureCache {
|
||||
void MarkRangeAsResolved(uint32_t start_unscaled, uint32_t length_unscaled);
|
||||
// Ensures the memory backing the range in the scaled resolve address space is
|
||||
// allocated and returns whether it is.
|
||||
virtual bool EnsureScaledResolveMemoryCommitted(uint32_t start_unscaled,
|
||||
uint32_t length_unscaled) {
|
||||
virtual bool EnsureScaledResolveMemoryCommitted(
|
||||
uint32_t start_unscaled, uint32_t length_unscaled,
|
||||
uint32_t length_scaled_alignment_log2 = 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,19 +89,15 @@ void TracePlayer::PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
||||
TracePlaybackMode playback_mode,
|
||||
bool clear_caches) {
|
||||
playing_trace_ = true;
|
||||
// Pass a copy of present_last_copy_ to the thread so it's not accessible by
|
||||
// multiple threads at once.
|
||||
bool present_last_copy = present_last_copy_;
|
||||
graphics_system_->command_processor()->CallInThread([=]() {
|
||||
PlayTraceOnThread(trace_data, trace_size, playback_mode, clear_caches,
|
||||
present_last_copy);
|
||||
PlayTraceOnThread(trace_data, trace_size, playback_mode, clear_caches);
|
||||
});
|
||||
}
|
||||
|
||||
void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data,
|
||||
size_t trace_size,
|
||||
TracePlaybackMode playback_mode,
|
||||
bool clear_caches, bool present_last_copy) {
|
||||
bool clear_caches) {
|
||||
auto memory = graphics_system_->memory();
|
||||
auto command_processor = graphics_system_->command_processor();
|
||||
|
||||
@@ -109,10 +105,6 @@ void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data,
|
||||
command_processor->ClearCaches();
|
||||
}
|
||||
|
||||
if (present_last_copy) {
|
||||
command_processor->SetIgnoreSwap(true);
|
||||
}
|
||||
|
||||
playback_percent_ = 0;
|
||||
auto trace_end = trace_data + trace_size;
|
||||
|
||||
@@ -252,11 +244,6 @@ void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data,
|
||||
|
||||
playing_trace_ = false;
|
||||
|
||||
if (present_last_copy) {
|
||||
command_processor->SetIgnoreSwap(false);
|
||||
command_processor->IssueSwap(0, 1280, 720);
|
||||
}
|
||||
|
||||
playback_event_->Set();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,6 @@ class TracePlayer : public TraceReader {
|
||||
TracePlayer(GraphicsSystem* graphics_system);
|
||||
|
||||
GraphicsSystem* graphics_system() const { return graphics_system_; }
|
||||
void SetPresentLastCopy(bool present_last_copy) {
|
||||
present_last_copy_ = present_last_copy;
|
||||
}
|
||||
int current_frame_index() const { return current_frame_index_; }
|
||||
int current_command_index() const { return current_command_index_; }
|
||||
bool is_playing_trace() const { return playing_trace_; }
|
||||
@@ -53,13 +50,9 @@ class TracePlayer : public TraceReader {
|
||||
void PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
||||
TracePlaybackMode playback_mode, bool clear_caches);
|
||||
void PlayTraceOnThread(const uint8_t* trace_data, size_t trace_size,
|
||||
TracePlaybackMode playback_mode, bool clear_caches,
|
||||
bool present_last_copy);
|
||||
TracePlaybackMode playback_mode, bool clear_caches);
|
||||
|
||||
GraphicsSystem* graphics_system_;
|
||||
// Whether to present the results of the latest resolve instead of displaying
|
||||
// the front buffer from the trace.
|
||||
bool present_last_copy_ = false;
|
||||
int current_frame_index_;
|
||||
int current_command_index_;
|
||||
bool playing_trace_ = false;
|
||||
|
||||
@@ -114,7 +114,7 @@ bool TraceViewer::Setup() {
|
||||
// Main display window.
|
||||
assert_true(app_context().IsInUIThread());
|
||||
window_ = xe::ui::Window::Create(app_context(), "xenia-gpu-trace-viewer",
|
||||
1920, 1200);
|
||||
1920, 1080);
|
||||
window_->AddListener(&window_listener_);
|
||||
window_->AddInputListener(&window_listener_, kZOrderTraceViewerInput);
|
||||
if (!window_->Open()) {
|
||||
@@ -135,28 +135,27 @@ bool TraceViewer::Setup() {
|
||||
graphics_system_ = emulator_->graphics_system();
|
||||
|
||||
player_ = std::make_unique<TracePlayer>(graphics_system_);
|
||||
player_->SetPresentLastCopy(true);
|
||||
|
||||
// Setup drawing to the window.
|
||||
xe::ui::GraphicsProvider& graphics_provider = *graphics_system_->provider();
|
||||
presenter_ = graphics_provider.CreatePresenter();
|
||||
if (!presenter_) {
|
||||
ui::Presenter* presenter = graphics_system_->presenter();
|
||||
if (!presenter) {
|
||||
XELOGE("Failed to initialize the presenter");
|
||||
return false;
|
||||
}
|
||||
xe::ui::GraphicsProvider& graphics_provider = *graphics_system_->provider();
|
||||
immediate_drawer_ = graphics_provider.CreateImmediateDrawer();
|
||||
if (!immediate_drawer_) {
|
||||
XELOGE("Failed to initialize the immediate drawer");
|
||||
return false;
|
||||
}
|
||||
immediate_drawer_->SetPresenter(presenter_.get());
|
||||
immediate_drawer_->SetPresenter(presenter);
|
||||
imgui_drawer_ =
|
||||
std::make_unique<xe::ui::ImGuiDrawer>(window_.get(), kZOrderImGui);
|
||||
imgui_drawer_->SetPresenterAndImmediateDrawer(presenter_.get(),
|
||||
imgui_drawer_->SetPresenterAndImmediateDrawer(presenter,
|
||||
immediate_drawer_.get());
|
||||
trace_viewer_dialog_ = std::unique_ptr<TraceViewerDialog>(
|
||||
new TraceViewerDialog(imgui_drawer_.get(), *this));
|
||||
window_->SetPresenter(presenter_.get());
|
||||
window_->SetPresenter(presenter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "xenia/ui/imgui_dialog.h"
|
||||
#include "xenia/ui/imgui_drawer.h"
|
||||
#include "xenia/ui/immediate_drawer.h"
|
||||
#include "xenia/ui/presenter.h"
|
||||
#include "xenia/ui/window.h"
|
||||
#include "xenia/ui/window_listener.h"
|
||||
#include "xenia/ui/windowed_app.h"
|
||||
@@ -129,7 +128,6 @@ class TraceViewer : public xe::ui::WindowedApp {
|
||||
GraphicsSystem* graphics_system_ = nullptr;
|
||||
std::unique_ptr<TracePlayer> player_;
|
||||
|
||||
std::unique_ptr<xe::ui::Presenter> presenter_;
|
||||
std::unique_ptr<xe::ui::ImmediateDrawer> immediate_drawer_;
|
||||
std::unique_ptr<xe::ui::ImGuiDrawer> imgui_drawer_;
|
||||
std::unique_ptr<TraceViewerDialog> trace_viewer_dialog_;
|
||||
|
||||
@@ -269,11 +269,6 @@ void VulkanCommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frontbuffer_ptr) {
|
||||
// Trace viewer does this.
|
||||
frontbuffer_ptr = last_copy_base_;
|
||||
}
|
||||
|
||||
std::vector<VkCommandBuffer> submit_buffers;
|
||||
if (frame_open_) {
|
||||
// TODO(DrChat): If the setup buffer is empty, don't bother queueing it up.
|
||||
@@ -1108,9 +1103,6 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
|
||||
texture->in_flight_fence = current_batch_fence_;
|
||||
|
||||
// For debugging purposes only (trace viewer)
|
||||
last_copy_base_ = texture->texture_info.memory.base_address;
|
||||
|
||||
if (!frame_open_) {
|
||||
BeginFrame();
|
||||
} else if (current_render_state_) {
|
||||
|
||||
@@ -106,9 +106,6 @@ class VulkanCommandProcessor : public CommandProcessor {
|
||||
uint32_t coher_base_vc_ = 0;
|
||||
uint32_t coher_size_vc_ = 0;
|
||||
|
||||
// Last copy base address, for debugging only.
|
||||
uint32_t last_copy_base_ = 0;
|
||||
|
||||
bool capturing_ = false;
|
||||
bool trace_requested_ = false;
|
||||
bool cache_clear_requested_ = false;
|
||||
|
||||
Reference in New Issue
Block a user