Merge branch 'master' into shader-purge
This commit is contained in:
commit
244fe13219
|
@ -243,6 +243,7 @@ typedef uint32_t ThreadIdType;
|
||||||
#define MICROPROFILE_DEFINE_GPU(var, name, color) MicroProfileToken g_mp_##var = MicroProfileGetToken("GPU", name, color, MicroProfileTokenTypeGpu)
|
#define MICROPROFILE_DEFINE_GPU(var, name, color) MicroProfileToken g_mp_##var = MicroProfileGetToken("GPU", name, color, MicroProfileTokenTypeGpu)
|
||||||
#define MICROPROFILE_TOKEN_PASTE0(a, b) a ## b
|
#define MICROPROFILE_TOKEN_PASTE0(a, b) a ## b
|
||||||
#define MICROPROFILE_TOKEN_PASTE(a, b) MICROPROFILE_TOKEN_PASTE0(a,b)
|
#define MICROPROFILE_TOKEN_PASTE(a, b) MICROPROFILE_TOKEN_PASTE0(a,b)
|
||||||
|
#define MICROPROFILE_TOKEN(var) g_mp_##var
|
||||||
#define MICROPROFILE_SCOPE(var) MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo, __LINE__)(g_mp_##var)
|
#define MICROPROFILE_SCOPE(var) MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo, __LINE__)(g_mp_##var)
|
||||||
#define MICROPROFILE_SCOPE_TOKEN(token) MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo, __LINE__)(token)
|
#define MICROPROFILE_SCOPE_TOKEN(token) MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo, __LINE__)(token)
|
||||||
#define MICROPROFILE_SCOPEI(group, name, color) static MicroProfileToken MICROPROFILE_TOKEN_PASTE(g_mp,__LINE__) = MicroProfileGetToken(group, name, color, MicroProfileTokenTypeCpu); MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo,__LINE__)( MICROPROFILE_TOKEN_PASTE(g_mp,__LINE__))
|
#define MICROPROFILE_SCOPEI(group, name, color) static MicroProfileToken MICROPROFILE_TOKEN_PASTE(g_mp,__LINE__) = MicroProfileGetToken(group, name, color, MicroProfileTokenTypeCpu); MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo,__LINE__)( MICROPROFILE_TOKEN_PASTE(g_mp,__LINE__))
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "audio_core/cubeb_sink.h"
|
#include "audio_core/cubeb_sink.h"
|
||||||
#include "audio_core/stream.h"
|
#include "audio_core/stream.h"
|
||||||
#include "audio_core/time_stretch.h"
|
#include "audio_core/time_stretch.h"
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/ring_buffer.h"
|
#include "common/ring_buffer.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
@ -65,12 +66,25 @@ public:
|
||||||
void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override {
|
void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override {
|
||||||
if (source_num_channels > num_channels) {
|
if (source_num_channels > num_channels) {
|
||||||
// Downsample 6 channels to 2
|
// Downsample 6 channels to 2
|
||||||
|
ASSERT_MSG(source_num_channels == 6, "Channel count must be 6");
|
||||||
|
|
||||||
std::vector<s16> buf;
|
std::vector<s16> buf;
|
||||||
buf.reserve(samples.size() * num_channels / source_num_channels);
|
buf.reserve(samples.size() * num_channels / source_num_channels);
|
||||||
for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
|
for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
|
||||||
for (std::size_t ch = 0; ch < num_channels; ch++) {
|
// Downmixing implementation taken from the ATSC standard
|
||||||
buf.push_back(samples[i + ch]);
|
const s16 left{samples[i + 0]};
|
||||||
}
|
const s16 right{samples[i + 1]};
|
||||||
|
const s16 center{samples[i + 2]};
|
||||||
|
const s16 surround_left{samples[i + 4]};
|
||||||
|
const s16 surround_right{samples[i + 5]};
|
||||||
|
// Not used in the ATSC reference implementation
|
||||||
|
[[maybe_unused]] const s16 low_frequency_effects { samples[i + 3] };
|
||||||
|
|
||||||
|
constexpr s32 clev{707}; // center mixing level coefficient
|
||||||
|
constexpr s32 slev{707}; // surround mixing level coefficient
|
||||||
|
|
||||||
|
buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000));
|
||||||
|
buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000));
|
||||||
}
|
}
|
||||||
queue.Push(buf);
|
queue.Push(buf);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -48,8 +48,8 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) {
|
||||||
u32 width, height;
|
u32 width, height;
|
||||||
|
|
||||||
if (Settings::values.use_docked_mode) {
|
if (Settings::values.use_docked_mode) {
|
||||||
width = ScreenDocked::WidthDocked * res_scale;
|
width = ScreenDocked::Width * res_scale;
|
||||||
height = ScreenDocked::HeightDocked * res_scale;
|
height = ScreenDocked::Height * res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = ScreenUndocked::Width * res_scale;
|
width = ScreenUndocked::Width * res_scale;
|
||||||
height = ScreenUndocked::Height * res_scale;
|
height = ScreenUndocked::Height * res_scale;
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
|
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
|
|
||||||
enum ScreenUndocked : u32 {
|
namespace ScreenUndocked {
|
||||||
Width = 1280,
|
constexpr u32 Width = 1280;
|
||||||
Height = 720,
|
constexpr u32 Height = 720;
|
||||||
};
|
} // namespace ScreenUndocked
|
||||||
|
|
||||||
enum ScreenDocked : u32 {
|
namespace ScreenDocked {
|
||||||
WidthDocked = 1920,
|
constexpr u32 Width = 1920;
|
||||||
HeightDocked = 1080,
|
constexpr u32 Height = 1080;
|
||||||
};
|
} // namespace ScreenDocked
|
||||||
|
|
||||||
enum class AspectRatio {
|
enum class AspectRatio {
|
||||||
Default,
|
Default,
|
||||||
|
|
|
@ -191,8 +191,6 @@ void NVFlinger::Compose() {
|
||||||
// Search for a queued buffer and acquire it
|
// Search for a queued buffer and acquire it
|
||||||
auto buffer = buffer_queue.AcquireBuffer();
|
auto buffer = buffer_queue.AcquireBuffer();
|
||||||
|
|
||||||
MicroProfileFlip();
|
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -206,6 +204,8 @@ void NVFlinger::Compose() {
|
||||||
gpu.WaitFence(fence.id, fence.value);
|
gpu.WaitFence(fence.id, fence.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MicroProfileFlip();
|
||||||
|
|
||||||
// Now send the buffer to the GPU for drawing.
|
// Now send the buffer to the GPU for drawing.
|
||||||
// TODO(Subv): Support more than just disp0. The display device selection is probably based
|
// TODO(Subv): Support more than just disp0. The display device selection is probably based
|
||||||
// on which display we're drawing (Default, Internal, External, etc)
|
// on which display we're drawing (Default, Internal, External, etc)
|
||||||
|
|
|
@ -525,6 +525,12 @@ public:
|
||||||
FractionalEven = 2,
|
FractionalEven = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PolygonMode : u32 {
|
||||||
|
Point = 0x1b00,
|
||||||
|
Line = 0x1b01,
|
||||||
|
Fill = 0x1b02,
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderTargetConfig {
|
struct RenderTargetConfig {
|
||||||
u32 address_high;
|
u32 address_high;
|
||||||
u32 address_low;
|
u32 address_low;
|
||||||
|
@ -728,7 +734,12 @@ public:
|
||||||
|
|
||||||
s32 clear_stencil;
|
s32 clear_stencil;
|
||||||
|
|
||||||
INSERT_UNION_PADDING_WORDS(0x7);
|
INSERT_UNION_PADDING_WORDS(0x2);
|
||||||
|
|
||||||
|
PolygonMode polygon_mode_front;
|
||||||
|
PolygonMode polygon_mode_back;
|
||||||
|
|
||||||
|
INSERT_UNION_PADDING_WORDS(0x3);
|
||||||
|
|
||||||
u32 polygon_offset_point_enable;
|
u32 polygon_offset_point_enable;
|
||||||
u32 polygon_offset_line_enable;
|
u32 polygon_offset_line_enable;
|
||||||
|
@ -787,7 +798,11 @@ public:
|
||||||
BitField<12, 4, u32> viewport;
|
BitField<12, 4, u32> viewport;
|
||||||
} clear_flags;
|
} clear_flags;
|
||||||
|
|
||||||
INSERT_UNION_PADDING_WORDS(0x19);
|
INSERT_UNION_PADDING_WORDS(0x10);
|
||||||
|
|
||||||
|
u32 fill_rectangle;
|
||||||
|
|
||||||
|
INSERT_UNION_PADDING_WORDS(0x8);
|
||||||
|
|
||||||
std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
|
std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
|
||||||
|
|
||||||
|
@ -1451,6 +1466,8 @@ ASSERT_REG_POSITION(depth_mode, 0x35F);
|
||||||
ASSERT_REG_POSITION(clear_color[0], 0x360);
|
ASSERT_REG_POSITION(clear_color[0], 0x360);
|
||||||
ASSERT_REG_POSITION(clear_depth, 0x364);
|
ASSERT_REG_POSITION(clear_depth, 0x364);
|
||||||
ASSERT_REG_POSITION(clear_stencil, 0x368);
|
ASSERT_REG_POSITION(clear_stencil, 0x368);
|
||||||
|
ASSERT_REG_POSITION(polygon_mode_front, 0x36B);
|
||||||
|
ASSERT_REG_POSITION(polygon_mode_back, 0x36C);
|
||||||
ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
|
ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
|
||||||
ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
|
ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
|
||||||
ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
|
ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
|
||||||
|
@ -1464,6 +1481,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
|
||||||
ASSERT_REG_POSITION(depth_bounds, 0x3E7);
|
ASSERT_REG_POSITION(depth_bounds, 0x3E7);
|
||||||
ASSERT_REG_POSITION(zeta, 0x3F8);
|
ASSERT_REG_POSITION(zeta, 0x3F8);
|
||||||
ASSERT_REG_POSITION(clear_flags, 0x43E);
|
ASSERT_REG_POSITION(clear_flags, 0x43E);
|
||||||
|
ASSERT_REG_POSITION(fill_rectangle, 0x44F);
|
||||||
ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
|
ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
|
||||||
ASSERT_REG_POSITION(rt_control, 0x487);
|
ASSERT_REG_POSITION(rt_control, 0x487);
|
||||||
ASSERT_REG_POSITION(zeta_width, 0x48a);
|
ASSERT_REG_POSITION(zeta_width, 0x48a);
|
||||||
|
|
|
@ -484,6 +484,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
|
|
||||||
SyncViewport();
|
SyncViewport();
|
||||||
SyncRasterizeEnable();
|
SyncRasterizeEnable();
|
||||||
|
SyncPolygonModes();
|
||||||
SyncColorMask();
|
SyncColorMask();
|
||||||
SyncFragmentColorClampState();
|
SyncFragmentColorClampState();
|
||||||
SyncMultiSampleState();
|
SyncMultiSampleState();
|
||||||
|
@ -562,7 +563,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
bind_ubo_pushbuffer.Bind();
|
bind_ubo_pushbuffer.Bind();
|
||||||
bind_ssbo_pushbuffer.Bind();
|
bind_ssbo_pushbuffer.Bind();
|
||||||
|
|
||||||
program_manager.Update();
|
program_manager.BindGraphicsPipeline();
|
||||||
|
|
||||||
if (texture_cache.TextureBarrier()) {
|
if (texture_cache.TextureBarrier()) {
|
||||||
glTextureBarrier();
|
glTextureBarrier();
|
||||||
|
@ -619,7 +620,7 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
|
||||||
auto kernel = shader_cache.GetComputeKernel(code_addr);
|
auto kernel = shader_cache.GetComputeKernel(code_addr);
|
||||||
SetupComputeTextures(kernel);
|
SetupComputeTextures(kernel);
|
||||||
SetupComputeImages(kernel);
|
SetupComputeImages(kernel);
|
||||||
glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT, kernel->GetHandle());
|
program_manager.BindComputeShader(kernel->GetHandle());
|
||||||
|
|
||||||
const std::size_t buffer_size =
|
const std::size_t buffer_size =
|
||||||
Tegra::Engines::KeplerCompute::NumConstBuffers *
|
Tegra::Engines::KeplerCompute::NumConstBuffers *
|
||||||
|
@ -1089,6 +1090,45 @@ void RasterizerOpenGL::SyncRasterizeEnable() {
|
||||||
oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
|
oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::SyncPolygonModes() {
|
||||||
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
|
auto& flags = gpu.dirty.flags;
|
||||||
|
if (!flags[Dirty::PolygonModes]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flags[Dirty::PolygonModes] = false;
|
||||||
|
|
||||||
|
if (gpu.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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags[Dirty::PolygonModeFront] = true;
|
||||||
|
flags[Dirty::PolygonModeBack] = true;
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_RECTANGLE_NV);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) {
|
||||||
|
flags[Dirty::PolygonModeFront] = false;
|
||||||
|
flags[Dirty::PolygonModeBack] = false;
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags[Dirty::PolygonModeFront]) {
|
||||||
|
flags[Dirty::PolygonModeFront] = false;
|
||||||
|
glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags[Dirty::PolygonModeBack]) {
|
||||||
|
flags[Dirty::PolygonModeBack] = false;
|
||||||
|
glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncColorMask() {
|
void RasterizerOpenGL::SyncColorMask() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
auto& flags = gpu.dirty.flags;
|
auto& flags = gpu.dirty.flags;
|
||||||
|
|
|
@ -177,6 +177,9 @@ private:
|
||||||
/// Syncs the rasterizer enable state to match the guest state
|
/// Syncs the rasterizer enable state to match the guest state
|
||||||
void SyncRasterizeEnable();
|
void SyncRasterizeEnable();
|
||||||
|
|
||||||
|
/// Syncs polygon modes to match the guest state
|
||||||
|
void SyncPolygonModes();
|
||||||
|
|
||||||
/// Syncs Color Mask
|
/// Syncs Color Mask
|
||||||
void SyncColorMask();
|
void SyncColorMask();
|
||||||
|
|
||||||
|
|
|
@ -2,21 +2,29 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "video_core/engines/maxwell_3d.h"
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
|
|
||||||
namespace OpenGL::GLShader {
|
namespace OpenGL::GLShader {
|
||||||
|
|
||||||
using Tegra::Engines::Maxwell3D;
|
ProgramManager::ProgramManager() = default;
|
||||||
|
|
||||||
ProgramManager::~ProgramManager() = default;
|
ProgramManager::~ProgramManager() = default;
|
||||||
|
|
||||||
void ProgramManager::Create() {
|
void ProgramManager::Create() {
|
||||||
pipeline.Create();
|
graphics_pipeline.Create();
|
||||||
|
glBindProgramPipeline(graphics_pipeline.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramManager::Update() {
|
void ProgramManager::BindGraphicsPipeline() {
|
||||||
|
if (!is_graphics_bound) {
|
||||||
|
is_graphics_bound = true;
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid updating the pipeline when values have no changed
|
// Avoid updating the pipeline when values have no changed
|
||||||
if (old_state == current_state) {
|
if (old_state == current_state) {
|
||||||
return;
|
return;
|
||||||
|
@ -25,16 +33,21 @@ void ProgramManager::Update() {
|
||||||
// Workaround for AMD bug
|
// Workaround for AMD bug
|
||||||
static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
|
static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
|
||||||
GL_FRAGMENT_SHADER_BIT};
|
GL_FRAGMENT_SHADER_BIT};
|
||||||
glUseProgramStages(pipeline.handle, all_used_stages, 0);
|
const GLuint handle = graphics_pipeline.handle;
|
||||||
|
glUseProgramStages(handle, all_used_stages, 0);
|
||||||
glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
|
glUseProgramStages(handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
|
||||||
glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader);
|
glUseProgramStages(handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader);
|
||||||
glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader);
|
glUseProgramStages(handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader);
|
||||||
|
|
||||||
old_state = current_state;
|
old_state = current_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell) {
|
void ProgramManager::BindComputeShader(GLuint program) {
|
||||||
|
is_graphics_bound = false;
|
||||||
|
glUseProgram(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaxwellUniformData::SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell) {
|
||||||
const auto& regs = maxwell.regs;
|
const auto& regs = maxwell.regs;
|
||||||
|
|
||||||
// Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value.
|
// Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value.
|
||||||
|
|
|
@ -28,11 +28,16 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
|
||||||
|
|
||||||
class ProgramManager {
|
class ProgramManager {
|
||||||
public:
|
public:
|
||||||
|
explicit ProgramManager();
|
||||||
~ProgramManager();
|
~ProgramManager();
|
||||||
|
|
||||||
void Create();
|
void Create();
|
||||||
|
|
||||||
void Update();
|
/// Updates the graphics pipeline and binds it.
|
||||||
|
void BindGraphicsPipeline();
|
||||||
|
|
||||||
|
/// Binds a compute shader.
|
||||||
|
void BindComputeShader(GLuint program);
|
||||||
|
|
||||||
void UseVertexShader(GLuint program) {
|
void UseVertexShader(GLuint program) {
|
||||||
current_state.vertex_shader = program;
|
current_state.vertex_shader = program;
|
||||||
|
@ -46,33 +51,27 @@ public:
|
||||||
current_state.fragment_shader = program;
|
current_state.fragment_shader = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint GetHandle() const {
|
|
||||||
return pipeline.handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UseTrivialFragmentShader() {
|
|
||||||
current_state.fragment_shader = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PipelineState {
|
struct PipelineState {
|
||||||
bool operator==(const PipelineState& rhs) const {
|
bool operator==(const PipelineState& rhs) const noexcept {
|
||||||
return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader &&
|
return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader &&
|
||||||
geometry_shader == rhs.geometry_shader;
|
geometry_shader == rhs.geometry_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const PipelineState& rhs) const {
|
bool operator!=(const PipelineState& rhs) const noexcept {
|
||||||
return !operator==(rhs);
|
return !operator==(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint vertex_shader{};
|
GLuint vertex_shader = 0;
|
||||||
GLuint fragment_shader{};
|
GLuint fragment_shader = 0;
|
||||||
GLuint geometry_shader{};
|
GLuint geometry_shader = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
OGLPipeline pipeline;
|
OGLPipeline graphics_pipeline;
|
||||||
|
OGLPipeline compute_pipeline;
|
||||||
PipelineState current_state;
|
PipelineState current_state;
|
||||||
PipelineState old_state;
|
PipelineState old_state;
|
||||||
|
bool is_graphics_bound = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenGL::GLShader
|
} // namespace OpenGL::GLShader
|
||||||
|
|
|
@ -94,6 +94,15 @@ void SetupDirtyShaders(Tables& tables) {
|
||||||
Shaders);
|
Shaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupDirtyPolygonModes(Tables& tables) {
|
||||||
|
tables[0][OFF(polygon_mode_front)] = PolygonModeFront;
|
||||||
|
tables[0][OFF(polygon_mode_back)] = PolygonModeBack;
|
||||||
|
|
||||||
|
tables[1][OFF(polygon_mode_front)] = PolygonModes;
|
||||||
|
tables[1][OFF(polygon_mode_back)] = PolygonModes;
|
||||||
|
tables[0][OFF(fill_rectangle)] = PolygonModes;
|
||||||
|
}
|
||||||
|
|
||||||
void SetupDirtyDepthTest(Tables& tables) {
|
void SetupDirtyDepthTest(Tables& tables) {
|
||||||
auto& table = tables[0];
|
auto& table = tables[0];
|
||||||
table[OFF(depth_test_enable)] = DepthTest;
|
table[OFF(depth_test_enable)] = DepthTest;
|
||||||
|
@ -211,6 +220,7 @@ void StateTracker::Initialize() {
|
||||||
SetupDirtyVertexArrays(tables);
|
SetupDirtyVertexArrays(tables);
|
||||||
SetupDirtyVertexFormat(tables);
|
SetupDirtyVertexFormat(tables);
|
||||||
SetupDirtyShaders(tables);
|
SetupDirtyShaders(tables);
|
||||||
|
SetupDirtyPolygonModes(tables);
|
||||||
SetupDirtyDepthTest(tables);
|
SetupDirtyDepthTest(tables);
|
||||||
SetupDirtyStencilTest(tables);
|
SetupDirtyStencilTest(tables);
|
||||||
SetupDirtyAlphaTest(tables);
|
SetupDirtyAlphaTest(tables);
|
||||||
|
|
|
@ -59,6 +59,10 @@ enum : u8 {
|
||||||
Shaders,
|
Shaders,
|
||||||
ClipDistances,
|
ClipDistances,
|
||||||
|
|
||||||
|
PolygonModes,
|
||||||
|
PolygonModeFront,
|
||||||
|
PolygonModeBack,
|
||||||
|
|
||||||
ColorMask,
|
ColorMask,
|
||||||
FrontFace,
|
FrontFace,
|
||||||
CullTest,
|
CullTest,
|
||||||
|
@ -111,6 +115,13 @@ public:
|
||||||
flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
|
flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
void NotifyViewport0() {
|
||||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||||
flags[OpenGL::Dirty::Viewports] = true;
|
flags[OpenGL::Dirty::Viewports] = true;
|
||||||
|
|
|
@ -488,5 +488,18 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) {
|
||||||
return GL_COPY;
|
return GL_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) {
|
||||||
|
switch (polygon_mode) {
|
||||||
|
case Maxwell::PolygonMode::Point:
|
||||||
|
return GL_POINT;
|
||||||
|
case Maxwell::PolygonMode::Line:
|
||||||
|
return GL_LINE;
|
||||||
|
case Maxwell::PolygonMode::Fill:
|
||||||
|
return GL_FILL;
|
||||||
|
}
|
||||||
|
UNREACHABLE_MSG("Invalid polygon mode={}", static_cast<int>(polygon_mode));
|
||||||
|
return GL_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MaxwellToGL
|
} // namespace MaxwellToGL
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -443,7 +443,6 @@ void RendererOpenGL::InitOpenGLObjects() {
|
||||||
|
|
||||||
// Create program pipeline
|
// Create program pipeline
|
||||||
program_manager.Create();
|
program_manager.Create();
|
||||||
glBindProgramPipeline(program_manager.GetHandle());
|
|
||||||
|
|
||||||
// Generate VBO handle for drawing
|
// Generate VBO handle for drawing
|
||||||
vertex_buffer.Create();
|
vertex_buffer.Create();
|
||||||
|
@ -577,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
|
|
||||||
// TODO: Signal state tracker about these changes
|
// TODO: Signal state tracker about these changes
|
||||||
state_tracker.NotifyScreenDrawVertexArray();
|
state_tracker.NotifyScreenDrawVertexArray();
|
||||||
|
state_tracker.NotifyPolygonModes();
|
||||||
state_tracker.NotifyViewport0();
|
state_tracker.NotifyViewport0();
|
||||||
state_tracker.NotifyScissor0();
|
state_tracker.NotifyScissor0();
|
||||||
state_tracker.NotifyColorMask0();
|
state_tracker.NotifyColorMask0();
|
||||||
|
@ -596,7 +596,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
program_manager.UseVertexShader(vertex_program.handle);
|
program_manager.UseVertexShader(vertex_program.handle);
|
||||||
program_manager.UseGeometryShader(0);
|
program_manager.UseGeometryShader(0);
|
||||||
program_manager.UseFragmentShader(fragment_program.handle);
|
program_manager.UseFragmentShader(fragment_program.handle);
|
||||||
program_manager.Update();
|
program_manager.BindGraphicsPipeline();
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
if (screen_info.display_srgb) {
|
if (screen_info.display_srgb) {
|
||||||
|
@ -612,6 +612,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
glDisablei(GL_BLEND, 0);
|
glDisablei(GL_BLEND, 0);
|
||||||
glDisablei(GL_SCISSOR_TEST, 0);
|
glDisablei(GL_SCISSOR_TEST, 0);
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
|
|
@ -854,7 +854,7 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
|
||||||
|
|
||||||
void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
|
void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
|
||||||
MICROPROFILE_SCOPE(Vulkan_Images);
|
MICROPROFILE_SCOPE(Vulkan_Images);
|
||||||
const auto& gpu = system.GPU().KeplerCompute();
|
const auto& gpu = system.GPU().Maxwell3D();
|
||||||
for (const auto& entry : entries.images) {
|
for (const auto& entry : entries.images) {
|
||||||
const auto tic = GetTextureInfo(gpu, entry, stage).tic;
|
const auto tic = GetTextureInfo(gpu, entry, stage).tic;
|
||||||
SetupImage(tic, entry);
|
SetupImage(tic, entry);
|
||||||
|
@ -915,6 +915,13 @@ void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) {
|
||||||
|
|
||||||
void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
|
void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
|
||||||
const Tegra::Engines::ConstBufferInfo& buffer) {
|
const Tegra::Engines::ConstBufferInfo& buffer) {
|
||||||
|
if (!buffer.enabled) {
|
||||||
|
// Set values to zero to unbind buffers
|
||||||
|
update_descriptor_queue.AddBuffer(buffer_cache.GetEmptyBuffer(sizeof(float)), 0,
|
||||||
|
sizeof(float));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Align the size to avoid bad std140 interactions
|
// Align the size to avoid bad std140 interactions
|
||||||
const std::size_t size =
|
const std::size_t size =
|
||||||
Common::AlignUp(CalculateConstBufferSize(entry, buffer), 4 * sizeof(float));
|
Common::AlignUp(CalculateConstBufferSize(entry, buffer), 4 * sizeof(float));
|
||||||
|
|
|
@ -73,7 +73,8 @@ VKBuffer* VKStagingBufferPool::TryGetReservedBuffer(std::size_t size, bool host_
|
||||||
VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) {
|
VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) {
|
||||||
const auto usage =
|
const auto usage =
|
||||||
vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst |
|
vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst |
|
||||||
vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer;
|
vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer |
|
||||||
|
vk::BufferUsageFlagBits::eIndexBuffer;
|
||||||
const u32 log2 = Common::Log2Ceil64(size);
|
const u32 log2 = Common::Log2Ceil64(size);
|
||||||
const vk::BufferCreateInfo buffer_ci({}, 1ULL << log2, usage, vk::SharingMode::eExclusive, 0,
|
const vk::BufferCreateInfo buffer_ci({}, 1ULL << log2, usage, vk::SharingMode::eExclusive, 0,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
Reference in New Issue