mirror of
https://github.com/TomHarte/CLK.git
synced 2024-08-29 11:29:52 +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:
parent
4595741ab0
commit
c0cd1ed89e
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user