aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp15
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp4
6 files changed, 50 insertions, 17 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 08f4d69ab..6af4ae793 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -29,17 +29,17 @@ constexpr std::array PROGRAM_LUT{
[[nodiscard]] GLenum GetTextureBufferFormat(GLenum gl_format) {
switch (gl_format) {
case GL_RGBA8_SNORM:
- return GL_RGBA8;
+ return GL_RGBA8I;
case GL_R8_SNORM:
- return GL_R8;
+ return GL_R8I;
case GL_RGBA16_SNORM:
- return GL_RGBA16;
+ return GL_RGBA16I;
case GL_R16_SNORM:
- return GL_R16;
+ return GL_R16I;
case GL_RG16_SNORM:
- return GL_RG16;
+ return GL_RG16I;
case GL_RG8_SNORM:
- return GL_RG8;
+ return GL_RG8I;
default:
return gl_format;
}
@@ -96,9 +96,6 @@ GLuint Buffer::View(u32 offset, u32 size, PixelFormat format) {
texture.Create(GL_TEXTURE_BUFFER);
const GLenum gl_format{MaxwellToGL::GetFormatTuple(format).internal_format};
const GLenum texture_format{GetTextureBufferFormat(gl_format)};
- if (texture_format != gl_format) {
- LOG_WARNING(Render_OpenGL, "Emulating SNORM texture buffer with UNORM.");
- }
glTextureBufferRange(texture.handle, texture_format, buffer.handle, offset, size);
views.push_back({
.offset = offset,
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 1d20a79ec..c115dabe1 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -503,6 +503,17 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
float_image_scaling_mask, down_factor, 0.0f);
}
}
+ if (info.uses_render_area) {
+ const auto render_area_width(static_cast<GLfloat>(regs.surface_clip.width));
+ const auto render_area_height(static_cast<GLfloat>(regs.surface_clip.height));
+ if (use_assembly) {
+ glProgramLocalParameter4fARB(AssemblyStage(stage), 1, render_area_width,
+ render_area_height, 0.0f, 0.0f);
+ } else {
+ glProgramUniform4f(source_programs[stage].handle, 1, render_area_width,
+ render_area_height, 0.0f, 0.0f);
+ }
+ }
}};
if constexpr (Spec::enabled_stages[0]) {
prepare_stage(0);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e5c09a969..8a8b5ce54 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -205,7 +205,7 @@ void RasterizerOpenGL::Clear() {
++num_queued_commands;
}
-void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
+void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) {
MICROPROFILE_SCOPE(OpenGL_Drawing);
SCOPE_EXIT({ gpu.TickWork(); });
@@ -222,14 +222,15 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed);
+ BindInlineIndexBuffer();
+
SyncState();
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);
BeginTransformFeedback(pipeline, primitive_mode);
const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.global_base_instance_index);
- const GLsizei num_instances =
- static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1);
+ const GLsizei num_instances = static_cast<GLsizei>(instance_count);
if (is_indexed) {
const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.global_base_vertex_index);
const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_buffer.count);
@@ -617,6 +618,16 @@ void RasterizerOpenGL::SyncViewport() {
}
flags[Dirty::Viewport0 + index] = false;
+ if (!regs.viewport_scale_offset_enabled) {
+ const auto x = static_cast<GLfloat>(regs.surface_clip.x);
+ const auto y = static_cast<GLfloat>(regs.surface_clip.y);
+ const auto width = static_cast<GLfloat>(regs.surface_clip.width);
+ const auto height = static_cast<GLfloat>(regs.surface_clip.height);
+ glViewportIndexedf(static_cast<GLuint>(index), x, y, width != 0.0f ? width : 1.0f,
+ height != 0.0f ? height : 1.0f);
+ continue;
+ }
+
const auto& src = regs.viewport_transform[index];
GLfloat x = conv(src.translate_x - src.scale_x);
GLfloat y = conv(src.translate_y - src.scale_y);
@@ -1129,6 +1140,16 @@ void RasterizerOpenGL::ReleaseChannel(s32 channel_id) {
query_cache.EraseChannel(channel_id);
}
+void RasterizerOpenGL::BindInlineIndexBuffer() {
+ if (maxwell3d->inline_index_draw_indexes.empty()) {
+ return;
+ }
+ const auto data_count = static_cast<u32>(maxwell3d->inline_index_draw_indexes.size());
+ auto buffer = Buffer(buffer_cache_runtime, *this, 0, data_count);
+ buffer.ImmediateUpload(0, maxwell3d->inline_index_draw_indexes);
+ buffer_cache_runtime.BindIndexBuffer(buffer, 0, data_count);
+}
+
AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}
bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 45131b785..793e0d608 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -68,7 +68,7 @@ public:
StateTracker& state_tracker_);
~RasterizerOpenGL() override;
- void Draw(bool is_indexed, bool is_instanced) override;
+ void Draw(bool is_indexed, u32 instance_count) override;
void Clear() override;
void DispatchCompute() override;
void ResetCounter(VideoCore::QueryType type) override;
@@ -199,6 +199,8 @@ private:
/// End a transform feedback
void EndTransformFeedback();
+ void BindInlineIndexBuffer();
+
Tegra::GPU& gpu;
const Device& device;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index e94cfdb1a..3fe04a115 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -49,7 +49,7 @@ using VideoCommon::LoadPipelines;
using VideoCommon::SerializePipeline;
using Context = ShaderContext::Context;
-constexpr u32 CACHE_VERSION = 6;
+constexpr u32 CACHE_VERSION = 7;
template <typename Container>
auto MakeSpan(Container& container) {
@@ -76,7 +76,8 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
}
break;
case Shader::Stage::TessellationEval:
- info.tess_clockwise = key.tessellation_clockwise != 0;
+ // Flip the face, as OpenGL's drawing is flipped.
+ info.tess_clockwise = key.tessellation_clockwise == 0;
info.tess_primitive = [&key] {
switch (key.tessellation_primitive) {
case Maxwell::Tessellation::DomainType::Isolines:
@@ -218,6 +219,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
.support_float16 = false,
.support_int64 = device.HasShaderInt64(),
.needs_demote_reorder = device.IsAmd(),
+ .support_snorm_render_buffer = false,
} {
if (use_asynchronous_shaders) {
workers = CreateWorkers();
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index a359f96f1..d53b422ca 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -70,8 +70,8 @@ void SetupDirtyViewports(Tables& tables) {
FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports);
FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports);
- tables[0][OFF(viewport_scale_offset_enbled)] = ViewportTransform;
- tables[1][OFF(viewport_scale_offset_enbled)] = Viewports;
+ tables[0][OFF(viewport_scale_offset_enabled)] = ViewportTransform;
+ tables[1][OFF(viewport_scale_offset_enabled)] = Viewports;
}
void SetupDirtyScissors(Tables& tables) {