这是indexloc提供的服务,不要输入任何密码
Skip to content

SIGBUS: Illegal storage access. (Attempt to read from nil?) when usingmakeImage #32

@Nazariglez

Description

@Nazariglez

I have an issue trying to render images. I am not sure what's going on because it happen using images with more than 2809 pixels... a size of 53x53 works, but no higher.

One way to test this is loading an image as:

proc getImage(): Image =
  var data = newSeq[uint8](0)
  var width, height, channels: int

  const f = staticRead("./assets/img.png")
  data = stbi.loadFromMemory(cast[seq[uint8]](f), width, height, channels, stbi.RGBA)

  let desc = sg.ImageDesc(
    width: cast[int32](width),
    height: cast[int32](height),
    data: ImageData(
      subimage: [ [ sg.Range(addr: addr data, size: width * height * 4) ] ]
    ),
  )
  sg.makeImage(desc)

Another is altering the texcube example to increase the size of the generated texture:

#-------------------------------------------------------------------------------
#   texcube.nim
#   Texture creation, rendering with texture, packed vertex components.
#-------------------------------------------------------------------------------
import sokol/log as slog
import sokol/gfx as sg
import sokol/app as sapp
import sokol/glue as sglue
import math/vec3
import math/mat4
import shaders/texcube as shd

