bkaradzic / bgfx

Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.
https://bkaradzic.github.io/bgfx/overview.html
BSD 2-Clause "Simplified" License
15.13k stars 1.95k forks source link

Uniforms are not found and not set with OpenGL renderer in the compute program #2636

Open borisbat opened 3 years ago

borisbat commented 3 years ago

Uniforms are not found and not set with OpenGL renderer in the compute program. Works fine with DX11 and DX12. I'm using C99 bindings.

Not sure how easy it would be to provide simple C repro, since this is using bindings for another programming language. I'm willing to participate in remote debugging session of any kind.

Log:

C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (3545): BGFX Init complete.
render_type BGFX_RENDERER_TYPE_OPENGL
cs.id = 0x9
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx_p.h (4753): BGFX Creating uniform (handle   3) f_tex
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx_p.h (4753): BGFX Creating uniform (handle   4) c_offset
new uniform c_offset = 0x4
new uniform f_tex = 0x3
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (537): BGFX VertexLayout 89639db9 (144bfef2), stride 28
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (557): BGFX      attr  0: Attrib::Position     num 2, type 4, norm [ ], asint [ ], offset  0
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (557): BGFX      attr  4: Attrib::Color0       num 3, type 4, norm [ ], asint [ ], offset  8
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (557): BGFX      attr 10: Attrib::TexCoord0    num 2, type 4, norm [ ], asint [ ], offset 20
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5981): BGFX Compute Shader consts 0
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (4764): BGFX Program create: GL22: GL21, GL0
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (4874): BGFX Program 22
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (4875): BGFX Attributes (1):
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (4904): BGFX      GL_UNSIGNED_INT_VEC3 gl_GlobalInvocationID is at location -1
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (4910): BGFX Uniforms (2):
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5010): BGFX Sampler #0 at location 0.
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5038): BGFX WARN User defined uniform 'c_destTex' is not found, it won't be set.
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5061): BGFX      uniform GL_IMAGE_2D c_destTex is at location 0, size 1, offset 0
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5038): BGFX WARN User defined uniform 'c_offset' is not found, it won't be set.
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5061): BGFX      uniform GL_FLOAT_VEC4 c_offset is at location 1, size 1, offset 0
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_gl.cpp (5079): BGFX Buffers (0):

Direct3D11 log for comparison

render_type BGFX_RENDERER_TYPE_DIRECT3D11
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx_p.h (4753): BGFX Creating uniform (handle   3) c_offset
cs.id = 0x9
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx_p.h (4753): BGFX Creating uniform (handle   4) f_tex
new uniform c_offset = 0x3
new uniform f_tex = 0x4
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (537): BGFX VertexLayout 89639db9 (144bfef2), stride 28
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (557): BGFX      attr  0: Attrib::Position     num 2, type 4, norm [ ], asint [ ], offset  0
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (557): BGFX      attr  4: Attrib::Color0       num 3, type 4, norm [ ], asint [ ], offset  8
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\bgfx.cpp (557): BGFX      attr 10: Attrib::TexCoord0    num 2, type 4, norm [ ], asint [ ], offset 20
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_d3d11.cpp (4109): BGFX Compute Shader consts 1
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_d3d11.cpp (4187): BGFX   user: c_offset (vec4), num  0, r.index   0, r.count  1
C:\Users\Boris\Work\yzg\modules\dasBGFX\bgfx\bgfx\src\renderer_d3d11.cpp (4282): BGFX   CB size: 16

Shader itself:


#include <bgfx_compute.sh>

