Browse Source

Implement partial uploads to texture

sdf
A.Olokhtonov 1 month ago
parent
commit
dc235c7365
  1. 2
      client/client_send.js
  2. 36
      client/webgl_draw.js

2
client/client_send.js

@ -8,7 +8,7 @@ function serializer_create(size) { @@ -8,7 +8,7 @@ function serializer_create(size) {
'strview': new Uint8Array(buffer),
'need_gpu_allocate': true, // need to call glBufferData to create a GPU buffer of size serializer.size
'gpu_upload_from': 0, // need to call glBufferSubData for bytes in [serializer.gpu_upload_from, serializer.offset)
'gpu_upload_from': 0, // need to call glBufferSubData/glTexSubImage2D for bytes in [serializer.gpu_upload_from, serializer.offset)
};
}

36
client/webgl_draw.js

@ -25,26 +25,46 @@ function upload_if_needed(gl, buffer_kind, serializer) { @@ -25,26 +25,46 @@ function upload_if_needed(gl, buffer_kind, serializer) {
}
function upload_square_rgba16ui_texture(gl, serializer, texture_size) {
// TODO: only subupload what's needed
const bpp = 2 * 4;
const data_size = serializer.offset;
const data_pixels = data_size / bpp; // data_size % bpp is expected to always be zero here
const data_size = serializer.offset - serializer.gpu_upload_from;
let data_pixels = data_size / bpp; // data_size % bpp is expected to always be zero here
const pixels_already_uploaded = serializer.gpu_upload_from / bpp;
let rows_uploaded = Math.floor(pixels_already_uploaded / texture_size);
const rows_remainder = pixels_already_uploaded % texture_size;
// Upload first non-whole row (if last upload was not a whole number of rows)
if (rows_remainder > 0) {
const row_upload_to_full = texture_size - rows_remainder;
const first_upload = Math.min(row_upload_to_full, data_pixels);
if (first_upload > 0) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, rows_remainder, rows_uploaded, first_upload, 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, serializer.gpu_upload_from, first_upload * 4));
data_pixels -= first_upload;
serializer.gpu_upload_from += first_upload;
rows_uploaded += 1;
}
}
const rows = Math.ceil(data_pixels / texture_size);
const last_row = data_pixels % texture_size;
const whole_upload = (rows - 1) * texture_size * bpp;
const whole_upload = (rows - 1) * texture_size;
// Upload whole rows
if (rows > 1) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, texture_size, rows - 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, 0, whole_upload / 2));
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, rows_uploaded, texture_size, rows - 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, serializer.gpu_upload_from, whole_upload * 4));
rows_uploaded += rows - 1;
}
// Upload last row
if (last_row > 0) {
if (last_row > 0) {
const last_row_upload = last_row * bpp;
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, rows - 1, last_row, 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, whole_upload, last_row_upload / 2));
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, rows_uploaded, last_row, 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, whole_upload, last_row_upload * 4));
}
serializer.gpu_upload_from = serializer.offset;
}
function draw_html(state) {

Loading…
Cancel
Save