mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-17 17:25:18 +00:00
Merge pull request #10 from TomHarte/NewInstancing
Introduces use of array instancing for output runs.
This commit is contained in:
commit
fa34b9c67b
@ -96,10 +96,10 @@ Flywheel::SyncEvent CRT::get_next_horizontal_sync_event(bool hsync_is_requested,
|
|||||||
return _horizontal_flywheel->get_next_event_in_period(hsync_is_requested, cycles_to_run_for, cycles_advanced);
|
return _horizontal_flywheel->get_next_event_in_period(hsync_is_requested, cycles_to_run_for, cycles_advanced);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define output_position_x(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfPosition + 0])
|
#define output_x1() (*(uint16_t *)&next_run[OutputVertexOffsetOfHorizontal + 0])
|
||||||
#define output_position_y(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfPosition + 2])
|
#define output_x2() (*(uint16_t *)&next_run[OutputVertexOffsetOfHorizontal + 2])
|
||||||
#define output_tex_x(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 0])
|
#define output_position_y() (*(uint16_t *)&next_run[OutputVertexOffsetOfVertical + 0])
|
||||||
#define output_tex_y(v) (*(uint16_t *)&next_run[OutputVertexSize*v + OutputVertexOffsetOfTexCoord + 2])
|
#define output_tex_y() (*(uint16_t *)&next_run[OutputVertexOffsetOfVertical + 2])
|
||||||
|
|
||||||
#define source_input_position_x(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfInputPosition + 0])
|
#define source_input_position_x(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfInputPosition + 0])
|
||||||
#define source_input_position_y(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfInputPosition + 2])
|
#define source_input_position_y(v) (*(uint16_t *)&next_run[SourceVertexSize*v + SourceVertexOffsetOfInputPosition + 2])
|
||||||
@ -188,18 +188,24 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
|||||||
{
|
{
|
||||||
if(
|
if(
|
||||||
_is_writing_composite_run == _did_start_run &&
|
_is_writing_composite_run == _did_start_run &&
|
||||||
_openGL_output_builder->composite_output_run_has_room_for_vertices(_did_start_run ? 3 : 6) &&
|
_openGL_output_builder->composite_output_run_has_room_for_vertex() &&
|
||||||
!_openGL_output_builder->composite_output_buffer_is_full())
|
!_openGL_output_builder->composite_output_buffer_is_full())
|
||||||
{
|
{
|
||||||
uint8_t *next_run = _openGL_output_builder->get_next_output_run();
|
uint8_t *next_run = _openGL_output_builder->get_next_output_run();
|
||||||
if(next_run)
|
if(next_run)
|
||||||
{
|
{
|
||||||
output_position_x(0) = output_position_x(1) = output_position_x(2) = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
if(_did_start_run)
|
||||||
output_position_y(0) = output_position_y(1) = output_position_y(2) = (uint16_t)(_vertical_flywheel->get_current_output_position() / _vertical_flywheel_output_divider);
|
{
|
||||||
output_tex_x(0) = output_tex_x(1) = output_tex_x(2) = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
output_x1() = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
||||||
output_tex_y(0) = output_tex_y(1) = output_tex_y(2) = _openGL_output_builder->get_composite_output_y();
|
output_position_y() = (uint16_t)(_vertical_flywheel->get_current_output_position() / _vertical_flywheel_output_divider);
|
||||||
|
output_tex_y() = _openGL_output_builder->get_composite_output_y();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output_x2() = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
||||||
|
_openGL_output_builder->complete_output_run();
|
||||||
|
}
|
||||||
|
|
||||||
_openGL_output_builder->complete_output_run(3);
|
|
||||||
_did_start_run ^= true;
|
_did_start_run ^= true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,11 +233,10 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef output_position_x
|
#undef output_x1
|
||||||
|
#undef output_x2
|
||||||
#undef output_position_y
|
#undef output_position_y
|
||||||
#undef output_tex_x
|
|
||||||
#undef output_tex_y
|
#undef output_tex_y
|
||||||
#undef output_lateral
|
|
||||||
|
|
||||||
#undef input_input_position_x
|
#undef input_input_position_x
|
||||||
#undef input_input_position_y
|
#undef input_input_position_y
|
||||||
|
@ -17,8 +17,8 @@ namespace CRT {
|
|||||||
|
|
||||||
// Output vertices are those used to copy from an input buffer — whether it describes data that maps directly to RGB
|
// Output vertices are those used to copy from an input buffer — whether it describes data that maps directly to RGB
|
||||||
// or is one of the intermediate buffers that we've used to convert from composite towards RGB.
|
// or is one of the intermediate buffers that we've used to convert from composite towards RGB.
|
||||||
const GLsizei OutputVertexOffsetOfPosition = 0;
|
const GLsizei OutputVertexOffsetOfHorizontal = 0;
|
||||||
const GLsizei OutputVertexOffsetOfTexCoord = 4;
|
const GLsizei OutputVertexOffsetOfVertical = 4;
|
||||||
|
|
||||||
const GLsizei OutputVertexSize = 8;
|
const GLsizei OutputVertexSize = 8;
|
||||||
|
|
||||||
|
@ -324,7 +324,8 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
output_shader_program->bind();
|
output_shader_program->bind();
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, submitted_output_data / OutputVertexSize);
|
// glDrawArrays(GL_TRIANGLE_STRIP, 0, submitted_output_data / OutputVertexSize);
|
||||||
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, submitted_output_data / OutputVertexSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy framebuffer to the intended place
|
// copy framebuffer to the intended place
|
||||||
@ -423,18 +424,23 @@ void OpenGLOutputBuilder::prepare_output_vertex_array()
|
|||||||
{
|
{
|
||||||
if(output_shader_program)
|
if(output_shader_program)
|
||||||
{
|
{
|
||||||
GLint positionAttribute = output_shader_program->get_attrib_location("position");
|
|
||||||
GLint textureCoordinatesAttribute = output_shader_program->get_attrib_location("srcCoordinates");
|
|
||||||
|
|
||||||
glBindVertexArray(output_vertex_array);
|
glBindVertexArray(output_vertex_array);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
||||||
glEnableVertexAttribArray((GLuint)positionAttribute);
|
|
||||||
glEnableVertexAttribArray((GLuint)textureCoordinatesAttribute);
|
|
||||||
|
|
||||||
const GLsizei vertexStride = OutputVertexSize;
|
const GLsizei vertexStride = OutputVertexSize;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
size_t offset = 0;
|
||||||
glVertexAttribPointer((GLuint)positionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfPosition);
|
|
||||||
glVertexAttribPointer((GLuint)textureCoordinatesAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)OutputVertexOffsetOfTexCoord);
|
const char *attributes[] = {"horizontal", "vertical", nullptr};
|
||||||
|
const char **attribute = attributes;
|
||||||
|
while(*attribute)
|
||||||
|
{
|
||||||
|
GLint attributeLocation = output_shader_program->get_attrib_location(*attribute);
|
||||||
|
glEnableVertexAttribArray((GLuint)attributeLocation);
|
||||||
|
glVertexAttribPointer((GLuint)attributeLocation, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)offset);
|
||||||
|
glVertexAttribDivisor((GLuint)attributeLocation, 1);
|
||||||
|
offset += 4;
|
||||||
|
attribute++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,9 +115,9 @@ class OpenGLOutputBuilder {
|
|||||||
_source_buffer_data_pointer += 2 * SourceVertexSize;
|
_source_buffer_data_pointer += 2 * SourceVertexSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool composite_output_run_has_room_for_vertices(GLsizei vertices_to_write)
|
inline bool composite_output_run_has_room_for_vertex()
|
||||||
{
|
{
|
||||||
return _output_buffer_data_pointer <= OutputVertexBufferDataSize - vertices_to_write * OutputVertexSize;
|
return _output_buffer_data_pointer < OutputVertexBufferDataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t *get_next_output_run()
|
inline uint8_t *get_next_output_run()
|
||||||
@ -126,9 +126,9 @@ class OpenGLOutputBuilder {
|
|||||||
return &_output_buffer_data.get()[_output_buffer_data_pointer % OutputVertexBufferDataSize];
|
return &_output_buffer_data.get()[_output_buffer_data_pointer % OutputVertexBufferDataSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void complete_output_run(GLsizei vertices_written)
|
inline void complete_output_run()
|
||||||
{
|
{
|
||||||
_output_buffer_data_pointer += vertices_written * OutputVertexSize;
|
_output_buffer_data_pointer += OutputVertexSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void lock_output()
|
inline void lock_output()
|
||||||
|
@ -30,8 +30,8 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
|
|||||||
asprintf(&vertex_shader,
|
asprintf(&vertex_shader,
|
||||||
"#version 150\n"
|
"#version 150\n"
|
||||||
|
|
||||||
"in vec2 position;"
|
"in vec2 horizontal;"
|
||||||
"in vec2 srcCoordinates;"
|
"in vec2 vertical;"
|
||||||
|
|
||||||
"uniform vec2 boundsOrigin;"
|
"uniform vec2 boundsOrigin;"
|
||||||
"uniform vec2 boundsSize;"
|
"uniform vec2 boundsSize;"
|
||||||
@ -45,15 +45,19 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
|
|||||||
|
|
||||||
"void main(void)"
|
"void main(void)"
|
||||||
"{"
|
"{"
|
||||||
"float laterals[] = float[](0, 0, 1, 0, 1, 1);"
|
"float lateral = float(gl_VertexID & 1);"
|
||||||
"float lateral = laterals[gl_VertexID %% 6];"
|
"float longitudinal = float((gl_VertexID & 2) >> 1);"
|
||||||
|
"float x = mix(horizontal.x, horizontal.y, longitudinal);"
|
||||||
|
|
||||||
"lateralVarying = lateral - 0.5;"
|
"lateralVarying = lateral - 0.5;"
|
||||||
|
|
||||||
|
"vec2 vSrcCoordinates = vec2(x, vertical.y);"
|
||||||
"ivec2 textureSize = textureSize(texID, 0);"
|
"ivec2 textureSize = textureSize(texID, 0);"
|
||||||
"iSrcCoordinatesVarying = srcCoordinates;"
|
"iSrcCoordinatesVarying = vSrcCoordinates;"
|
||||||
"srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);"
|
"srcCoordinatesVarying = vec2(vSrcCoordinates.x / textureSize.x, (vSrcCoordinates.y + 0.5) / textureSize.y);"
|
||||||
|
|
||||||
"vec2 floatingPosition = (position / positionConversion) + lateral * scanNormal;"
|
"vec2 vPosition = vec2(x, vertical.x);"
|
||||||
|
"vec2 floatingPosition = (vPosition / positionConversion) + lateral * 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);"
|
||||||
"}", sampler_type);
|
"}", sampler_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user