ivec2 range ( int r ) { return ivec2(0,r); }
ivec2 range ( int f, int t ) { return ivec2(f,t); }
float SATURATE ( float a ) { return clamp(a,0.,1.); }
vec2 SATURATE ( vec2 a ) { return clamp(a,vec2(0.,0.),vec2(1.,1.)); }
vec3 SATURATE ( vec3 a ) { return clamp(a,vec3(0.,0.,0.),vec3(1.,1.,1.)); }
vec4 SATURATE ( vec4 a ) { return clamp(a,vec4(0.,0.,0.,0.),vec4(1.,1.,1.,1.)); }
void sincos ( float a, out float sv, out float cv ) { sv=sin(a); cv=cos(a); }
float length_sq ( vec2 t ) { return dot(t,t); }
float length_sq ( vec3 t ) { return dot(t,t); }
float length_sq ( vec4 t ) { return dot(t,t); }
float mad ( float a, float b, float c ) { return a*b+c; }
vec2 mad ( vec2 a, float b, vec2 c ) { return a*vec2(b,b)+c; }
vec3 mad ( vec3 a, float b, vec3 c ) { return a*vec3(b,b,b)+c; }
vec4 mad ( vec4 a, float b, vec4 c ) { return a*vec4(b,b,b,b)+c; }
vec2 mad ( vec2 a, vec2 b, vec2 c ) { return a*b+c; }
vec3 mad ( vec3 a, vec3 b, vec3 c ) { return a*b+c; }
vec4 mad ( vec4 a, vec4 b, vec4 c ) { return a*b+c; }
float distance_sq ( vec3 a, vec3 b ) { return length_sq(a-b); }
float inv_distance_sq ( vec3 a, vec3 b ) { return 1. / distance_sq(a,b); }
vec2 VEC2(float c) { return vec2(c,c); }
vec2 VEC2(float x, float y) { return vec2(x,y); }
vec3 VEC3(float c) { return vec3(c,c,c); }
vec3 VEC3(float x, float y, float z) { return vec3(x,y,z); }
vec3 VEC3(vec2 xy, float z) { return vec3(xy.x,xy.y,z); }
vec3 VEC3(float x, vec2 yz) { return vec3(x,yz.x,yz.y); }
vec4 VEC4(float c) { return vec4(c,c,c,c); }
vec4 VEC4(vec2 xy, float z, float w) { return vec4(xy.x,xy.y,z,w); }
vec4 VEC4(vec2 xy, vec2 zw) { return vec4(xy.x,xy.y,zw.x,zw.y); }
vec4 VEC4(float x, float y, vec2 zw) { return vec4(x,y,zw.x,zw.y); }
vec4 VEC4(float x, vec2 yz, float w) { return vec4(x,yz.x,yz.y,w); }
vec4 VEC4(vec3 xyz, float w) { return vec4(xyz.x,xyz.y,xyz.z,w); }
vec4 VEC4(float x, vec3 yzw) { return vec4(x,yzw.x,yzw.y,yzw.z); }
vec4 VEC4(float x, float y, float z, float w) { return vec4(x,y,z,w); }
mat3 MAT3(vec3 a, vec3 b, vec3 c) { mat3 res; res[0]=a; res[1]=b; res[2]=c; return res; }
mat3 MAT3(mat4 m) { mat3 res; res[0]=m[0].xyz; res[1]=m[1].xyz; res[2]=m[2].xyz; return res; }
IMAGE2D_WR(c_destTex,rgba8,0);

uniform vec4 c_offset;

NUM_THREADS(16,16,1)
void main()
{
    ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);
    ivec2 bitPos = (storePos + ivec2((int(c_offset.x) * 3),(int(c_offset.x) * 3)));
    int bit = (((bitPos.x >> 4) & (bitPos.y >> 4)) & 1);
    if ((bit != 0))
    {
        imageStore(c_destTex,storePos,(VEC4(storePos.x,storePos.y,0,255) / 255.000000000));
    }
    else
    {
        imageStore(c_destTex,storePos,vec4(1,0.5,0.25,1));
    }
;
}

Program body (just in case)

require glfw/glfw_boost
require dasbgfx/bgfx_boost
require daslib/defer
require daslib/math_boost
require daslib/safe_addr

