From 7ad64ff16b702f77c554be23ee2156f65c9f32c0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 8 Jan 2017 14:47:16 -0500 Subject: [PATCH] Made further efforts to support throughput via memory barrier. --- Outputs/CRT/Internals/CRTOpenGL.cpp | 40 ++++++++++++------- .../Internals/Shaders/IntermediateShader.cpp | 8 ++-- .../Internals/Shaders/IntermediateShader.hpp | 2 +- .../CRT/Internals/Shaders/OutputShader.cpp | 9 ++++- .../CRT/Internals/Shaders/OutputShader.hpp | 4 ++ 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index 479c73e93..e388c6453 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -18,13 +18,14 @@ using namespace Outputs::CRT; namespace { - static const GLenum composite_texture_unit = GL_TEXTURE0; - static const GLenum separated_texture_unit = GL_TEXTURE1; - static const GLenum filtered_texture_unit = GL_TEXTURE2; - static const GLenum source_data_texture_unit = GL_TEXTURE3; - static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE4; + static const GLenum source_data_texture_unit = GL_TEXTURE0; + static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE1; - static const GLenum work_texture_unit = GL_TEXTURE0; + static const GLenum composite_texture_unit = GL_TEXTURE2; + static const GLenum separated_texture_unit = GL_TEXTURE3; + static const GLenum filtered_texture_unit = GL_TEXTURE4; + + static const GLenum work_texture_unit = GL_TEXTURE2; } OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) : @@ -62,11 +63,11 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) : } #endif - if(supports_texture_barrier) - { - work_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight*2, work_texture_unit)); - } - else +// if(supports_texture_barrier) +// { +// work_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight*2, work_texture_unit)); +// } +// else { composite_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, composite_texture_unit)); separated_texture_.reset(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, separated_texture_unit)); @@ -292,17 +293,27 @@ void OpenGLOutputBuilder::prepare_composite_input_shaders() composite_input_shader_program_ = OpenGL::IntermediateShader::make_source_conversion_shader(composite_shader_, rgb_shader_); composite_input_shader_program_->set_source_texture_unit(source_data_texture_unit); composite_input_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight); - composite_input_shader_program_->set_vertical_offsets(0.0f, 0.0f); composite_separation_filter_program_ = OpenGL::IntermediateShader::make_chroma_luma_separation_shader(); composite_separation_filter_program_->set_source_texture_unit(work_texture_ ? work_texture_unit : composite_texture_unit); composite_separation_filter_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight); - composite_separation_filter_program_->set_vertical_offsets(0.0f, work_texture_ ? 0.5f : 0.0f); composite_chrominance_filter_shader_program_ = OpenGL::IntermediateShader::make_chroma_filter_shader(); composite_chrominance_filter_shader_program_->set_source_texture_unit(work_texture_ ? work_texture_unit : separated_texture_unit); composite_chrominance_filter_shader_program_->set_output_size(IntermediateBufferWidth, IntermediateBufferHeight); - composite_chrominance_filter_shader_program_->set_vertical_offsets(work_texture_ ? 0.5f : 0.0f, 0.0f); + + if(work_texture_) + { + composite_input_shader_program_->set_is_double_height(true, 0.0f, 0.0f); + composite_separation_filter_program_->set_is_double_height(true, 0.0f, 0.5f); + composite_chrominance_filter_shader_program_->set_is_double_height(true, 0.5f, 0.0f); + } + else + { + composite_input_shader_program_->set_is_double_height(false); + composite_separation_filter_program_->set_is_double_height(false); + composite_chrominance_filter_shader_program_->set_is_double_height(false); + } } void OpenGLOutputBuilder::prepare_rgb_input_shaders() @@ -337,6 +348,7 @@ void OpenGLOutputBuilder::prepare_output_shader() { output_shader_program_ = OpenGL::OutputShader::make_shader("", "texture(texID, srcCoordinatesVarying).rgb", false); output_shader_program_->set_source_texture_unit(work_texture_ ? work_texture_unit : filtered_texture_unit); + output_shader_program_->set_origin_is_double_height(!!work_texture_); } void OpenGLOutputBuilder::prepare_output_vertex_array() diff --git a/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp b/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp index c85735d21..06c1fa052 100644 --- a/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp +++ b/Outputs/CRT/Internals/Shaders/IntermediateShader.cpp @@ -48,6 +48,7 @@ std::unique_ptr IntermediateShader::make_shader(const char * "uniform vec2 widthScalers;" "uniform float inputVerticalOffset;" "uniform float outputVerticalOffset;" + "uniform float textureHeightDivisor;" "out vec2 phaseAndAmplitudeVarying;" "out vec2 inputPositionsVarying[11];" @@ -477,8 +478,9 @@ void IntermediateShader::set_width_scalers(float input_scaler, float output_scal set_uniform("widthScalers", input_scaler, output_scaler); } -void IntermediateShader::set_vertical_offsets(float input, float output) +void IntermediateShader::set_is_double_height(bool is_double_height, float input_offset, float output_offset) { - set_uniform("inputVerticalOffset", input); - set_uniform("outputVerticalOffset", output); + set_uniform("textureHeightDivisor", is_double_height ? 2.0f : 1.0f); + set_uniform("inputVerticalOffset", input_offset); + set_uniform("outputVerticalOffset", output_offset); } diff --git a/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp b/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp index c8c801809..046e3bb69 100644 --- a/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp +++ b/Outputs/CRT/Internals/Shaders/IntermediateShader.hpp @@ -92,7 +92,7 @@ public: /*! Sets source and target vertical offsets. */ - void set_vertical_offsets(float input, float output); + void set_is_double_height(bool is_double_height, float input_offset = 0.0f, float output_offset = 0.0f); private: static std::unique_ptr make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition); diff --git a/Outputs/CRT/Internals/Shaders/OutputShader.cpp b/Outputs/CRT/Internals/Shaders/OutputShader.cpp index 86f0f928c..ea31acebd 100644 --- a/Outputs/CRT/Internals/Shaders/OutputShader.cpp +++ b/Outputs/CRT/Internals/Shaders/OutputShader.cpp @@ -39,6 +39,7 @@ std::unique_ptr OutputShader::make_shader(const char *fragment_met "uniform vec2 scanNormal;" "uniform %s texID;" "uniform float inputScaler;" + "uniform int textureHeightDivisor;" "out float lateralVarying;" "out vec2 srcCoordinatesVarying;" @@ -53,9 +54,10 @@ std::unique_ptr OutputShader::make_shader(const char *fragment_met "lateralVarying = lateral - 0.5;" "vec2 vSrcCoordinates = vec2(x, vertical.y);" - "ivec2 textureSize = textureSize(texID, 0);" + "ivec2 textureSize = textureSize(texID, 0) * ivec2(1, textureHeightDivisor);" "iSrcCoordinatesVarying = vSrcCoordinates;" "srcCoordinatesVarying = vec2(inputScaler * vSrcCoordinates.x / textureSize.x, (vSrcCoordinates.y + 0.5) / textureSize.y);" + "srcCoordinatesVarying.x = srcCoordinatesVarying.x - mod(srcCoordinatesVarying.x, 1.0 / textureSize.x);" "vec2 vPosition = vec2(x, vertical.x);" "vec2 floatingPosition = (vPosition / positionConversion) + lateral * scanNormal;" @@ -123,3 +125,8 @@ void OutputShader::set_input_width_scaler(float input_scaler) { set_uniform("inputScaler", input_scaler); } + +void OutputShader::set_origin_is_double_height(bool is_double_height) +{ + set_uniform("textureHeightDivisor", is_double_height ? 2 : 1); +} diff --git a/Outputs/CRT/Internals/Shaders/OutputShader.hpp b/Outputs/CRT/Internals/Shaders/OutputShader.hpp index 44f4ec041..0df8143f4 100644 --- a/Outputs/CRT/Internals/Shaders/OutputShader.hpp +++ b/Outputs/CRT/Internals/Shaders/OutputShader.hpp @@ -59,6 +59,10 @@ public: */ void set_timing(unsigned int height_of_display, unsigned int cycles_per_line, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider); + /*! + */ + void set_origin_is_double_height(bool is_double_height); + /*! Sets the proportion of the input area that should be considered the whole width — 1.0 means use all available space, 0.5 means use half, etc.