1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +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_y(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 2])
#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 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_lateral(0) = output_lateral(1) = output_lateral(3) = 0;
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
{

View File

@ -21,6 +21,7 @@ const size_t OutputVertexOffsetOfPosition = 0;
const size_t OutputVertexOffsetOfTexCoord = 4;
const size_t OutputVertexOffsetOfTimestamp = 8;
const size_t OutputVertexOffsetOfLateral = 12;
const size_t OutputVertexOffsetOfFrameID = 13;
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);
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,
InputBufferBuilderWidth, (GLint)(InputBufferBuilderHeight - _buffer_builder->last_uploaded_line),
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)
{
glTexSubImage2D(GL_TEXTURE_2D, 0,
glTexSubImage2D( GL_TEXTURE_2D, 0,
0, (GLint)_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,
@ -200,35 +200,37 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
// draw all sitting frames
unsigned int run = (unsigned int)_run_write_pointer;
GLint total_age = 0;
float timestampBases[4];
size_t start = 0, count = 0;
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;
if(_run_builders[run]->amount_of_data > 0)
{
// 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
timestampBases[run] = (float)total_age;
count += _run_builders[run]->amount_of_data;
start = _run_builders[run]->start;
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
_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);
_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();
@ -282,8 +284,6 @@ char *OpenGLOutputBuilder::get_input_vertex_shader()
"in vec2 phaseAndAmplitude;"
"in float phaseTime;"
"uniform vec2 outputTextureSize;"
"uniform vec2 inputTextureSize;"
"uniform float phaseCyclesPerTick;"
"out vec2 inputPositionVarying;"
@ -339,7 +339,7 @@ char *OpenGLOutputBuilder::get_output_vertex_shader()
"in vec2 position;"
"in vec2 srcCoordinates;"
"in float lateral;"
"in vec2 lateralAndTimestampBaseOffset;"
"in float timestamp;"
"uniform vec2 boundsOrigin;"
@ -349,30 +349,34 @@ char *OpenGLOutputBuilder::get_output_vertex_shader()
"out vec2 shadowMaskCoordinates;"
"out float alpha;"
"uniform vec2 textureSize;"
"uniform float timestampBase;"
"uniform vec4 timestampBase;"
"uniform float ticksPerFrame;"
"uniform vec2 positionConversion;"
"uniform vec2 scanNormal;"
"uniform vec3 filterCoefficients;"
"uniform usampler2D texID;"
"uniform sampler2D shadowMaskTexID;"
"const float shadowMaskMultiple = 600;"
"out vec2 srcCoordinatesVarying;"
"void main(void)"
"{"
"lateralVarying = lateral + 1.0707963267949;"
"lateralVarying = lateralAndTimestampBaseOffset.x + 1.0707963267949;"
"shadowMaskCoordinates = position * vec2(shadowMaskMultiple, shadowMaskMultiple * 0.85057471264368);"
"ivec2 textureSize = textureSize(texID, 0);"
"srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);"
"float age = (timestampBase - 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));"
"float age = (timestampBase[int(lateralAndTimestampBaseOffset.y)] - timestamp) / ticksPerFrame;"
"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 = 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;"
"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));
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");
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));
}
free(vertex_shader);
@ -510,7 +510,6 @@ void OpenGLOutputBuilder::prepare_rgb_output_shader()
GLint texIDUniform = rgb_shader_program->get_uniform_location("texID");
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 scanNormalUniform = rgb_shader_program->get_uniform_location("scanNormal");
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(shadowMaskTexIDUniform, 1);
glUniform2f(textureSizeUniform, InputBufferBuilderWidth, InputBufferBuilderHeight);
glUniform1f(ticksPerFrameUniform, (GLfloat)(_cycles_per_line * _height_of_display));
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 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");
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)textureCoordinatesAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfTexCoord);
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();
}
inline int get_current_field()
{
return _run_write_pointer;
}
inline uint8_t *allocate_write_area(size_t required_length)
{
_output_mutex->lock();