var [[in, semantics=POSITION]]     a_position  : float2
var [[in, semantics=COLOR0]]       a_color0    : float3
var [[in, semantics=TEXCOORD0]]    a_texcoord0 : float2
var [[inout, semantics=COLOR0]]    v_color0    : float3
var [[inout, semantics=TEXCOORD0]] v_texcoord0 : float2
var [[uniform, stage=0]] f_tex : sampler2D
var [[uniform, format=rgba8, binding=0, writeonly]] c_destTex : image2D
var [[uniform]] c_offset : float4

[bgfx_vertex_program(name="VERTEX_SRC")]
def vs_main
    v_color0 = a_color0
    v_texcoord0 = a_texcoord0
    gl_Position = u_modelViewProj * float4(a_position, 0.0, 1.0)

[bgfx_fragment_program(name="FRAGMENT_SRC")]
def fs_main
    gl_FragColor = texture2D(f_tex,v_texcoord0) * float4(v_color0, 1.0)

[bgfx_compute_program(name="COMPUTE_SRC",local_size_x=16,local_size_y=16)]
def compute_effect
    let storePos = int2(gl_GlobalInvocationID.xy)
    let bitPos = storePos + int2(int(c_offset.x)*3,int(c_offset.x)*3)
    let bit = (bitPos.x>>4) & (bitPos.y>>4) & 1
    if bit != 0
        imageStore(c_destTex,storePos, float4(storePos.x,storePos.y,0,255)/255.)
    else
        imageStore(c_destTex,storePos, float4(1.,.5,.25,1.))

[bgfx_vertex_buffer]
struct Vertex
    [[type=FLOAT, size=2, semantics=POSITION]]   xy : float2
    [[type=FLOAT, size=3, semantics=COLOR0]]    rgb : float3
    [[type=FLOAT, size=2, semantics=TEXCOORD0]]  uv : float2

let vertices = [[Vertex
        xy=float2(-1.0, 1.0), rgb=float3(0.0,0.0,0.0), uv=float2(0.0,0.0);
        xy=float2( 1.0, 1.0), rgb=float3(1.0,1.0,0.0), uv=float2(1.0,0.0);
        xy=float2( 1.0,-1.0), rgb=float3(1.0,0.0,0.0), uv=float2(1.0,1.0);
        xy=float2(-1.0,-1.0), rgb=float3(1.0,1.0,0.0), uv=float2(0.0,1.0)
]]

let indices = [[int 0; 2; 1; 2; 0; 3]]

