1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-11 04:28:58 +00:00

Made an attempt to consolidate timestamp bases to a single vector and hence to lump all geometry into one or two calls, with no repetitive setting of a uniform. I'm not sure the result is correct yet.

This commit is contained in:
Thomas Harte 2016-04-04 21:57:27 -04:00
parent 4595741ab0
commit c0cd1ed89e
4 changed files with 47 additions and 41 deletions

View File

@ -98,6 +98,7 @@ Flywheel::SyncEvent CRT::get_next_horizontal_sync_event(bool hsync_is_requested,
#define output_tex_x(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 0]) #define output_tex_x(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 0])
#define output_tex_y(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 2]) #define output_tex_y(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 2])
#define output_lateral(v) next_run[OutputVertexSize*v + OutputVertexOffsetOfLateral] #define output_lateral(v) next_run[OutputVertexSize*v + OutputVertexOffsetOfLateral]
#define output_frame_id(v) next_run[OutputVertexSize*v + OutputVertexOffsetOfFrameID]
#define output_timestamp(v) (*(uint32_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTimestamp]) #define output_timestamp(v) (*(uint32_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTimestamp])
#define input_input_position_x(v) (*(uint16_t *)&next_run[InputVertexSize*v + InputVertexOffsetOfInputPosition + 0]) #define input_input_position_x(v) (*(uint16_t *)&next_run[InputVertexSize*v + InputVertexOffsetOfInputPosition + 0])
@ -153,6 +154,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
output_tex_y(0) = output_tex_y(1) = output_tex_y(2) = output_tex_y(3) = output_tex_y(4) = output_tex_y(5) = tex_y; output_tex_y(0) = output_tex_y(1) = output_tex_y(2) = output_tex_y(3) = output_tex_y(4) = output_tex_y(5) = tex_y;
output_lateral(0) = output_lateral(1) = output_lateral(3) = 0; output_lateral(0) = output_lateral(1) = output_lateral(3) = 0;
output_lateral(2) = output_lateral(4) = output_lateral(5) = 1; output_lateral(2) = output_lateral(4) = output_lateral(5) = 1;
output_frame_id(0) = output_frame_id(1) = output_frame_id(2) = output_frame_id(3) = output_frame_id(4) = output_frame_id(5) = (uint8_t)_openGL_output_builder->get_current_field();
} }
else else
{ {

View File

@ -21,6 +21,7 @@ const size_t OutputVertexOffsetOfPosition = 0;
const size_t OutputVertexOffsetOfTexCoord = 4; const size_t OutputVertexOffsetOfTexCoord = 4;
const size_t OutputVertexOffsetOfTimestamp = 8; const size_t OutputVertexOffsetOfTimestamp = 8;
const size_t OutputVertexOffsetOfLateral = 12; const size_t OutputVertexOffsetOfLateral = 12;
const size_t OutputVertexOffsetOfFrameID = 13;
const size_t OutputVertexSize = 16; const size_t OutputVertexSize = 16;

View File

@ -150,7 +150,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
// glActiveTexture(GL_TEXTURE0 + first_supplied_buffer_texture_unit + buffer); // glActiveTexture(GL_TEXTURE0 + first_supplied_buffer_texture_unit + buffer);
if(_buffer_builder->_next_write_y_position < _buffer_builder->last_uploaded_line) if(_buffer_builder->_next_write_y_position < _buffer_builder->last_uploaded_line)
{ {
glTexSubImage2D(GL_TEXTURE_2D, 0, glTexSubImage2D( GL_TEXTURE_2D, 0,
0, (GLint)_buffer_builder->last_uploaded_line, 0, (GLint)_buffer_builder->last_uploaded_line,
InputBufferBuilderWidth, (GLint)(InputBufferBuilderHeight - _buffer_builder->last_uploaded_line), InputBufferBuilderWidth, (GLint)(InputBufferBuilderHeight - _buffer_builder->last_uploaded_line),
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE, formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
@ -160,7 +160,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
if(_buffer_builder->_next_write_y_position > _buffer_builder->last_uploaded_line) if(_buffer_builder->_next_write_y_position > _buffer_builder->last_uploaded_line)
{ {
glTexSubImage2D(GL_TEXTURE_2D, 0, glTexSubImage2D( GL_TEXTURE_2D, 0,
0, (GLint)_buffer_builder->last_uploaded_line, 0, (GLint)_buffer_builder->last_uploaded_line,
InputBufferBuilderWidth, (GLint)(1 + _buffer_builder->_next_write_y_position - _buffer_builder->last_uploaded_line), InputBufferBuilderWidth, (GLint)(1 + _buffer_builder->_next_write_y_position - _buffer_builder->last_uploaded_line),
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE, formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
@ -200,35 +200,37 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
// draw all sitting frames // draw all sitting frames
unsigned int run = (unsigned int)_run_write_pointer; unsigned int run = (unsigned int)_run_write_pointer;
GLint total_age = 0; GLint total_age = 0;
float timestampBases[4];
size_t start = 0, count = 0;
for(int c = 0; c < NumberOfFields; c++) for(int c = 0; c < NumberOfFields; c++)
{ {
// update the total age at the start of this set of runs
total_age += _run_builders[run]->duration; total_age += _run_builders[run]->duration;
timestampBases[run] = (float)total_age;
if(_run_builders[run]->amount_of_data > 0) count += _run_builders[run]->amount_of_data;
{ start = _run_builders[run]->start;
// draw
glUniform1f(timestampBaseUniform, (GLfloat)total_age);
GLsizei count = (GLsizei)(_run_builders[run]->amount_of_data / InputVertexSize);
GLsizei max_count = (GLsizei)((InputVertexBufferDataSize - _run_builders[run]->start) / InputVertexSize);
if(count < max_count)
{
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(_run_builders[run]->start / InputVertexSize), count);
}
else
{
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(_run_builders[run]->start / InputVertexSize), max_count);
glDrawArrays(GL_TRIANGLE_STRIP, 0, count - max_count);
}
}
// advance back in time
run = (run - 1 + NumberOfFields) % NumberOfFields; run = (run - 1 + NumberOfFields) % NumberOfFields;
} }
glUniform4fv(timestampBaseUniform, 1, timestampBases);
if(count > 0)
{
// draw
GLsizei primitive_count = (GLsizei)(count / InputVertexSize);
GLsizei max_count = (GLsizei)((InputVertexBufferDataSize - start) / InputVertexSize);
if(primitive_count < max_count)
{
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(start / InputVertexSize), primitive_count);
}
else
{
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(start / InputVertexSize), max_count);
glDrawArrays(GL_TRIANGLE_STRIP, 0, primitive_count - max_count);
}
}
} }
// drawing commands having been issued, reclaim the array buffer pointer // drawing commands having been issued, reclaim the array buffer pointer
_buffer_builder->move_to_new_line(); // _buffer_builder->move_to_new_line();
_output_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, InputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); _output_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, InputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
_input_texture_data = (uint8_t *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _input_texture_array_size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); _input_texture_data = (uint8_t *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _input_texture_array_size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
_output_mutex->unlock(); _output_mutex->unlock();
@ -282,8 +284,6 @@ char *OpenGLOutputBuilder::get_input_vertex_shader()
"in vec2 phaseAndAmplitude;" "in vec2 phaseAndAmplitude;"
"in float phaseTime;" "in float phaseTime;"
"uniform vec2 outputTextureSize;"
"uniform vec2 inputTextureSize;"
"uniform float phaseCyclesPerTick;" "uniform float phaseCyclesPerTick;"
"out vec2 inputPositionVarying;" "out vec2 inputPositionVarying;"
@ -339,7 +339,7 @@ char *OpenGLOutputBuilder::get_output_vertex_shader()
"in vec2 position;" "in vec2 position;"
"in vec2 srcCoordinates;" "in vec2 srcCoordinates;"
"in float lateral;" "in vec2 lateralAndTimestampBaseOffset;"
"in float timestamp;" "in float timestamp;"
"uniform vec2 boundsOrigin;" "uniform vec2 boundsOrigin;"
@ -349,30 +349,34 @@ char *OpenGLOutputBuilder::get_output_vertex_shader()
"out vec2 shadowMaskCoordinates;" "out vec2 shadowMaskCoordinates;"
"out float alpha;" "out float alpha;"
"uniform vec2 textureSize;" "uniform vec4 timestampBase;"
"uniform float timestampBase;"
"uniform float ticksPerFrame;" "uniform float ticksPerFrame;"
"uniform vec2 positionConversion;" "uniform vec2 positionConversion;"
"uniform vec2 scanNormal;" "uniform vec2 scanNormal;"
"uniform vec3 filterCoefficients;" "uniform vec3 filterCoefficients;"
"uniform usampler2D texID;"
"uniform sampler2D shadowMaskTexID;"
"const float shadowMaskMultiple = 600;" "const float shadowMaskMultiple = 600;"
"out vec2 srcCoordinatesVarying;" "out vec2 srcCoordinatesVarying;"
"void main(void)" "void main(void)"
"{" "{"
"lateralVarying = lateral + 1.0707963267949;" "lateralVarying = lateralAndTimestampBaseOffset.x + 1.0707963267949;"
"shadowMaskCoordinates = position * vec2(shadowMaskMultiple, shadowMaskMultiple * 0.85057471264368);" "shadowMaskCoordinates = position * vec2(shadowMaskMultiple, shadowMaskMultiple * 0.85057471264368);"
"ivec2 textureSize = textureSize(texID, 0);"
"srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);" "srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);"
"float age = (timestampBase - timestamp) / ticksPerFrame;" "float age = (timestampBase[int(lateralAndTimestampBaseOffset.y)] - timestamp) / ticksPerFrame;"
"vec3 alphas = vec3(10.0 * exp((-age - 1.33) * 2.0), 10.0 * exp(-(age - 0.66) * 2.0), 10.0 * exp(-age * 2.0));" "alpha = 10.0 * exp(-age * 2.0);"
// "vec3 alphas = vec3(10.0 * exp((-age - 1.33) * 2.0), 10.0 * exp(-(age - 0.66) * 2.0), 10.0 * exp(-age * 2.0));"
// "alpha = min(10.0 * exp(-age * 2.0), 1.0);" // "alpha = min(10.0 * exp(-age * 2.0), 1.0);"
"alpha = dot(alphas, filterCoefficients);" // "alpha = dot(alphas, filterCoefficients);"
"vec2 floatingPosition = (position / positionConversion) + lateral*scanNormal;" "vec2 floatingPosition = (position / positionConversion) + lateralAndTimestampBaseOffset.x * scanNormal;"
"vec2 mappedPosition = (floatingPosition - boundsOrigin) / boundsSize;" "vec2 mappedPosition = (floatingPosition - boundsOrigin) / boundsSize;"
"gl_Position = vec4(mappedPosition.x * 2.0 - 1.0, 1.0 - mappedPosition.y * 2.0, 0.0, 1.0);" "gl_Position = vec4(mappedPosition.x * 2.0 - 1.0, 1.0 - mappedPosition.y * 2.0, 0.0, 1.0);"
"}"); "}");
@ -440,13 +444,9 @@ void OpenGLOutputBuilder::prepare_composite_input_shader()
composite_input_shader_program = std::unique_ptr<OpenGL::Shader>(new OpenGL::Shader(vertex_shader, fragment_shader)); composite_input_shader_program = std::unique_ptr<OpenGL::Shader>(new OpenGL::Shader(vertex_shader, fragment_shader));
GLint texIDUniform = composite_input_shader_program->get_uniform_location("texID"); GLint texIDUniform = composite_input_shader_program->get_uniform_location("texID");
GLint inputTextureSizeUniform = composite_input_shader_program->get_uniform_location("inputTextureSize");
GLint outputTextureSizeUniform = composite_input_shader_program->get_uniform_location("outputTextureSize");
GLint phaseCyclesPerTickUniform = composite_input_shader_program->get_uniform_location("phaseCyclesPerTick"); GLint phaseCyclesPerTickUniform = composite_input_shader_program->get_uniform_location("phaseCyclesPerTick");
glUniform1i(texIDUniform, first_supplied_buffer_texture_unit); glUniform1i(texIDUniform, first_supplied_buffer_texture_unit);
glUniform2f(outputTextureSizeUniform, IntermediateBufferWidth, IntermediateBufferHeight);
glUniform2f(inputTextureSizeUniform, InputBufferBuilderWidth, InputBufferBuilderHeight);
glUniform1f(phaseCyclesPerTickUniform, (float)_colour_cycle_numerator / (float)(_colour_cycle_denominator * _cycles_per_line)); glUniform1f(phaseCyclesPerTickUniform, (float)_colour_cycle_numerator / (float)(_colour_cycle_denominator * _cycles_per_line));
} }
free(vertex_shader); free(vertex_shader);
@ -510,7 +510,6 @@ void OpenGLOutputBuilder::prepare_rgb_output_shader()
GLint texIDUniform = rgb_shader_program->get_uniform_location("texID"); GLint texIDUniform = rgb_shader_program->get_uniform_location("texID");
GLint shadowMaskTexIDUniform = rgb_shader_program->get_uniform_location("shadowMaskTexID"); GLint shadowMaskTexIDUniform = rgb_shader_program->get_uniform_location("shadowMaskTexID");
GLint textureSizeUniform = rgb_shader_program->get_uniform_location("textureSize");
GLint ticksPerFrameUniform = rgb_shader_program->get_uniform_location("ticksPerFrame"); GLint ticksPerFrameUniform = rgb_shader_program->get_uniform_location("ticksPerFrame");
GLint scanNormalUniform = rgb_shader_program->get_uniform_location("scanNormal"); GLint scanNormalUniform = rgb_shader_program->get_uniform_location("scanNormal");
GLint positionConversionUniform = rgb_shader_program->get_uniform_location("positionConversion"); GLint positionConversionUniform = rgb_shader_program->get_uniform_location("positionConversion");
@ -518,7 +517,6 @@ void OpenGLOutputBuilder::prepare_rgb_output_shader()
glUniform1i(texIDUniform, first_supplied_buffer_texture_unit); glUniform1i(texIDUniform, first_supplied_buffer_texture_unit);
glUniform1i(shadowMaskTexIDUniform, 1); glUniform1i(shadowMaskTexIDUniform, 1);
glUniform2f(textureSizeUniform, InputBufferBuilderWidth, InputBufferBuilderHeight);
glUniform1f(ticksPerFrameUniform, (GLfloat)(_cycles_per_line * _height_of_display)); glUniform1f(ticksPerFrameUniform, (GLfloat)(_cycles_per_line * _height_of_display));
glUniform2f(positionConversionUniform, _horizontal_scan_period, _vertical_scan_period / (unsigned int)_vertical_period_divider); glUniform2f(positionConversionUniform, _horizontal_scan_period, _vertical_scan_period / (unsigned int)_vertical_period_divider);
@ -545,7 +543,7 @@ void OpenGLOutputBuilder::prepare_output_vertex_array()
{ {
GLint positionAttribute = rgb_shader_program->get_attrib_location("position"); GLint positionAttribute = rgb_shader_program->get_attrib_location("position");
GLint textureCoordinatesAttribute = rgb_shader_program->get_attrib_location("srcCoordinates"); GLint textureCoordinatesAttribute = rgb_shader_program->get_attrib_location("srcCoordinates");
GLint lateralAttribute = rgb_shader_program->get_attrib_location("lateral"); GLint lateralAttribute = rgb_shader_program->get_attrib_location("lateralAndTimestampBaseOffset");
GLint timestampAttribute = rgb_shader_program->get_attrib_location("timestamp"); GLint timestampAttribute = rgb_shader_program->get_attrib_location("timestamp");
glEnableVertexAttribArray((GLuint)positionAttribute); glEnableVertexAttribArray((GLuint)positionAttribute);
@ -557,7 +555,7 @@ void OpenGLOutputBuilder::prepare_output_vertex_array()
glVertexAttribPointer((GLuint)positionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfPosition); glVertexAttribPointer((GLuint)positionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfPosition);
glVertexAttribPointer((GLuint)textureCoordinatesAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfTexCoord); glVertexAttribPointer((GLuint)textureCoordinatesAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfTexCoord);
glVertexAttribPointer((GLuint)timestampAttribute, 4, GL_UNSIGNED_INT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfTimestamp); glVertexAttribPointer((GLuint)timestampAttribute, 4, GL_UNSIGNED_INT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfTimestamp);
glVertexAttribPointer((GLuint)lateralAttribute, 1, GL_UNSIGNED_BYTE, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfLateral); glVertexAttribPointer((GLuint)lateralAttribute, 2, GL_UNSIGNED_BYTE, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfLateral);
} }
} }

View File

@ -164,6 +164,11 @@ class OpenGLOutputBuilder {
_output_mutex->unlock(); _output_mutex->unlock();
} }
inline int get_current_field()
{
return _run_write_pointer;
}
inline uint8_t *allocate_write_area(size_t required_length) inline uint8_t *allocate_write_area(size_t required_length)
{ {
_output_mutex->lock(); _output_mutex->lock();