static struct vrend_linked_shader_program *add_cs_shader_program(struct vrend_context *ctx,
                                                                 struct vrend_shader *cs)
{
   struct vrend_linked_shader_program *sprog = CALLOC_STRUCT(vrend_linked_shader_program);
   GLuint prog_id;
   GLint lret;
   prog_id = glCreateProgram();
   glAttachShader(prog_id, cs->id);
   glLinkProgram(prog_id);

   glGetProgramiv(prog_id, GL_LINK_STATUS, &lret);
   if (lret == GL_FALSE) {
      char infolog[65536];
      int len;
      glGetProgramInfoLog(prog_id, 65536, &len, infolog);
      vrend_printf("got error linking\n%s\n", infolog);
      /* dump shaders */
      vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
      vrend_shader_dump(cs);
      glDeleteProgram(prog_id);
      free(sprog);
      return NULL;
   }
   sprog->ss[PIPE_SHADER_COMPUTE] = cs;

   list_add(&sprog->sl[PIPE_SHADER_COMPUTE], &cs->programs);
   sprog->id = prog_id;
   list_addtail(&sprog->head, &ctx->sub->cs_programs);

   vrend_use_program(ctx->sub, prog_id);

   bind_sampler_locs(sprog, PIPE_SHADER_COMPUTE, 0);
   bind_ubo_locs(sprog, PIPE_SHADER_COMPUTE, 0);
   bind_ssbo_locs(sprog, PIPE_SHADER_COMPUTE);
   bind_const_locs(sprog, PIPE_SHADER_COMPUTE);
   bind_image_locs(sprog, PIPE_SHADER_COMPUTE);
   return sprog;
}
static struct vrend_linked_shader_program *add_cs_shader_program(struct vrend_context *ctx,
                                                                 struct vrend_shader *cs)
{
   struct vrend_linked_shader_program *sprog = CALLOC_STRUCT(vrend_linked_shader_program);
   GLuint prog_id;
   GLint lret;
   prog_id = glCreateProgram();
   glAttachShader(prog_id, cs->id);
   glLinkProgram(prog_id);

   glGetProgramiv(prog_id, GL_LINK_STATUS, &lret);
   if (lret == GL_FALSE) {
      char infolog[65536];
      int len;
      glGetProgramInfoLog(prog_id, 65536, &len, infolog);
      vrend_printf("got error linking\n%s\n", infolog);
       
      vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
      vrend_shader_dump(cs);
      glDeleteProgram(prog_id);
      free(sprog);
      return NULL;
   }
   sprog->ss[PIPE_SHADER_COMPUTE] = cs;

   list_add(&sprog->sl[PIPE_SHADER_COMPUTE], &cs->programs);
   sprog->id = prog_id;
   list_addtail(&sprog->head, &ctx->sub->cs_programs);

   vrend_use_program(ctx->sub, prog_id);

   bind_sampler_locs(sprog, PIPE_SHADER_COMPUTE, 0);
   bind_ubo_locs(sprog, PIPE_SHADER_COMPUTE, 0);
   bind_ssbo_locs(sprog, PIPE_SHADER_COMPUTE);
   bind_const_locs(sprog, PIPE_SHADER_COMPUTE);
   bind_image_locs(sprog, PIPE_SHADER_COMPUTE);
   return sprog;
}