[export]
def main
    let WNDW_WIDTH = 1280
    let WNDW_HEIGHT = 720
    if glfwInit()==0
        panic("can't init glfw")
    defer <|
        glfwTerminate()
    var window = glfwCreateWindow(WNDW_WIDTH, WNDW_HEIGHT, "Hello image", null, null)
    if window==null
        panic("can't create window")
    defer <|
        glfwDestroyWindow(window)
    var pd: bgfx_platform_data_s
    pd.nwh = glfwGetWin32Window(window)
    bgfx_set_platform_data(safe_addr(pd))
    var init : bgfx_init_s
    bgfx_init_ctor(safe_addr(init))
    // init._type = bgfx_renderer_type BGFX_RENDERER_TYPE_OPENGL
    init._type = bgfx_renderer_type BGFX_RENDERER_TYPE_COUNT
    init.resolution.width = uint(WNDW_WIDTH)
    init.resolution.height = uint(WNDW_HEIGHT)
    init.resolution.reset = BGFX_RESET_VSYNC
    bgfx_init_debug(init)
    bgfx_init(safe_addr(init))
    let render_type = bgfx_get_renderer_type()
    print("render_type {render_type}\n")
    var pcvl_decl = bgfx_create_vertex_layout(type<Vertex>,render_type)
    var pcvl_handle = bgfx_create_vertex_layout(safe_addr(pcvl_decl))
    var vbh = bgfx_create_vertex_buffer(bgfx_make_ref(vertices), safe_addr(pcvl_decl), BGFX_BUFFER_NONE)
    var ibh = bgfx_create_index_buffer(bgfx_make_ref(indices), BGFX_BUFFER_INDEX32)
    var compute_program = bgfx_create_compute_shader_program(COMPUTE_SRC, render_type)
    var program = bgfx_create_shader_program(VERTEX_SRC, VERTEX_SRC_DECL, FRAGMENT_SRC, FRAGMENT_SRC_DECL, render_type)
    var texture = bgfx_create_texture_2d(256u, 256u, false, 1u,
        bgfx_texture_format BGFX_TEXTURE_FORMAT_RGBA8, BGFX_TEXTURE_COMPUTE_WRITE, null)
    if texture.idx==uint16(0xffff)
        panic("can't create texture")
    let v_ortho = bgfx_mat_ortho(-1.,1.,-1.,1.,0.,100.,0.,bgfx_get_caps().homogeneousDepth,false)
    bgfx_set_view_clear(0u, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, RGBA_TO_BGFX_UCOLOR(0.2,0.2,0.2,1.0), 1.0f, 0u)
    var ioffset = 0
    while glfwWindowShouldClose(window)==0
        glfwPollEvents()
        var display_w, display_h : int
        glfwGetFramebufferSize(window, display_w, display_h)

        c_offset.x = float(ioffset++)
        c_destTex.texture2D = uint(texture.idx)
        compute_effect_bind_uniform()
        bgfx_dispatch(0u, compute_program, 256u/16u, 256u/16u, 1u, 0u)

        bgfx_set_view_transform(0u, null, safe_addr(v_ortho))
        bgfx_set_view_rect(0u, 0u, 0u, uint(display_w), uint(display_h))
        bgfx_set_vertex_buffer(0u, vbh, 0u, uint(length(vertices)))
        bgfx_set_index_buffer(ibh, 0u, uint(length(indices)))
        f_tex.texture2D = uint(texture.idx)
        vs_main_bind_uniform()
        fs_main_bind_uniform()
        bgfx_submit(0u, program, 1u, BGFX_DISCARD_NONE)
        bgfx_frame(false)
    bgfx_shutdown()

options log
pezcode commented 3 years ago

When are you calling bgfx_create_uniform? Try calling that before bgfx_create_shader_program

borisbat commented 3 years ago

When are you calling bgfx_create_uniform? Try calling that before bgfx_create_shader_program

I've added bgfx_create_uniform before the program creation, like this:

    bgfx_create_uniform("c_offset", bgfx_uniform_type BGFX_UNIFORM_TYPE_VEC4, 1u)
    var compute_program = bgfx_create_compute_shader_program(COMPUTE_SRC, render_type)

and that made it work. Is that the intended use? I.e. do I have to create all uniforms before creating the programs?

In the original code uniform was created after the creation of the program, but set before program was used.

bkaradzic commented 3 years ago

Hey Boris! Long time no see! :)

Is that the intended use? I.e. do I have to create all uniforms before creating the programs?

This is actually not intended use, rather shortcoming/bug of how shaderc process GLSL compute shaders. glsl-optimizer doesn't do compute shaders, shaders get just preprocessed and output as raw shader without compilation/optimization step, and there is no reflection.

borisbat commented 3 years ago

Hey Boris! Long time no see! :)

:)

output as raw shader without compilation/optimization step, and there is no reflection.

I'm doing daScript integration ( daScript.org ). So I have all the information necessary and then some. I can create all uniforms before hand, or I can provide all that extra info to the shader compiler - if there is a way to do so.

bkaradzic commented 3 years ago

I can create all uniforms before hand, or I can provide all that extra info to the shader compiler - if there is a way to do so.

Yes, the best is to create all uniforms before creating shaders. Once I fix shaderc this requirement will be gone, but no ETA yet.

borisbat commented 3 years ago

Yes, the best is to create all uniforms before creating shaders.

Found a case where it crashes DX12 renderer (and DX12 only, DX11 and OpenGL work fine). I'll keep the workaround as OpenGL only thing for now.