proc generateCheckerboard(width: int, height: int): seq[uint32] =
  var pixels: seq[uint32] = @[]
  for y in 0..<height:
    for x in 0..<width:
      if (x div 8 + y div 8) mod 2 == 0:
        pixels.add(0xFFFFFFFF'u32)  # white
      else:
        pixels.add(0xFF000000'u32)  # black
  return pixels

var
  rx, ry: float32
  pip: Pipeline
  bindings: Bindings

const
  passAction = PassAction(
    colors: [
      ColorAttachmentAction( loadAction: loadActionClear, clearValue: (0.25, 0.5, 0.75, 1.0))
    ]
  )

type Vertex = object
  x, y, z: float32
  color: uint32
  u, v: uint16

proc init() {.cdecl.} =
  sg.setup(sg.Desc(
    environment: sglue.environment(),
    logger: sg.Logger(fn: slog.fn),
  ))

  #[
    Cube vertex buffer with packed vertex formats for color and texture coords.
    Note that a vertex format which must be portable across all
    backends must only use the normalized integer formats
    (BYTE4N, UBYTE4N, SHORT2N, SHORT4N), which can be converted
    to floating point formats in the vertex shader inputs.
  ]#
  const vertices = [
    Vertex( x: -1.0, y: -1.0, z: -1.0,  color: 0xFF0000FF'u32, u:     0, v:     0 ),
    Vertex( x:  1.0, y: -1.0, z: -1.0,  color: 0xFF0000FF'u32, u: 32767, v:     0 ),
    Vertex( x:  1.0, y:  1.0, z: -1.0,  color: 0xFF0000FF'u32, u: 32767, v: 32767 ),
    Vertex( x: -1.0, y:  1.0, z: -1.0,  color: 0xFF0000FF'u32, u:     0, v: 32767 ),
    Vertex( x: -1.0, y: -1.0, z:  1.0,  color: 0xFF00FF00'u32, u:     0, v:     0 ),
    Vertex( x:  1.0, y: -1.0, z:  1.0,  color: 0xFF00FF00'u32, u: 32767, v:     0 ),
    Vertex( x:  1.0, y:  1.0, z:  1.0,  color: 0xFF00FF00'u32, u: 32767, v: 32767 ),
    Vertex( x: -1.0, y:  1.0, z:  1.0,  color: 0xFF00FF00'u32, u:     0, v: 32767 ),
    Vertex( x: -1.0, y: -1.0, z: -1.0,  color: 0xFFFF0000'u32, u:     0, v:     0 ),
    Vertex( x: -1.0, y:  1.0, z: -1.0,  color: 0xFFFF0000'u32, u: 32767, v:     0 ),
    Vertex( x: -1.0, y:  1.0, z:  1.0,  color: 0xFFFF0000'u32, u: 32767, v: 32767 ),
    Vertex( x: -1.0, y: -1.0, z:  1.0,  color: 0xFFFF0000'u32, u:     0, v: 32767 ),
    Vertex( x:  1.0, y: -1.0, z: -1.0,  color: 0xFFFF007F'u32, u:     0, v:     0 ),
    Vertex( x:  1.0, y:  1.0, z: -1.0,  color: 0xFFFF007F'u32, u: 32767, v:     0 ),
    Vertex( x:  1.0, y:  1.0, z:  1.0,  color: 0xFFFF007F'u32, u: 32767, v: 32767 ),
    Vertex( x:  1.0, y: -1.0, z:  1.0,  color: 0xFFFF007F'u32, u:     0, v: 32767 ),
    Vertex( x: -1.0, y: -1.0, z: -1.0,  color: 0xFFFF7F00'u32, u:     0, v:     0 ),
    Vertex( x: -1.0, y: -1.0, z:  1.0,  color: 0xFFFF7F00'u32, u: 32767, v:     0 ),
    Vertex( x:  1.0, y: -1.0, z:  1.0,  color: 0xFFFF7F00'u32, u: 32767, v: 32767 ),
    Vertex( x:  1.0, y: -1.0, z: -1.0,  color: 0xFFFF7F00'u32, u:     0, v: 32767 ),
    Vertex( x: -1.0, y:  1.0, z: -1.0,  color: 0xFF007FFF'u32, u:     0, v:     0 ),
    Vertex( x: -1.0, y:  1.0, z:  1.0,  color: 0xFF007FFF'u32, u: 32767, v:     0 ),
    Vertex( x:  1.0, y:  1.0, z:  1.0,  color: 0xFF007FFF'u32, u: 32767, v: 32767 ),
    Vertex( x:  1.0, y:  1.0, z: -1.0,  color: 0xFF007FFF'u32, u:     0, v: 32767 ),
  ]
  bindings.vertexBuffers[0] = sg.makeBuffer(BufferDesc(
    data: sg.Range(addr: vertices.addr, size: vertices.sizeof)
  ))

  # create an index buffer for the cube
  const indices = [
    0'u16, 1, 2,  0, 2, 3,
    6, 5, 4,  7, 6, 4,
    8, 9, 10,  8, 10, 11,
    14, 13, 12,  15, 14, 12,
    16, 17, 18,  16, 18, 19,
    22, 21, 20,  23, 22, 20
  ]
  bindings.indexBuffer = sg.makeBuffer(BufferDesc(
    type: bufferTypeIndexBuffer,
    data: sg.Range(addr: indices.addr, size: indices.sizeof)
  ))

  let h:int32 = 54
  let w:int32 = 53

  # create a checker board texture
  let pixels = generateCheckerboard(w, h)
  bindings.fs.images[shd.slotTex] = sg.makeImage(sg.ImageDesc(
    width: w,
    height: h,
    data: ImageData(
      subimage: [ [ sg.Range(addr: pixels.addr, size: w*h*4) ] ]
    )
  ))

  # create a matching sampler
  bindings.fs.samplers[shd.slotSmp] = sg.makeSampler(sg.SamplerDesc(
    minFilter: filterNearest,
    magFilter: filterNearest,
  ));

  # shader and pipeline object
  pip = sg.makePipeline(PipelineDesc(
    shader: sg.makeShader(texcubeShaderDesc(sg.queryBackend())),
    layout: VertexLayoutState(
      attrs: [
        VertexAttrState(format: vertexFormatFloat3),    # pos
        VertexAttrState(format: vertexFormatUbyte4n),   # color0
        VertexAttrState(format: vertexFormatShort2n)    # texcoord0
      ]
    ),
    indexType: indexTypeUint16,
    cullMode: cullModeBack,
    depth: DepthState(
      compare: compareFuncLessEqual,
      writeEnabled: true
    )
  ))

proc computeVsParams(): shd.VsParams =
  let proj = persp(60.0f, sapp.widthf()/sapp.heightf(), 0.01f, 10.0f)
  let view = lookat(vec3(0.0f, 1.5f, 6.0f), vec3.zero(), vec3.up())
  let rxm = rotate(rx, vec3(1f, 0f, 0f))
  let rym = rotate(ry, vec3(0f, 1f, 0f))
  let model = rxm * rym
  result = VsParams(mvp: proj * view * model)

proc frame() {.cdecl.} =
  let dt = sapp.frameDuration() * 60f
  rx += 1f * dt
  ry += 2f * dt
  let vsParams = computeVsParams()
  sg.beginPass(Pass(action: passAction, swapchain: sglue.swapchain()))
  sg.applyPipeline(pip)
  sg.applyBindings(bindings)
  sg.applyUniforms(shaderStageVs, shd.slotVsParams, sg.Range(addr: vsParams.addr, size: vsParams.sizeof))
  sg.draw(0, 36, 1)
  sg.endPass()
  sg.commit()

proc cleanup() {.cdecl.} =
  sg.shutdown()

sapp.run(sapp.Desc(
  initCb: init,
  frameCb: frame,
  cleanupCb: cleanup,
  windowTitle: "texcube.nim",
  width: 800,
  height: 600,
  sampleCount: 4,
  icon: IconDesc(sokol_default: true),
  logger: sapp.Logger(fn: slog.fn),
))

this will panic at runtime with:

➜  sokol-nim git:(master) ✗ nimble texcube
  Verifying dependencies for sokol@0.5.1
  Executing task texcube in /Users/nazariglez/personal/sokol-nim/sokol.nimble
Hint: used config file '/opt/homebrew/Cellar/nim/2.0.6/nim/config/nim.cfg' [Conf]
Hint: used config file '/opt/homebrew/Cellar/nim/2.0.6/nim/config/config.nims' [Conf]
..................................................................................
CC: ../../../../../opt/homebrew/Cellar/nim/2.0.6/nim/lib/system.nim
CC: ../../../.nimble/pkgs2/sokol-0.5.5-afa97955f1370ea45bf6b8e512b309004fc9eb6a/sokol/gfx.nim
CC: texcube.nim
Hint:  [Link]
ld: warning: ignoring duplicate libraries: '-lm'
Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
35722 lines; 0.254s; 46.449MiB peakmem; proj: examples/texcube; out: /Users/nazariglez/personal/sokol-nim/build/texcube [SuccessX]
Traceback (most recent call last)
/Users/nazariglez/personal/sokol-nim/examples/texcube.nim(158) texcube
/Users/nazariglez/.nimble/pkgs2/sokol-0.5.5-afa97955f1370ea45bf6b8e512b309004fc9eb6a/sokol/app.nim(560) run
/Users/nazariglez/personal/sokol-nim/examples/texcube.nim(102) init
/Users/nazariglez/.nimble/pkgs2/sokol-0.5.5-afa97955f1370ea45bf6b8e512b309004fc9eb6a/sokol/gfx.nim(1381) makeImage
SIGBUS: Illegal storage access. (Attempt to read from nil?)
stack trace: (most recent call last)
/private/var/folders/zw/1nf4s1_92b1fkgcbgqr604t80000gn/T/nimblecache-1799278598/nimscriptapi_1188391125.nim(211, 16)
/Users/nazariglez/personal/sokol-nim/sokol.nimble(91, 3) texcubeTask
/Users/nazariglez/personal/sokol-nim/sokol.nimble(69, 3) run
/opt/homebrew/Cellar/nim/2.0.6/nim/lib/system/nimscript.nim(265, 7) exec
/opt/homebrew/Cellar/nim/2.0.6/nim/lib/system/nimscript.nim(265, 7) Error: unhandled exception: FAILED: build/texcube [OSError]
       Tip: 1 messages have been suppressed, use --verbose to show them.
nimscriptwrapper.nim(161) execScript

    Error:  Exception raised during nimble script execution

I think that I am missing something, or there is a bug somewhere in nim or the sokol bindings. Does this rings any bell?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions