dfranx / SPIRV-VM

Virtual machine for executing SPIR-V
MIT License
294 stars 27 forks source link

Somethign wrong with this shader or SPIRV-VM (random segfault on some shaders) #2

Open danilw opened 3 years ago

danilw commented 3 years ago

(this shader code does work in GPU-GLSL and other CPU "GLSL emulators/environments") shader spv file in attachment

I tried a few of my own shaders - works, but then next few shaders just do not work in SPIRV-VM, I think it because of large arrays in the shaders or something wrong with array logic in SPIRV-VM...

Or maybe I make error in C code. C code of modified example.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <spvm/context.h>
#include <spvm/state.h>
#include <spvm/ext/GLSL450.h>

spvm_source load_source(const char* fname, size_t* src_size) {
  FILE* f = fopen(fname, "rb");
  if (f == 0) {
    printf("Failed to load file %s\n", fname);
    return 0;
  }

  fseek(f, 0, SEEK_END);
  long file_size = ftell(f);
  fseek(f, 0, SEEK_SET);

  size_t el_count = (file_size / sizeof(spvm_word));
  spvm_source ret = (spvm_source)malloc(el_count * sizeof(spvm_word));
  fread(ret, el_count, sizeof(spvm_word), f);
  fclose(f);

  *src_size = el_count;

  return ret;
}
int main()
{
  // context holds all opcode functions
  spvm_context_t ctx = spvm_context_initialize();

  // load source code
  size_t spv_length = 0;
  spvm_source spv = load_source("shader.spv", &spv_length);

  int ires[2] = { 10, 10 };
  float timeData = 0.0f;
  float iresf[2] = { ires[0], ires[1] };
  int index = 0;
  for(int y=0;y<ires[1];y++){
    for(int x=0;x<ires[0];x++){
      spvm_program_t prog = spvm_program_create(ctx, spv, spv_length);
      spvm_state_t state = spvm_state_create(prog);
      spvm_ext_opcode_func* glsl_ext_data = spvm_build_glsl450_ext();
      spvm_result_t glsl_std_450 = spvm_state_get_result(state, "GLSL.std.450");
      if (glsl_std_450)
        glsl_std_450->extension = glsl_ext_data;
      // get uBlock
      spvm_result_t uBlock = spvm_state_get_result(state, "uBlock");

      // set uBlock.time
      spvm_member_t uBlock_time = spvm_state_get_object_member(state, uBlock, "iTime");
      spvm_member_set_value_f(uBlock_time->members, uBlock_time->member_count, &timeData);

      // set uBlock.iResolution
      spvm_member_t uBlock_info = spvm_state_get_object_member(state, uBlock, "iResolution");
      spvm_member_set_value_f(uBlock_info->members, uBlock_info->member_count, iresf);

      // call main
      spvm_word fnMain = spvm_state_get_result_location(state, "main");
      spvm_state_prepare(state, fnMain);

      //spvm_state_set_frag_coord(state,x,y,0,0); //does not matter

      spvm_state_call_function(state); // crash on 3 loop

      spvm_result_t outColor = spvm_state_get_result(state, "outColor");
      for (int i = 0; i < outColor->member_count; i++)
        printf("%.2f ", outColor->members[i].value.f);
      printf("\n");
      printf("%d %d\n",x,y);

      spvm_state_delete(state);
      spvm_program_delete(prog);
      free(glsl_ext_data);
    }
  }

  // free memory
  //spvm_state_delete(state);
  //spvm_program_delete(prog);
  //free(glsl_ext_data);
  free(spv);

  spvm_context_deinitialize(ctx);

  return 0;
}

Launching this code with this shader result 100% crash on 3-rd loop iteration.

I tried to have only(recreate it) state and spvm_state_delete(state); inside loop - it still crash. (moving everything to loop does not fix it, it still crashes) Crash on line spvm_state_call_function, crash only when it called using loop. Crash same with spvm_state_step_into on line 0 on first call in 3-rd loop iteration.

Call only once does not have a crash.

Sorry if I missing something in the C code and its my error, I dont see error there.

shader.zip