video_core: Remove all Core::System references in renderer
Now that the GPU is initialized when video backends are initialized, it's no longer needed to query components once the game is running: it can be done when yuzu is booting. This allows us to pass components between constructors and in the process remove all Core::System references in the video backend.
This commit is contained in:
parent
045f50bc7f
commit
9e87193725
53 changed files with 573 additions and 633 deletions
|
@ -59,9 +59,10 @@ void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst
|
|||
static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
|
||||
}
|
||||
|
||||
OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system,
|
||||
OGLBufferCache::OGLBufferCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
|
||||
const Device& device_, std::size_t stream_size)
|
||||
: GenericBufferCache{rasterizer, system,
|
||||
: GenericBufferCache{rasterizer, gpu_memory, cpu_memory,
|
||||
std::make_unique<OGLStreamBuffer>(device_, stream_size, true)},
|
||||
device{device_} {
|
||||
if (!device.HasFastBufferSubData()) {
|
||||
|
|
|
@ -52,7 +52,8 @@ private:
|
|||
using GenericBufferCache = VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>;
|
||||
class OGLBufferCache final : public GenericBufferCache {
|
||||
public:
|
||||
explicit OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system,
|
||||
explicit OGLBufferCache(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
|
||||
const Device& device, std::size_t stream_size);
|
||||
~OGLBufferCache();
|
||||
|
||||
|
|
|
@ -45,11 +45,10 @@ void GLInnerFence::Wait() {
|
|||
glClientWaitSync(sync_object.handle, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system,
|
||||
VideoCore::RasterizerInterface& rasterizer,
|
||||
FenceManagerOpenGL::FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
|
||||
TextureCacheOpenGL& texture_cache,
|
||||
OGLBufferCache& buffer_cache, QueryCache& query_cache)
|
||||
: GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache) {}
|
||||
: GenericFenceManager{rasterizer, gpu, texture_cache, buffer_cache, query_cache} {}
|
||||
|
||||
Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) {
|
||||
return std::make_shared<GLInnerFence>(value, is_stubbed);
|
||||
|
|
|
@ -37,9 +37,9 @@ using GenericFenceManager =
|
|||
|
||||
class FenceManagerOpenGL final : public GenericFenceManager {
|
||||
public:
|
||||
FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache,
|
||||
QueryCache& query_cache);
|
||||
explicit FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
|
||||
TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache,
|
||||
QueryCache& query_cache);
|
||||
|
||||
protected:
|
||||
Fence CreateFence(u32 value, bool is_stubbed) override;
|
||||
|
|
|
@ -30,12 +30,13 @@ constexpr GLenum GetTarget(VideoCore::QueryType type) {
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
QueryCache::QueryCache(Core::System& system, RasterizerOpenGL& gl_rasterizer)
|
||||
QueryCache::QueryCache(RasterizerOpenGL& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::MemoryManager& gpu_memory)
|
||||
: VideoCommon::QueryCacheBase<
|
||||
QueryCache, CachedQuery, CounterStream, HostCounter,
|
||||
std::vector<OGLQuery>>{system,
|
||||
static_cast<VideoCore::RasterizerInterface&>(gl_rasterizer)},
|
||||
gl_rasterizer{gl_rasterizer} {}
|
||||
std::vector<OGLQuery>>{static_cast<VideoCore::RasterizerInterface&>(rasterizer),
|
||||
maxwell3d, gpu_memory},
|
||||
gl_rasterizer{rasterizer} {}
|
||||
|
||||
QueryCache::~QueryCache() = default;
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ using CounterStream = VideoCommon::CounterStreamBase<QueryCache, HostCounter>;
|
|||
class QueryCache final : public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream,
|
||||
HostCounter, std::vector<OGLQuery>> {
|
||||
public:
|
||||
explicit QueryCache(Core::System& system, RasterizerOpenGL& rasterizer);
|
||||
explicit QueryCache(RasterizerOpenGL& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::MemoryManager& gpu_memory);
|
||||
~QueryCache();
|
||||
|
||||
OGLQuery AllocateQuery(VideoCore::QueryType type);
|
||||
|
|
|
@ -153,16 +153,19 @@ void UpdateBindlessPointers(GLenum target, GLuint64EXT* pointers, std::size_t nu
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||
const Device& device, ScreenInfo& info,
|
||||
ProgramManager& program_manager, StateTracker& state_tracker)
|
||||
: RasterizerAccelerated{system.Memory()}, device{device}, texture_cache{system, *this, device,
|
||||
state_tracker},
|
||||
shader_cache{*this, system, emu_window, device}, query_cache{system, *this},
|
||||
buffer_cache{*this, system, device, STREAM_BUFFER_SIZE},
|
||||
fence_manager{system, *this, texture_cache, buffer_cache, query_cache}, system{system},
|
||||
screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker},
|
||||
async_shaders{emu_window} {
|
||||
RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu_,
|
||||
Core::Memory::Memory& cpu_memory, const Device& device_,
|
||||
ScreenInfo& screen_info_, ProgramManager& program_manager_,
|
||||
StateTracker& state_tracker_)
|
||||
: RasterizerAccelerated{cpu_memory}, gpu(gpu_), maxwell3d(gpu.Maxwell3D()),
|
||||
kepler_compute(gpu.KeplerCompute()), gpu_memory(gpu.MemoryManager()), device(device_),
|
||||
screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_),
|
||||
texture_cache(*this, maxwell3d, gpu_memory, device, state_tracker),
|
||||
shader_cache(*this, emu_window, gpu, maxwell3d, kepler_compute, gpu_memory, device),
|
||||
query_cache(*this, maxwell3d, gpu_memory),
|
||||
buffer_cache(*this, gpu_memory, cpu_memory, device, STREAM_BUFFER_SIZE),
|
||||
fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache),
|
||||
async_shaders(emu_window) {
|
||||
CheckExtensions();
|
||||
|
||||
unified_uniform_buffer.Create();
|
||||
|
@ -196,8 +199,7 @@ void RasterizerOpenGL::CheckExtensions() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SetupVertexFormat() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::VertexFormats]) {
|
||||
return;
|
||||
}
|
||||
|
@ -217,7 +219,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
|
|||
}
|
||||
flags[Dirty::VertexFormat0 + index] = false;
|
||||
|
||||
const auto attrib = gpu.regs.vertex_attrib_format[index];
|
||||
const auto attrib = maxwell3d.regs.vertex_attrib_format[index];
|
||||
const auto gl_index = static_cast<GLuint>(index);
|
||||
|
||||
// Disable constant attributes.
|
||||
|
@ -241,8 +243,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SetupVertexBuffer() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::VertexBuffers]) {
|
||||
return;
|
||||
}
|
||||
|
@ -253,7 +254,7 @@ void RasterizerOpenGL::SetupVertexBuffer() {
|
|||
const bool use_unified_memory = device.HasVertexBufferUnifiedMemory();
|
||||
|
||||
// Upload all guest vertex arrays sequentially to our buffer
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_BINDINGS; ++index) {
|
||||
if (!flags[Dirty::VertexBuffer0 + index]) {
|
||||
continue;
|
||||
|
@ -290,14 +291,13 @@ void RasterizerOpenGL::SetupVertexBuffer() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SetupVertexInstances() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::VertexInstances]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::VertexInstances] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {
|
||||
if (!flags[Dirty::VertexInstance0 + index]) {
|
||||
continue;
|
||||
|
@ -313,7 +313,7 @@ void RasterizerOpenGL::SetupVertexInstances() {
|
|||
|
||||
GLintptr RasterizerOpenGL::SetupIndexBuffer() {
|
||||
MICROPROFILE_SCOPE(OpenGL_Index);
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
const std::size_t size = CalculateIndexBufferSize();
|
||||
const auto info = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, info.handle);
|
||||
|
@ -322,15 +322,14 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
|
|||
|
||||
void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
|
||||
MICROPROFILE_SCOPE(OpenGL_Shader);
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
u32 clip_distances = 0;
|
||||
|
||||
for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
|
||||
const auto& shader_config = gpu.regs.shader_config[index];
|
||||
const auto& shader_config = maxwell3d.regs.shader_config[index];
|
||||
const auto program{static_cast<Maxwell::ShaderProgram>(index)};
|
||||
|
||||
// Skip stages that are not enabled
|
||||
if (!gpu.regs.IsShaderConfigEnabled(index)) {
|
||||
if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
|
||||
switch (program) {
|
||||
case Maxwell::ShaderProgram::Geometry:
|
||||
program_manager.UseGeometryShader(0);
|
||||
|
@ -391,11 +390,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
|
|||
}
|
||||
|
||||
SyncClipEnabled(clip_distances);
|
||||
gpu.dirty.flags[Dirty::Shaders] = false;
|
||||
maxwell3d.dirty.flags[Dirty::Shaders] = false;
|
||||
}
|
||||
|
||||
std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
std::size_t size = 0;
|
||||
for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||
|
@ -413,34 +412,27 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
|
|||
}
|
||||
|
||||
std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
|
||||
return static_cast<std::size_t>(regs.index_array.count) *
|
||||
static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
|
||||
return static_cast<std::size_t>(maxwell3d.regs.index_array.count) *
|
||||
static_cast<std::size_t>(maxwell3d.regs.index_array.FormatSizeInBytes());
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||
void RasterizerOpenGL::LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
|
||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||
shader_cache.LoadDiskCache(stop_loading, callback);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SetupDirtyFlags() {
|
||||
state_tracker.Initialize();
|
||||
shader_cache.LoadDiskCache(title_id, stop_loading, callback);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::ConfigureFramebuffers() {
|
||||
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
if (!gpu.dirty.flags[VideoCommon::Dirty::RenderTargets]) {
|
||||
if (!maxwell3d.dirty.flags[VideoCommon::Dirty::RenderTargets]) {
|
||||
return;
|
||||
}
|
||||
gpu.dirty.flags[VideoCommon::Dirty::RenderTargets] = false;
|
||||
maxwell3d.dirty.flags[VideoCommon::Dirty::RenderTargets] = false;
|
||||
|
||||
texture_cache.GuardRenderTargets(true);
|
||||
|
||||
View depth_surface = texture_cache.GetDepthBufferSurface(true);
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0);
|
||||
|
||||
// Bind the framebuffer surfaces
|
||||
|
@ -472,8 +464,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil) {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
texture_cache.GuardRenderTargets(true);
|
||||
View color_surface;
|
||||
|
@ -523,12 +514,11 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_de
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::Clear() {
|
||||
const auto& gpu = system.GPU().Maxwell3D();
|
||||
if (!gpu.ShouldExecute()) {
|
||||
if (!maxwell3d.ShouldExecute()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
bool use_color{};
|
||||
bool use_depth{};
|
||||
bool use_stencil{};
|
||||
|
@ -593,7 +583,6 @@ void RasterizerOpenGL::Clear() {
|
|||
|
||||
void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||
MICROPROFILE_SCOPE(OpenGL_Drawing);
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
|
||||
query_cache.UpdateCounters();
|
||||
|
||||
|
@ -641,7 +630,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
|
||||
if (invalidated) {
|
||||
// When the stream buffer has been invalidated, we have to consider vertex buffers as dirty
|
||||
auto& dirty = gpu.dirty.flags;
|
||||
auto& dirty = maxwell3d.dirty.flags;
|
||||
dirty[Dirty::VertexBuffers] = true;
|
||||
for (int index = Dirty::VertexBuffer0; index <= Dirty::VertexBuffer31; ++index) {
|
||||
dirty[index] = true;
|
||||
|
@ -662,7 +651,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
// Setup emulation uniform buffer.
|
||||
if (!device.UseAssemblyShaders()) {
|
||||
MaxwellUniformData ubo;
|
||||
ubo.SetFromRegs(gpu);
|
||||
ubo.SetFromRegs(maxwell3d);
|
||||
const auto info =
|
||||
buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, info.handle, info.offset,
|
||||
|
@ -671,7 +660,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
|
||||
// Setup shaders and their used resources.
|
||||
texture_cache.GuardSamplers(true);
|
||||
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(gpu.regs.draw.topology);
|
||||
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology);
|
||||
SetupShaders(primitive_mode);
|
||||
texture_cache.GuardSamplers(false);
|
||||
|
||||
|
@ -688,14 +677,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
|
||||
BeginTransformFeedback(primitive_mode);
|
||||
|
||||
const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance);
|
||||
const GLuint base_instance = static_cast<GLuint>(maxwell3d.regs.vb_base_instance);
|
||||
const GLsizei num_instances =
|
||||
static_cast<GLsizei>(is_instanced ? gpu.mme_draw.instance_count : 1);
|
||||
static_cast<GLsizei>(is_instanced ? maxwell3d.mme_draw.instance_count : 1);
|
||||
if (is_indexed) {
|
||||
const GLint base_vertex = static_cast<GLint>(gpu.regs.vb_element_base);
|
||||
const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.index_array.count);
|
||||
const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vb_element_base);
|
||||
const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.index_array.count);
|
||||
const GLvoid* offset = reinterpret_cast<const GLvoid*>(index_buffer_offset);
|
||||
const GLenum format = MaxwellToGL::IndexFormat(gpu.regs.index_array.format);
|
||||
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d.regs.index_array.format);
|
||||
if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {
|
||||
glDrawElements(primitive_mode, num_vertices, format, offset);
|
||||
} else if (num_instances == 1 && base_instance == 0) {
|
||||
|
@ -714,8 +703,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
base_instance);
|
||||
}
|
||||
} else {
|
||||
const GLint base_vertex = static_cast<GLint>(gpu.regs.vertex_buffer.first);
|
||||
const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.vertex_buffer.count);
|
||||
const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vertex_buffer.first);
|
||||
const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.vertex_buffer.count);
|
||||
if (num_instances == 1 && base_instance == 0) {
|
||||
glDrawArrays(primitive_mode, base_vertex, num_vertices);
|
||||
} else if (base_instance == 0) {
|
||||
|
@ -730,7 +719,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
|
||||
++num_queued_commands;
|
||||
|
||||
system.GPU().TickWork();
|
||||
gpu.TickWork();
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
|
||||
|
@ -753,7 +742,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
|
|||
|
||||
buffer_cache.Unmap();
|
||||
|
||||
const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
|
||||
const auto& launch_desc = kepler_compute.launch_description;
|
||||
program_manager.BindCompute(kernel->GetHandle());
|
||||
glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
|
||||
++num_queued_commands;
|
||||
}
|
||||
|
@ -815,17 +805,14 @@ void RasterizerOpenGL::SyncGuestHost() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) {
|
||||
auto& gpu{system.GPU()};
|
||||
if (!gpu.IsAsync()) {
|
||||
auto& memory_manager{gpu.MemoryManager()};
|
||||
memory_manager.Write<u32>(addr, value);
|
||||
gpu_memory.Write<u32>(addr, value);
|
||||
return;
|
||||
}
|
||||
fence_manager.SignalSemaphore(addr, value);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SignalSyncPoint(u32 value) {
|
||||
auto& gpu{system.GPU()};
|
||||
if (!gpu.IsAsync()) {
|
||||
gpu.IncrementSyncPoint(value);
|
||||
return;
|
||||
|
@ -834,7 +821,6 @@ void RasterizerOpenGL::SignalSyncPoint(u32 value) {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::ReleaseFences() {
|
||||
auto& gpu{system.GPU()};
|
||||
if (!gpu.IsAsync()) {
|
||||
return;
|
||||
}
|
||||
|
@ -920,7 +906,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh
|
|||
GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV};
|
||||
|
||||
MICROPROFILE_SCOPE(OpenGL_UBO);
|
||||
const auto& stages = system.GPU().Maxwell3D().state.shader_stages;
|
||||
const auto& stages = maxwell3d.state.shader_stages;
|
||||
const auto& shader_stage = stages[stage_index];
|
||||
const auto& entries = shader->GetEntries();
|
||||
const bool use_unified = entries.use_unified_uniforms;
|
||||
|
@ -945,7 +931,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh
|
|||
|
||||
void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) {
|
||||
MICROPROFILE_SCOPE(OpenGL_UBO);
|
||||
const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
|
||||
const auto& launch_desc = kepler_compute.launch_description;
|
||||
const auto& entries = kernel->GetEntries();
|
||||
const bool use_unified = entries.use_unified_uniforms;
|
||||
|
||||
|
@ -1018,9 +1004,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
|
|||
GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV,
|
||||
};
|
||||
|
||||
auto& gpu{system.GPU()};
|
||||
auto& memory_manager{gpu.MemoryManager()};
|
||||
const auto& cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]};
|
||||
const auto& cbufs{maxwell3d.state.shader_stages[stage_index]};
|
||||
const auto& entries{shader->GetEntries().global_memory_entries};
|
||||
|
||||
std::array<GLuint64EXT, 32> pointers;
|
||||
|
@ -1030,8 +1014,8 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
|
|||
u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer;
|
||||
for (const auto& entry : entries) {
|
||||
const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset};
|
||||
const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)};
|
||||
const u32 size{memory_manager.Read<u32>(addr + 8)};
|
||||
const GPUVAddr gpu_addr{gpu_memory.Read<u64>(addr)};
|
||||
const u32 size{gpu_memory.Read<u32>(addr + 8)};
|
||||
SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]);
|
||||
++binding;
|
||||
}
|
||||
|
@ -1041,9 +1025,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
|
||||
auto& gpu{system.GPU()};
|
||||
auto& memory_manager{gpu.MemoryManager()};
|
||||
const auto& cbufs{gpu.KeplerCompute().launch_description.const_buffer_config};
|
||||
const auto& cbufs{kepler_compute.launch_description.const_buffer_config};
|
||||
const auto& entries{kernel->GetEntries().global_memory_entries};
|
||||
|
||||
std::array<GLuint64EXT, 32> pointers;
|
||||
|
@ -1052,8 +1034,8 @@ void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
|
|||
u32 binding = 0;
|
||||
for (const auto& entry : entries) {
|
||||
const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset};
|
||||
const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)};
|
||||
const u32 size{memory_manager.Read<u32>(addr + 8)};
|
||||
const GPUVAddr gpu_addr{gpu_memory.Read<u64>(addr)};
|
||||
const u32 size{gpu_memory.Read<u32>(addr + 8)};
|
||||
SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]);
|
||||
++binding;
|
||||
}
|
||||
|
@ -1077,7 +1059,6 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
|
|||
|
||||
void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) {
|
||||
MICROPROFILE_SCOPE(OpenGL_Texture);
|
||||
const auto& maxwell3d = system.GPU().Maxwell3D();
|
||||
u32 binding = device.GetBaseBindings(stage_index).sampler;
|
||||
for (const auto& entry : shader->GetEntries().samplers) {
|
||||
const auto shader_type = static_cast<ShaderType>(stage_index);
|
||||
|
@ -1090,11 +1071,10 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader
|
|||
|
||||
void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) {
|
||||
MICROPROFILE_SCOPE(OpenGL_Texture);
|
||||
const auto& compute = system.GPU().KeplerCompute();
|
||||
u32 binding = 0;
|
||||
for (const auto& entry : kernel->GetEntries().samplers) {
|
||||
for (std::size_t i = 0; i < entry.size; ++i) {
|
||||
const auto texture = GetTextureInfo(compute, entry, ShaderType::Compute, i);
|
||||
const auto texture = GetTextureInfo(kepler_compute, entry, ShaderType::Compute, i);
|
||||
SetupTexture(binding++, texture, entry);
|
||||
}
|
||||
}
|
||||
|
@ -1118,20 +1098,18 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) {
|
||||
const auto& maxwell3d = system.GPU().Maxwell3D();
|
||||
u32 binding = device.GetBaseBindings(stage_index).image;
|
||||
for (const auto& entry : shader->GetEntries().images) {
|
||||
const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index);
|
||||
const auto shader_type = static_cast<ShaderType>(stage_index);
|
||||
const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic;
|
||||
SetupImage(binding++, tic, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SetupComputeImages(Shader* shader) {
|
||||
const auto& compute = system.GPU().KeplerCompute();
|
||||
u32 binding = 0;
|
||||
for (const auto& entry : shader->GetEntries().images) {
|
||||
const auto tic = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute).tic;
|
||||
const auto tic = GetTextureInfo(kepler_compute, entry, ShaderType::Compute).tic;
|
||||
SetupImage(binding++, tic, entry);
|
||||
}
|
||||
}
|
||||
|
@ -1151,9 +1129,8 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncViewport() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
const auto& regs = gpu.regs;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
const bool dirty_viewport = flags[Dirty::Viewports];
|
||||
const bool dirty_clip_control = flags[Dirty::ClipControl];
|
||||
|
@ -1225,25 +1202,23 @@ void RasterizerOpenGL::SyncViewport() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncDepthClamp() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::DepthClampEnabled]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::DepthClampEnabled] = false;
|
||||
|
||||
oglEnable(GL_DEPTH_CLAMP, gpu.regs.view_volume_clip_control.depth_clamp_disabled == 0);
|
||||
oglEnable(GL_DEPTH_CLAMP, maxwell3d.regs.view_volume_clip_control.depth_clamp_disabled == 0);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::ClipDistances] = false;
|
||||
|
||||
clip_mask &= gpu.regs.clip_distance_enabled;
|
||||
clip_mask &= maxwell3d.regs.clip_distance_enabled;
|
||||
if (clip_mask == last_clip_distance_mask) {
|
||||
return;
|
||||
}
|
||||
|
@ -1259,9 +1234,8 @@ void RasterizerOpenGL::SyncClipCoef() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncCullMode() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
const auto& regs = gpu.regs;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
if (flags[Dirty::CullTest]) {
|
||||
flags[Dirty::CullTest] = false;
|
||||
|
@ -1276,26 +1250,24 @@ void RasterizerOpenGL::SyncCullMode() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncPrimitiveRestart() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::PrimitiveRestart]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::PrimitiveRestart] = false;
|
||||
|
||||
if (gpu.regs.primitive_restart.enabled) {
|
||||
if (maxwell3d.regs.primitive_restart.enabled) {
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(gpu.regs.primitive_restart.index);
|
||||
glPrimitiveRestartIndex(maxwell3d.regs.primitive_restart.index);
|
||||
} else {
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncDepthTestState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
if (flags[Dirty::DepthMask]) {
|
||||
flags[Dirty::DepthMask] = false;
|
||||
glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE);
|
||||
|
@ -1313,14 +1285,13 @@ void RasterizerOpenGL::SyncDepthTestState() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncStencilTestState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::StencilTest]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::StencilTest] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
oglEnable(GL_STENCIL_TEST, regs.stencil_enable);
|
||||
|
||||
glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func),
|
||||
|
@ -1345,25 +1316,24 @@ void RasterizerOpenGL::SyncStencilTestState() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncRasterizeEnable() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::RasterizeEnable]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::RasterizeEnable] = false;
|
||||
|
||||
oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
|
||||
oglEnable(GL_RASTERIZER_DISCARD, maxwell3d.regs.rasterize_enable == 0);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncPolygonModes() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::PolygonModes]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::PolygonModes] = false;
|
||||
|
||||
if (gpu.regs.fill_rectangle) {
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.fill_rectangle) {
|
||||
if (!GLAD_GL_NV_fill_rectangle) {
|
||||
LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
@ -1376,27 +1346,26 @@ void RasterizerOpenGL::SyncPolygonModes() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) {
|
||||
if (regs.polygon_mode_front == regs.polygon_mode_back) {
|
||||
flags[Dirty::PolygonModeFront] = false;
|
||||
flags[Dirty::PolygonModeBack] = false;
|
||||
glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
|
||||
glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(regs.polygon_mode_front));
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags[Dirty::PolygonModeFront]) {
|
||||
flags[Dirty::PolygonModeFront] = false;
|
||||
glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
|
||||
glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(regs.polygon_mode_front));
|
||||
}
|
||||
|
||||
if (flags[Dirty::PolygonModeBack]) {
|
||||
flags[Dirty::PolygonModeBack] = false;
|
||||
glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back));
|
||||
glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(regs.polygon_mode_back));
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncColorMask() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::ColorMasks]) {
|
||||
return;
|
||||
}
|
||||
|
@ -1405,7 +1374,7 @@ void RasterizerOpenGL::SyncColorMask() {
|
|||
const bool force = flags[Dirty::ColorMaskCommon];
|
||||
flags[Dirty::ColorMaskCommon] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.color_mask_common) {
|
||||
if (!force && !flags[Dirty::ColorMask0]) {
|
||||
return;
|
||||
|
@ -1430,33 +1399,30 @@ void RasterizerOpenGL::SyncColorMask() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncMultiSampleState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::MultisampleControl]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::MultisampleControl] = false;
|
||||
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage);
|
||||
oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncFragmentColorClampState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::FragmentClampColor]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::FragmentClampColor] = false;
|
||||
|
||||
glClampColor(GL_CLAMP_FRAGMENT_COLOR, gpu.regs.frag_color_clamp ? GL_TRUE : GL_FALSE);
|
||||
glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d.regs.frag_color_clamp ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
const auto& regs = gpu.regs;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
if (flags[Dirty::BlendColor]) {
|
||||
flags[Dirty::BlendColor] = false;
|
||||
|
@ -1513,14 +1479,13 @@ void RasterizerOpenGL::SyncBlendState() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncLogicOpState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::LogicOp]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::LogicOp] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.logic_op.enable) {
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation));
|
||||
|
@ -1530,14 +1495,13 @@ void RasterizerOpenGL::SyncLogicOpState() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncScissorTest() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::Scissors]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::Scissors] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) {
|
||||
if (!flags[Dirty::Scissor0 + index]) {
|
||||
continue;
|
||||
|
@ -1556,16 +1520,15 @@ void RasterizerOpenGL::SyncScissorTest() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncPointState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::PointSize]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::PointSize] = false;
|
||||
|
||||
oglEnable(GL_POINT_SPRITE, gpu.regs.point_sprite_enable);
|
||||
oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable);
|
||||
|
||||
if (gpu.regs.vp_point_size.enable) {
|
||||
if (maxwell3d.regs.vp_point_size.enable) {
|
||||
// By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled.
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
return;
|
||||
|
@ -1573,32 +1536,30 @@ void RasterizerOpenGL::SyncPointState() {
|
|||
|
||||
// Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid
|
||||
// in OpenGL).
|
||||
glPointSize(std::max(1.0f, gpu.regs.point_size));
|
||||
glPointSize(std::max(1.0f, maxwell3d.regs.point_size));
|
||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncLineState() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::LineWidth]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::LineWidth] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable);
|
||||
glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncPolygonOffset() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::PolygonOffset]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::PolygonOffset] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable);
|
||||
oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable);
|
||||
oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable);
|
||||
|
@ -1612,14 +1573,13 @@ void RasterizerOpenGL::SyncPolygonOffset() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncAlphaTest() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::AlphaTest]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::AlphaTest] = false;
|
||||
|
||||
const auto& regs = gpu.regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.alpha_test_enabled && regs.rt_control.count > 1) {
|
||||
LOG_WARNING(Render_OpenGL, "Alpha testing with more than one render target is not tested");
|
||||
}
|
||||
|
@ -1633,20 +1593,19 @@ void RasterizerOpenGL::SyncAlphaTest() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncFramebufferSRGB() {
|
||||
auto& gpu = system.GPU().Maxwell3D();
|
||||
auto& flags = gpu.dirty.flags;
|
||||
auto& flags = maxwell3d.dirty.flags;
|
||||
if (!flags[Dirty::FramebufferSRGB]) {
|
||||
return;
|
||||
}
|
||||
flags[Dirty::FramebufferSRGB] = false;
|
||||
|
||||
oglEnable(GL_FRAMEBUFFER_SRGB, gpu.regs.framebuffer_srgb);
|
||||
oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d.regs.framebuffer_srgb);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncTransformFeedback() {
|
||||
// TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal
|
||||
// when this is required.
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
|
||||
static constexpr std::size_t STRIDE = 3;
|
||||
std::array<GLint, 128 * STRIDE * Maxwell::NumTransformFeedbackBuffers> attribs;
|
||||
|
@ -1698,7 +1657,7 @@ void RasterizerOpenGL::SyncTransformFeedback() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.tfb_enabled == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -1741,7 +1700,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::EndTransformFeedback() {
|
||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||
const auto& regs = maxwell3d.regs;
|
||||
if (regs.tfb_enabled == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#include "video_core/shader/async_shaders.h"
|
||||
#include "video_core/textures/texture.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
@ -55,9 +55,10 @@ struct DrawParameters;
|
|||
|
||||
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
||||
public:
|
||||
explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||
const Device& device, ScreenInfo& info,
|
||||
ProgramManager& program_manager, StateTracker& state_tracker);
|
||||
explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
|
||||
Core::Memory::Memory& cpu_memory, const Device& device,
|
||||
ScreenInfo& screen_info, ProgramManager& program_manager,
|
||||
StateTracker& state_tracker);
|
||||
~RasterizerOpenGL() override;
|
||||
|
||||
void Draw(bool is_indexed, bool is_instanced) override;
|
||||
|
@ -83,9 +84,8 @@ public:
|
|||
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
||||
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
||||
u32 pixel_stride) override;
|
||||
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||
void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
|
||||
const VideoCore::DiskResourceLoadCallback& callback) override;
|
||||
void SetupDirtyFlags() override;
|
||||
|
||||
/// Returns true when there are commands queued to the OpenGL server.
|
||||
bool AnyCommandQueued() const {
|
||||
|
@ -237,7 +237,15 @@ private:
|
|||
|
||||
void SetupShaders(GLenum primitive_mode);
|
||||
|
||||
Tegra::GPU& gpu;
|
||||
Tegra::Engines::Maxwell3D& maxwell3d;
|
||||
Tegra::Engines::KeplerCompute& kepler_compute;
|
||||
Tegra::MemoryManager& gpu_memory;
|
||||
|
||||
const Device& device;
|
||||
ScreenInfo& screen_info;
|
||||
ProgramManager& program_manager;
|
||||
StateTracker& state_tracker;
|
||||
|
||||
TextureCacheOpenGL texture_cache;
|
||||
ShaderCacheOpenGL shader_cache;
|
||||
|
@ -247,10 +255,6 @@ private:
|
|||
OGLBufferCache buffer_cache;
|
||||
FenceManagerOpenGL fence_manager;
|
||||
|
||||
Core::System& system;
|
||||
ScreenInfo& screen_info;
|
||||
ProgramManager& program_manager;
|
||||
StateTracker& state_tracker;
|
||||
VideoCommon::Shader::AsyncShaders async_shaders;
|
||||
|
||||
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
||||
|
|
|
@ -239,12 +239,11 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory(
|
|||
ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) {
|
||||
const auto shader_type = GetShaderType(program_type);
|
||||
|
||||
auto& gpu = params.system.GPU();
|
||||
auto& gpu = params.gpu;
|
||||
gpu.ShaderNotify().MarkSharderBuilding();
|
||||
|
||||
auto registry = std::make_shared<Registry>(shader_type, gpu.Maxwell3D());
|
||||
if (!async_shaders.IsShaderAsync(params.system.GPU()) ||
|
||||
!params.device.UseAsynchronousShaders()) {
|
||||
if (!async_shaders.IsShaderAsync(gpu) || !params.device.UseAsynchronousShaders()) {
|
||||
const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry);
|
||||
// TODO(Rodrigo): Handle VertexA shaders
|
||||
// std::optional<ShaderIR> ir_b;
|
||||
|
@ -287,11 +286,10 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory(
|
|||
|
||||
std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params,
|
||||
ProgramCode code) {
|
||||
auto& gpu = params.system.GPU();
|
||||
auto& gpu = params.gpu;
|
||||
gpu.ShaderNotify().MarkSharderBuilding();
|
||||
|
||||
auto& engine = gpu.KeplerCompute();
|
||||
auto registry = std::make_shared<Registry>(ShaderType::Compute, engine);
|
||||
auto registry = std::make_shared<Registry>(ShaderType::Compute, params.engine);
|
||||
const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry);
|
||||
const u64 uid = params.unique_identifier;
|
||||
auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry);
|
||||
|
@ -320,15 +318,20 @@ std::unique_ptr<Shader> Shader::CreateFromCache(const ShaderParameters& params,
|
|||
precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program));
|
||||
}
|
||||
|
||||
ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
|
||||
Core::Frontend::EmuWindow& emu_window, const Device& device)
|
||||
: VideoCommon::ShaderCache<Shader>{rasterizer}, system{system},
|
||||
emu_window{emu_window}, device{device}, disk_cache{system} {}
|
||||
ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer,
|
||||
Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d_,
|
||||
Tegra::Engines::KeplerCompute& kepler_compute_,
|
||||
Tegra::MemoryManager& gpu_memory_, const Device& device_)
|
||||
: VideoCommon::ShaderCache<Shader>{rasterizer}, emu_window{emu_window_}, gpu{gpu_},
|
||||
gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_},
|
||||
kepler_compute{kepler_compute_}, device{device_} {}
|
||||
|
||||
ShaderCacheOpenGL::~ShaderCacheOpenGL() = default;
|
||||
|
||||
void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
|
||||
void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
|
||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||
disk_cache.BindTitleID(title_id);
|
||||
const std::optional transferable = disk_cache.LoadTransferable();
|
||||
if (!transferable) {
|
||||
return;
|
||||
|
@ -481,21 +484,19 @@ ProgramSharedPtr ShaderCacheOpenGL::GeneratePrecompiledProgram(
|
|||
|
||||
Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
|
||||
VideoCommon::Shader::AsyncShaders& async_shaders) {
|
||||
if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) {
|
||||
if (!maxwell3d.dirty.flags[Dirty::Shaders]) {
|
||||
auto* last_shader = last_shaders[static_cast<std::size_t>(program)];
|
||||
if (last_shader->IsBuilt()) {
|
||||
return last_shader;
|
||||
}
|
||||
}
|
||||
|
||||
auto& memory_manager{system.GPU().MemoryManager()};
|
||||
const GPUVAddr address{GetShaderAddress(system, program)};
|
||||
const GPUVAddr address{GetShaderAddress(maxwell3d, program)};
|
||||
|
||||
if (device.UseAsynchronousShaders() && async_shaders.HasCompletedWork()) {
|
||||
auto completed_work = async_shaders.GetCompletedWork();
|
||||
for (auto& work : completed_work) {
|
||||
Shader* shader = TryGet(work.cpu_address);
|
||||
auto& gpu = system.GPU();
|
||||
gpu.ShaderNotify().MarkShaderComplete();
|
||||
if (shader == nullptr) {
|
||||
continue;
|
||||
|
@ -507,14 +508,13 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
|
|||
shader->AsyncGLASMBuilt(std::move(work.program.glasm));
|
||||
}
|
||||
|
||||
auto& registry = shader->GetRegistry();
|
||||
|
||||
ShaderDiskCacheEntry entry;
|
||||
entry.type = work.shader_type;
|
||||
entry.code = std::move(work.code);
|
||||
entry.code_b = std::move(work.code_b);
|
||||
entry.unique_identifier = work.uid;
|
||||
|
||||
auto& registry = shader->GetRegistry();
|
||||
|
||||
entry.bound_buffer = registry.GetBoundBuffer();
|
||||
entry.graphics_info = registry.GetGraphicsInfo();
|
||||
entry.keys = registry.GetKeys();
|
||||
|
@ -525,28 +525,28 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
|
|||
}
|
||||
|
||||
// Look up shader in the cache based on address
|
||||
const auto cpu_addr{memory_manager.GpuToCpuAddress(address)};
|
||||
const std::optional<VAddr> cpu_addr{gpu_memory.GpuToCpuAddress(address)};
|
||||
if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) {
|
||||
return last_shaders[static_cast<std::size_t>(program)] = shader;
|
||||
}
|
||||
|
||||
const auto host_ptr{memory_manager.GetPointer(address)};
|
||||
const u8* const host_ptr{gpu_memory.GetPointer(address)};
|
||||
|
||||
// No shader found - create a new one
|
||||
ProgramCode code{GetShaderCode(memory_manager, address, host_ptr, false)};
|
||||
ProgramCode code{GetShaderCode(gpu_memory, address, host_ptr, false)};
|
||||
ProgramCode code_b;
|
||||
if (program == Maxwell::ShaderProgram::VertexA) {
|
||||
const GPUVAddr address_b{GetShaderAddress(system, Maxwell::ShaderProgram::VertexB)};
|
||||
const u8* host_ptr_b = memory_manager.GetPointer(address_b);
|
||||
code_b = GetShaderCode(memory_manager, address_b, host_ptr_b, false);
|
||||
const GPUVAddr address_b{GetShaderAddress(maxwell3d, Maxwell::ShaderProgram::VertexB)};
|
||||
const u8* host_ptr_b = gpu_memory.GetPointer(address_b);
|
||||
code_b = GetShaderCode(gpu_memory, address_b, host_ptr_b, false);
|
||||
}
|
||||
const std::size_t code_size = code.size() * sizeof(u64);
|
||||
|
||||
const u64 unique_identifier = GetUniqueIdentifier(
|
||||
GetShaderType(program), program == Maxwell::ShaderProgram::VertexA, code, code_b);
|
||||
|
||||
const ShaderParameters params{system, disk_cache, device,
|
||||
*cpu_addr, host_ptr, unique_identifier};
|
||||
const ShaderParameters params{gpu, maxwell3d, disk_cache, device,
|
||||
*cpu_addr, host_ptr, unique_identifier};
|
||||
|
||||
std::unique_ptr<Shader> shader;
|
||||
const auto found = runtime_cache.find(unique_identifier);
|
||||
|
@ -568,21 +568,20 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
|
|||
}
|
||||
|
||||
Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) {
|
||||
auto& memory_manager{system.GPU().MemoryManager()};
|
||||
const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)};
|
||||
const std::optional<VAddr> cpu_addr{gpu_memory.GpuToCpuAddress(code_addr)};
|
||||
|
||||
if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) {
|
||||
return kernel;
|
||||
}
|
||||
|
||||
const auto host_ptr{memory_manager.GetPointer(code_addr)};
|
||||
// No kernel found, create a new one
|
||||
ProgramCode code{GetShaderCode(memory_manager, code_addr, host_ptr, true)};
|
||||
const u8* host_ptr{gpu_memory.GetPointer(code_addr)};
|
||||
ProgramCode code{GetShaderCode(gpu_memory, code_addr, host_ptr, true)};
|
||||
const std::size_t code_size{code.size() * sizeof(u64)};
|
||||
const u64 unique_identifier{GetUniqueIdentifier(ShaderType::Compute, false, code)};
|
||||
|
||||
const ShaderParameters params{system, disk_cache, device,
|
||||
*cpu_addr, host_ptr, unique_identifier};
|
||||
const ShaderParameters params{gpu, kepler_compute, disk_cache, device,
|
||||
*cpu_addr, host_ptr, unique_identifier};
|
||||
|
||||
std::unique_ptr<Shader> kernel;
|
||||
const auto found = runtime_cache.find(unique_identifier);
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "video_core/shader/shader_ir.h"
|
||||
#include "video_core/shader_cache.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
namespace Tegra {
|
||||
class MemoryManager;
|
||||
}
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
@ -57,11 +57,12 @@ struct PrecompiledShader {
|
|||
};
|
||||
|
||||
struct ShaderParameters {
|
||||
Core::System& system;
|
||||
Tegra::GPU& gpu;
|
||||
Tegra::Engines::ConstBufferEngineInterface& engine;
|
||||
ShaderDiskCacheOpenGL& disk_cache;
|
||||
const Device& device;
|
||||
VAddr cpu_addr;
|
||||
u8* host_ptr;
|
||||
const u8* host_ptr;
|
||||
u64 unique_identifier;
|
||||
};
|
||||
|
||||
|
@ -118,12 +119,14 @@ private:
|
|||
|
||||
class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> {
|
||||
public:
|
||||
explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
|
||||
Core::Frontend::EmuWindow& emu_window, const Device& device);
|
||||
explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::Frontend::EmuWindow& emu_window,
|
||||
Tegra::GPU& gpu, Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::Engines::KeplerCompute& kepler_compute,
|
||||
Tegra::MemoryManager& gpu_memory, const Device& device);
|
||||
~ShaderCacheOpenGL() override;
|
||||
|
||||
/// Loads disk cache for the current game
|
||||
void LoadDiskCache(const std::atomic_bool& stop_loading,
|
||||
void LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
|
||||
const VideoCore::DiskResourceLoadCallback& callback);
|
||||
|
||||
/// Gets the current specified shader stage program
|
||||
|
@ -138,9 +141,13 @@ private:
|
|||
const ShaderDiskCacheEntry& entry, const ShaderDiskCachePrecompiled& precompiled_entry,
|
||||
const std::unordered_set<GLenum>& supported_formats);
|
||||
|
||||
Core::System& system;
|
||||
Core::Frontend::EmuWindow& emu_window;
|
||||
Tegra::GPU& gpu;
|
||||
Tegra::MemoryManager& gpu_memory;
|
||||
Tegra::Engines::Maxwell3D& maxwell3d;
|
||||
Tegra::Engines::KeplerCompute& kepler_compute;
|
||||
const Device& device;
|
||||
|
||||
ShaderDiskCacheOpenGL disk_cache;
|
||||
std::unordered_map<u64, PrecompiledShader> runtime_cache;
|
||||
|
||||
|
|
|
@ -206,13 +206,17 @@ bool ShaderDiskCacheEntry::Save(Common::FS::IOFile& file) const {
|
|||
flat_bindless_samplers.size();
|
||||
}
|
||||
|
||||
ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL(Core::System& system) : system{system} {}
|
||||
ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL() = default;
|
||||
|
||||
ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default;
|
||||
|
||||
void ShaderDiskCacheOpenGL::BindTitleID(u64 title_id_) {
|
||||
title_id = title_id_;
|
||||
}
|
||||
|
||||
std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() {
|
||||
// Skip games without title id
|
||||
const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0;
|
||||
const bool has_title_id = title_id != 0;
|
||||
if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -474,7 +478,7 @@ std::string ShaderDiskCacheOpenGL::GetBaseDir() const {
|
|||
}
|
||||
|
||||
std::string ShaderDiskCacheOpenGL::GetTitleID() const {
|
||||
return fmt::format("{:016X}", system.CurrentProcess()->GetTitleID());
|
||||
return fmt::format("{:016X}", title_id);
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
#include "video_core/engines/shader_type.h"
|
||||
#include "video_core/shader/registry.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Common::FS {
|
||||
class IOFile;
|
||||
}
|
||||
|
@ -70,9 +66,12 @@ struct ShaderDiskCachePrecompiled {
|
|||
|
||||
class ShaderDiskCacheOpenGL {
|
||||
public:
|
||||
explicit ShaderDiskCacheOpenGL(Core::System& system);
|
||||
explicit ShaderDiskCacheOpenGL();
|
||||
~ShaderDiskCacheOpenGL();
|
||||
|
||||
/// Binds a title ID for all future operations.
|
||||
void BindTitleID(u64 title_id);
|
||||
|
||||
/// Loads transferable cache. If file has a old version or on failure, it deletes the file.
|
||||
std::optional<std::vector<ShaderDiskCacheEntry>> LoadTransferable();
|
||||
|
||||
|
@ -157,8 +156,6 @@ private:
|
|||
return LoadArrayFromPrecompiled(&object, 1);
|
||||
}
|
||||
|
||||
Core::System& system;
|
||||
|
||||
// Stores whole precompiled cache which will be read from or saved to the precompiled chache
|
||||
// file
|
||||
FileSys::VectorVfsFile precompiled_cache_virtual_file;
|
||||
|
@ -168,8 +165,11 @@ private:
|
|||
// Stored transferable shaders
|
||||
std::unordered_set<u64> stored_transferable;
|
||||
|
||||
/// Title ID to operate on
|
||||
u64 title_id = 0;
|
||||
|
||||
// The cache has been loaded at boot
|
||||
bool is_usable{};
|
||||
bool is_usable = false;
|
||||
};
|
||||
|
||||
} // namespace OpenGL
|
||||
|
|
|
@ -214,10 +214,8 @@ void SetupDirtyMisc(Tables& tables) {
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
StateTracker::StateTracker(Core::System& system) : system{system} {}
|
||||
|
||||
void StateTracker::Initialize() {
|
||||
auto& dirty = system.GPU().Maxwell3D().dirty;
|
||||
StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} {
|
||||
auto& dirty = gpu.Maxwell3D().dirty;
|
||||
auto& tables = dirty.tables;
|
||||
SetupDirtyRenderTargets(tables);
|
||||
SetupDirtyColorMasks(tables);
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include "video_core/dirty_flags.h"
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
namespace Tegra {
|
||||
class GPU;
|
||||
}
|
||||
|
||||
namespace OpenGL {
|
||||
|
@ -90,9 +90,7 @@ static_assert(Last <= std::numeric_limits<u8>::max());
|
|||
|
||||
class StateTracker {
|
||||
public:
|
||||
explicit StateTracker(Core::System& system);
|
||||
|
||||
void Initialize();
|
||||
explicit StateTracker(Tegra::GPU& gpu);
|
||||
|
||||
void BindIndexBuffer(GLuint new_index_buffer) {
|
||||
if (index_buffer == new_index_buffer) {
|
||||
|
@ -103,7 +101,6 @@ public:
|
|||
}
|
||||
|
||||
void NotifyScreenDrawVertexArray() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::VertexFormats] = true;
|
||||
flags[OpenGL::Dirty::VertexFormat0 + 0] = true;
|
||||
flags[OpenGL::Dirty::VertexFormat0 + 1] = true;
|
||||
|
@ -117,98 +114,81 @@ public:
|
|||
}
|
||||
|
||||
void NotifyPolygonModes() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::PolygonModes] = true;
|
||||
flags[OpenGL::Dirty::PolygonModeFront] = true;
|
||||
flags[OpenGL::Dirty::PolygonModeBack] = true;
|
||||
}
|
||||
|
||||
void NotifyViewport0() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::Viewports] = true;
|
||||
flags[OpenGL::Dirty::Viewport0] = true;
|
||||
}
|
||||
|
||||
void NotifyScissor0() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::Scissors] = true;
|
||||
flags[OpenGL::Dirty::Scissor0] = true;
|
||||
}
|
||||
|
||||
void NotifyColorMask0() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::ColorMasks] = true;
|
||||
flags[OpenGL::Dirty::ColorMask0] = true;
|
||||
}
|
||||
|
||||
void NotifyBlend0() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::BlendStates] = true;
|
||||
flags[OpenGL::Dirty::BlendState0] = true;
|
||||
}
|
||||
|
||||
void NotifyFramebuffer() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[VideoCommon::Dirty::RenderTargets] = true;
|
||||
}
|
||||
|
||||
void NotifyFrontFace() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::FrontFace] = true;
|
||||
}
|
||||
|
||||
void NotifyCullTest() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::CullTest] = true;
|
||||
}
|
||||
|
||||
void NotifyDepthMask() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::DepthMask] = true;
|
||||
}
|
||||
|
||||
void NotifyDepthTest() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::DepthTest] = true;
|
||||
}
|
||||
|
||||
void NotifyStencilTest() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::StencilTest] = true;
|
||||
}
|
||||
|
||||
void NotifyPolygonOffset() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::PolygonOffset] = true;
|
||||
}
|
||||
|
||||
void NotifyRasterizeEnable() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::RasterizeEnable] = true;
|
||||
}
|
||||
|
||||
void NotifyFramebufferSRGB() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::FramebufferSRGB] = true;
|
||||
}
|
||||
|
||||
void NotifyLogicOp() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::LogicOp] = true;
|
||||
}
|
||||
|
||||
void NotifyClipControl() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::ClipControl] = true;
|
||||
}
|
||||
|
||||
void NotifyAlphaTest() {
|
||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||
flags[OpenGL::Dirty::AlphaTest] = true;
|
||||
}
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
Tegra::Engines::Maxwell3D::DirtyState::Flags& flags;
|
||||
|
||||
GLuint index_buffer = 0;
|
||||
};
|
||||
|
|
|
@ -532,10 +532,12 @@ OGLTextureView CachedSurfaceView::CreateTextureView() const {
|
|||
return texture_view;
|
||||
}
|
||||
|
||||
TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
|
||||
VideoCore::RasterizerInterface& rasterizer,
|
||||
const Device& device, StateTracker& state_tracker)
|
||||
: TextureCacheBase{system, rasterizer, device.HasASTC()}, state_tracker{state_tracker} {
|
||||
TextureCacheOpenGL::TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::MemoryManager& gpu_memory, const Device& device,
|
||||
StateTracker& state_tracker_)
|
||||
: TextureCacheBase{rasterizer, maxwell3d, gpu_memory, device.HasASTC()}, state_tracker{
|
||||
state_tracker_} {
|
||||
src_framebuffer.Create();
|
||||
dst_framebuffer.Create();
|
||||
}
|
||||
|
|
|
@ -129,8 +129,10 @@ private:
|
|||
|
||||
class TextureCacheOpenGL final : public TextureCacheBase {
|
||||
public:
|
||||
explicit TextureCacheOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||
const Device& device, StateTracker& state_tracker);
|
||||
explicit TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer,
|
||||
Tegra::Engines::Maxwell3D& maxwell3d,
|
||||
Tegra::MemoryManager& gpu_memory, const Device& device,
|
||||
StateTracker& state_tracker);
|
||||
~TextureCacheOpenGL();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -275,11 +275,13 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
RendererOpenGL::RendererOpenGL(Core::System& system_, Core::Frontend::EmuWindow& emu_window_,
|
||||
Tegra::GPU& gpu_,
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
|
||||
: RendererBase{emu_window_, std::move(context_)}, system{system_},
|
||||
emu_window{emu_window_}, gpu{gpu_}, program_manager{device}, has_debug_tool{HasDebugTool()} {}
|
||||
RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
|
||||
Core::Frontend::EmuWindow& emu_window_,
|
||||
Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> context)
|
||||
: RendererBase{emu_window_, std::move(context)}, telemetry_session{telemetry_session_},
|
||||
emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, program_manager{device},
|
||||
has_debug_tool{HasDebugTool()} {}
|
||||
|
||||
RendererOpenGL::~RendererOpenGL() = default;
|
||||
|
||||
|
@ -386,7 +388,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
|
|||
VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)};
|
||||
const u32 bytes_per_pixel{VideoCore::Surface::GetBytesPerPixel(pixel_format)};
|
||||
const u64 size_in_bytes{framebuffer.stride * framebuffer.height * bytes_per_pixel};
|
||||
u8* const host_ptr{system.Memory().GetPointer(framebuffer_addr)};
|
||||
u8* const host_ptr{cpu_memory.GetPointer(framebuffer_addr)};
|
||||
rasterizer->FlushRegion(ToCacheAddr(host_ptr), size_in_bytes);
|
||||
|
||||
// TODO(Rodrigo): Read this from HLE
|
||||
|
@ -471,7 +473,6 @@ void RendererOpenGL::AddTelemetryFields() {
|
|||
LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
|
||||
LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
|
||||
|
||||
auto& telemetry_session = system.TelemetrySession();
|
||||
constexpr auto user_system = Common::Telemetry::FieldType::UserSystem;
|
||||
telemetry_session.AddField(user_system, "GPU_Vendor", gpu_vendor);
|
||||
telemetry_session.AddField(user_system, "GPU_Model", gpu_model);
|
||||
|
@ -482,8 +483,8 @@ void RendererOpenGL::CreateRasterizer() {
|
|||
if (rasterizer) {
|
||||
return;
|
||||
}
|
||||
rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, device, screen_info,
|
||||
program_manager, state_tracker);
|
||||
rasterizer = std::make_unique<RasterizerOpenGL>(emu_window, gpu, cpu_memory, device,
|
||||
screen_info, program_manager, state_tracker);
|
||||
}
|
||||
|
||||
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
|
|
|
@ -16,16 +16,25 @@
|
|||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
class TelemetrySession;
|
||||
} // namespace Core
|
||||
|
||||
namespace Core::Frontend {
|
||||
class EmuWindow;
|
||||
}
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
namespace Layout {
|
||||
struct FramebufferLayout;
|
||||
}
|
||||
|
||||
namespace Tegra {
|
||||
class GPU;
|
||||
}
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
/// Structure used for storing information about the textures for the Switch screen
|
||||
|
@ -56,7 +65,8 @@ class FrameMailbox;
|
|||
|
||||
class RendererOpenGL final : public VideoCore::RendererBase {
|
||||
public:
|
||||
explicit RendererOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||
explicit RendererOpenGL(Core::TelemetrySession& telemetry_session,
|
||||
Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory,
|
||||
Tegra::GPU& gpu,
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> context);
|
||||
~RendererOpenGL() override;
|
||||
|
@ -94,12 +104,13 @@ private:
|
|||
|
||||
bool Present(int timeout_ms);
|
||||
|
||||
Core::System& system;
|
||||
Core::TelemetrySession& telemetry_session;
|
||||
Core::Frontend::EmuWindow& emu_window;
|
||||
Core::Memory::Memory& cpu_memory;
|
||||
Tegra::GPU& gpu;
|
||||
const Device device;
|
||||
|
||||
StateTracker state_tracker{system};
|
||||
const Device device;
|
||||
StateTracker state_tracker{gpu};
|
||||
|
||||
// OpenGL object IDs
|
||||
OGLBuffer vertex_buffer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue