Esempio n. 1
0
FLightBuffer::FLightBuffer()
{

	mBufferSize = INITIAL_BUFFER_SIZE;
	mByteSize = mBufferSize * sizeof(float);
	if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
	{
		mBufferType = GL_SHADER_STORAGE_BUFFER;
		mBlockAlign = 0;
		mBlockSize = mBufferSize;
	}
	else
	{
		mBufferType = GL_UNIFORM_BUFFER;
		mBlockSize = gl.maxuniformblock / 16;
		if (mBlockSize > 2048) mBlockSize = 2048;	// we don't really need a larger buffer
		mBlockAlign = mBlockSize / 2;
	}

	glGenBuffers(1, &mBufferId);
	glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId);
	glBindBuffer(mBufferType, mBufferId);	// Note: Some older AMD drivers don't do that in glBindBufferBase, as they should.
	if (gl.flags & RFL_BUFFER_STORAGE)
	{
		glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
	}
	else
	{
		glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW);
		mBufferPointer = NULL;
	}

	Clear();
	mLastMappedIndex = UINT_MAX;
}
Esempio n. 2
0
//---------------------------------------------------------------------------//
  void GpuBufferGL4::create( const GpuBufferCreationParams& clParameters, void* pInitialData /*= nullptr*/ )
  {
    destroy();

    ASSERT(clParameters.uElementSizeBytes > 0 && clParameters.uNumElements > 0,
       "Invalid buffer size specified");

    GpuBufferCreationParams* pBaseParams = &m_clParameters;
    *pBaseParams = clParameters;

    GLenum eUsageTarget;
    GLenum eBindingQuery;
    eUsageTarget = Internal::mapBufferUsage(clParameters.ePrimaryUsageType, eBindingQuery);
    m_clParameters.eInitialBufferTargetGL = eUsageTarget;
    m_clParameters.eBindingQueryType = eBindingQuery;

    uint32 uRequestedAccessFlags = clParameters.uAccessFlags;
    uint32 uAccessFlagsGL = 0;

    if ((uRequestedAccessFlags & (uint) GpuResourceAccessFlags::READ) > 0) {
      uAccessFlagsGL |= GL_MAP_READ_BIT;
    }

    if ((uRequestedAccessFlags & (uint) GpuResourceAccessFlags::WRITE) > 0) {
      uAccessFlagsGL |= GL_MAP_WRITE_BIT;
    }

    if ((uRequestedAccessFlags & (uint) GpuResourceAccessFlags::DYNAMIC) > 0) {
      uAccessFlagsGL |= GL_DYNAMIC_STORAGE_BIT;
    }

    if ((uRequestedAccessFlags & (uint) GpuResourceAccessFlags::COHERENT) > 0) {
      uAccessFlagsGL |= GL_MAP_COHERENT_BIT;
    }

    if ((uRequestedAccessFlags & (uint) GpuResourceAccessFlags::PREFER_CPU_STORAGE) > 0) {
      uAccessFlagsGL |= GL_CLIENT_STORAGE_BIT;
    }

    if ((uRequestedAccessFlags & (uint) GpuResourceAccessFlags::PERSISTENT_LOCKABLE) > 0) {
      uAccessFlagsGL |= GL_MAP_PERSISTENT_BIT;
    }

    // Sanity-checks on the access flags (following the OpenGL 4.4 standard)
    if((uAccessFlagsGL & GL_MAP_PERSISTENT_BIT) > 0 
      && ((uAccessFlagsGL & GL_MAP_WRITE_BIT) == 0 && (uAccessFlagsGL & GL_MAP_READ_BIT) == 0))
    {
      ASSERT(false, "A persistent buffer without CPU-access doesn't make sense");
    }

    /*if ((uAccessFlagsGL & GL_MAP_COHERENT_BIT) > 0 &&
        (uAccessFlagsGL & GL_MAP_PERSISTENT_BIT) == 0) 
    {
      ASSERT(false, "Coherent buffers also need to be persistent");
    } */

    // Derive the appropriate multibuffering settings
    if (!m_clParameters.bIsMultiBuffered)
    {
      m_uDerivedInternalBufferCount = 1u;
      m_eMultiBufferStrategy = MultiBufferingStrategy::NONE;
    }
    else  // Multibuffering is used 
    {
      // Note: Here we assume that persistant mapping also means the buffer is
      //        multibuffered internally using an offset... have to see if this is always desired
      if ( (uAccessFlagsGL & GL_MAP_PERSISTENT_BIT) > 0 ) 
      {
        m_eMultiBufferStrategy = MultiBufferingStrategy::OFFSETS;
        m_uDerivedInternalBufferCount = 1u;
      } 
      else 
      {
        m_eMultiBufferStrategy = MultiBufferingStrategy::BUFFERS;
        m_uDerivedInternalBufferCount = MultiBuffering::kGpuMultiBufferingCount;
      }
    }

    // Create and allocate the buffer
    m_clParameters.uAccessFlagsGL = uAccessFlagsGL;
    m_clParameters.uTotalSizeBytes = 
      clParameters.uNumElements * clParameters.uElementSizeBytes;

    // Retrieve the currently bound buffer to restore it later
    GLint originalBufferBinding;
    glGetIntegerv(eBindingQuery, &originalBufferBinding);

    if (m_eMultiBufferStrategy == MultiBufferingStrategy::NONE || 
        m_eMultiBufferStrategy == MultiBufferingStrategy::BUFFERS)
    {
      for (uint32 i = 0; i < m_uDerivedInternalBufferCount; ++i)
      {
        uint32 uGlHandle;

        glGenBuffers(1, &uGlHandle);
        glBindBuffer(eUsageTarget, uGlHandle);

        glBufferStorage(eUsageTarget, 
            m_clParameters.uTotalSizeBytes, 
            pInitialData, uAccessFlagsGL);

        m_vGLhandles.push_back(uGlHandle);
      }
    }
    else  // MultiBufferingStrategy::OFFSETS
    {
      uint32 uGlHandle;

      glGenBuffers(1, &uGlHandle);
      glBindBuffer(eUsageTarget, uGlHandle);

      // Allocate additional storage but update the initial data in substeps 
      // (because multibuffering should be transparent for high-level and pInitialData is
      // assumed to point to a single-buffer data store)
      glBufferStorage(eUsageTarget, 
        m_clParameters.uTotalSizeBytes * MultiBuffering::kGpuMultiBufferingCount, 
        nullptr, uAccessFlagsGL);

      for (uint32 iBufferPart = 0; iBufferPart < MultiBuffering::kGpuMultiBufferingCount; ++iBufferPart)
      {
        glBufferSubData(eUsageTarget,
          iBufferPart * m_clParameters.uTotalSizeBytes,
          m_clParameters.uTotalSizeBytes, pInitialData );
      }

      m_vGLhandles.push_back(uGlHandle);
    }

    // Restore the originally bound buffer
    glBindBuffer(eUsageTarget, static_cast<GLuint>(originalBufferBinding));
  }
Esempio n. 3
0
void
piglit_init(int argc, char **argv)
{
	static const char *vs_source =
		"#version 140\n"
		"in vec4 piglit_vertex;\n"
		"void main()\n"
		"{\n"
		"	gl_Position = piglit_vertex;\n"
		"}\n";

	static const char *fs_source =
		"#version 140\n"
		"uniform samplerBuffer s;\n"
		"uniform int offset;\n"
		"void main()\n"
		"{\n"
		"	gl_FragColor = texelFetch(s, 0);\n"
		"}\n";

	static const GLfloat verts[16] = {
		-1, -1,
		 0, -1,
		 0,  1,
		-1,  1,

		 0, -1,
		 1, -1,
		 1,  1,
		 0,  1
	};

	GLuint tex, tbo;
	GLuint prog;

	int vertex_location;
	GLuint vao, vbo;

	piglit_require_extension("GL_ARB_buffer_storage");

	prog = piglit_build_simple_program(vs_source, fs_source);
	glUseProgram(prog);
	vertex_location = glGetAttribLocation(prog, "piglit_vertex");

	glGenBuffers(1, &tbo);
	glBindBuffer(GL_TEXTURE_BUFFER, tbo);
	glBufferStorage(GL_TEXTURE_BUFFER, sizeof(red), NULL,
			GL_MAP_WRITE_BIT |
			GL_MAP_PERSISTENT_BIT |
			GL_MAP_COHERENT_BIT |
			GL_DYNAMIC_STORAGE_BIT);
	piglit_check_gl_error(GL_NO_ERROR);

	map = glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(red),
			       GL_MAP_WRITE_BIT |
			       GL_MAP_PERSISTENT_BIT |
			       GL_MAP_COHERENT_BIT);

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_BUFFER, tex);

	glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);

	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_READ);
	glVertexAttribPointer(vertex_location, 2, GL_FLOAT,
			      GL_FALSE, 0, NULL);
	glEnableVertexAttribArray(vertex_location);
}
Esempio n. 4
0
int FLightBuffer::UploadLights(FDynLightData &data)
{
	int size0 = data.arrays[0].Size()/4;
	int size1 = data.arrays[1].Size()/4;
	int size2 = data.arrays[2].Size()/4;
	int totalsize = size0 + size1 + size2 + 1;

	// pointless type casting because some compilers can't print enough warnings.
	if (mBlockAlign > 0 && (unsigned int)totalsize + (mIndex % mBlockAlign) > mBlockSize)
	{
		mIndex = ((mIndex + mBlockAlign) / mBlockAlign) * mBlockAlign;

		// can't be rendered all at once.
		if ((unsigned int)totalsize > mBlockSize)
		{
			int diff = totalsize - (int)mBlockSize;

			size2 -= diff;
			if (size2 < 0)
			{
				size1 += size2;
				size2 = 0;
			}
			if (size1 < 0)
			{
				size0 += size1;
				size1 = 0;
			}
			totalsize = size0 + size1 + size2 + 1;
		}
	}

	if (totalsize <= 1) return -1;

	if (mIndex + totalsize > mBufferSize/4)
	{
		// reallocate the buffer with twice the size
		unsigned int newbuffer;

		// first unmap the old buffer
		glBindBuffer(mBufferType, mBufferId);
		glUnmapBuffer(mBufferType);

		// create and bind the new buffer, bind the old one to a copy target (too bad that DSA is not yet supported well enough to omit this crap.)
		glGenBuffers(1, &newbuffer);
		glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, newbuffer);
		glBindBuffer(mBufferType, newbuffer);	// Note: Some older AMD drivers don't do that in glBindBufferBase, as they should.
		glBindBuffer(GL_COPY_READ_BUFFER, mBufferId);

		// create the new buffer's storage (twice as large as the old one)
		mBufferSize *= 2;
		mByteSize *= 2;
		if (gl.lightmethod == LM_DIRECT)
		{
			glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
			mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}
		else
		{
			glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW);
			mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT);
		}

		// copy contents and delete the old buffer.
		glCopyBufferSubData(GL_COPY_READ_BUFFER, mBufferType, 0, 0, mByteSize/2);
		glBindBuffer(GL_COPY_READ_BUFFER, 0);
		glDeleteBuffers(1, &mBufferId);
		mBufferId = newbuffer;
	}

	float *copyptr;
	
	assert(mBufferPointer != NULL);
	if (mBufferPointer == NULL) return -1;
	copyptr = mBufferPointer + mIndex * 4;

	float parmcnt[] = { 0, float(size0), float(size0 + size1), float(size0 + size1 + size2) };

	memcpy(&copyptr[0], parmcnt, 4 * sizeof(float));
	memcpy(&copyptr[4], &data.arrays[0][0], 4 * size0*sizeof(float));
	memcpy(&copyptr[4 + 4*size0], &data.arrays[1][0], 4 * size1*sizeof(float));
	memcpy(&copyptr[4 + 4*(size0 + size1)], &data.arrays[2][0], 4 * size2*sizeof(float));

	unsigned int bufferindex = mIndex;
	mIndex += totalsize;
	draw_dlight += (totalsize-1) / 2;
	return bufferindex;
}
Esempio n. 5
0
bool InitScene()
{
	SetWindowText(hwnd, TITLE);
	Quadron::qGLExtensions::QueryFeatures();

	isGL4_4 = (Quadron::qGLExtensions::GLVersion >= Quadron::qGLExtensions::GL_4_4);

	// setup opengl
	glClearColor(0.0f, 0.125f, 0.3f, 1.0f);
	glClearDepth(1.0);

	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	if( !GLCreateMeshFromQM("../media/meshes/teapot.qm", &mesh) )
	{
		MYERROR("Could not load mesh");
		return false;
	}

	if( !GLCreateEffectFromFile("../media/shadersGL/blinnphong.vert", 0, "../media/shadersGL/blinnphong.frag", &effect1) )
	{
		MYERROR("Could not load 'blinnphong' effect");
		return false;
	}

	if( !GLCreateEffectFromFile("../media/shadersGL/uniformbuffer.vert", 0, "../media/shadersGL/uniformbuffer.frag", &effect2) )
	{
		MYERROR("Could not load 'uniformbuffer' effect");
		return false;
	}

	if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/basic2D.frag", &basic2D) )
	{
		MYERROR("Could not load 'basic2D' shader");
		return false;
	}

	// create framebuffer
	framebuffer = new OpenGLFramebuffer(screenwidth, screenheight);

	framebuffer->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_A8B8G8R8, GL_NEAREST);
	framebuffer->AttachRenderbuffer(GL_DEPTH_STENCIL_ATTACHMENT, GLFMT_D24S8);

	if( !framebuffer->Validate() )
	{
		MYERROR("Framebuffer validation failed");
		return false;
	}

	// create uniform buffer
	effect2->SetUniformBlockBinding("VertexUniformData", 0);
	effect2->SetUniformBlockBinding("FragmentUniformData", 1);

	// simple uniform buffer
	glGenBuffers(1, &uniformbuffer1);
	glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer1);

	glBufferData(GL_UNIFORM_BUFFER, sizeof(EffectUniformBlock), NULL, GL_DYNAMIC_DRAW);
	glBindBuffer(GL_UNIFORM_BUFFER, 0);

	// uniform ringbuffer
	glGenBuffers(1, &uniformbuffer2);
	glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer2);

	glBufferData(GL_UNIFORM_BUFFER, UNIFORM_COPIES * sizeof(EffectUniformBlock), NULL, GL_DYNAMIC_DRAW);
	glBindBuffer(GL_UNIFORM_BUFFER, 0);

	if( isGL4_4 ) {
		// uniform storage buffer
		glGenBuffers(1, &uniformbuffer3);
		glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer3);

		glBufferStorage(GL_UNIFORM_BUFFER, UNIFORM_COPIES * sizeof(EffectUniformBlock), NULL, GL_DYNAMIC_STORAGE_BIT|GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT|GL_MAP_COHERENT_BIT);
		glBindBuffer(GL_UNIFORM_BUFFER, 0);
	}

	memset(&uniformDTO, 0, sizeof(uniformDTO));

	// render text
	GLCreateTexture(512, 512, 1, GLFMT_A8B8G8R8, &text1);

	if( isGL4_4 ) {
		glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer3);
		persistentdata = (EffectUniformBlock*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, UNIFORM_COPIES * sizeof(EffectUniformBlock), GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT|GL_MAP_COHERENT_BIT);
		glBindBuffer(GL_UNIFORM_BUFFER, 0);

		assert(persistentdata != 0);

		GLRenderText(
			"1 - glUniformXX\n2 - UBO with glBufferSubData\n3 - UBO with glMapBufferRange\n4 - UBO with glFenceSync\n5 - UBO with persistent mapping",
			text1, 512, 512);
	} else {
		GLRenderText(
			"1 - glUniformXX\n2 - UBO with glBufferSubData\n3 - UBO with glMapBufferRange\n4 - UBO with glFenceSync",
			text1, 512, 512);
	}

	screenquad = new OpenGLScreenQuad();

	// setup cameras
	basiccamera.SetAspect((float)screenwidth / screenheight);
	basiccamera.SetFov(GLDegreesToRadians(80));
	basiccamera.SetClipPlanes(0.1f, 30.0f);
	basiccamera.SetDistance(10.0f);

	return true;
}
Esempio n. 6
0
static void
testBufferStorage(void)
{

    if (!GLAD_GL_VERSION_4_4 &&
        !glfwExtensionSupported("GL_ARB_buffer_storage")) {
        fprintf(stderr, "error: GL_ARB_buffer_storage not supported\n");
        glfwTerminate();
        exit(EXIT_SKIP);
    }

    GLbitfield map_trace_explicit_bit = 0;
    if (glfwExtensionSupported("GL_VMWX_map_buffer_debug")) {
        glNotifyMappedBufferRangeVMWX = (PFNGLNOTIFYMAPPEDBUFFERRANGEVMWXPROC)glfwGetProcAddress("glNotifyMappedBufferRangeVMWX");
        assert(glNotifyMappedBufferRangeVMWX);
        map_trace_explicit_bit = GL_MAP_NOTIFY_EXPLICIT_BIT_VMWX;
    }

    GLuint buffer = 0;
    glGenBuffers(1, &buffer);

    glBindBuffer(target, buffer);

    GLsizeiptr size = 1000;

    void *data = malloc(size);
    memset(data, 0, size);

    while ((glGetError() != GL_NO_ERROR))
        ;
    
    glBufferStorage(target, size, data,
                    GL_MAP_WRITE_BIT |
                    GL_MAP_PERSISTENT_BIT |
                    GL_MAP_COHERENT_BIT |
                    map_trace_explicit_bit);

    free(data);

    GLenum error = glGetError();
    switch (error) {
    case GL_NO_ERROR:
        break;
    case GL_OUT_OF_MEMORY:
        exit(EXIT_SKIP);
    default:
        exit(EXIT_FAILURE);
    }

    GLubyte *map;

    // straightforward mapping
    map = (GLubyte *)glMapBufferRange(target, 100, 100, GL_MAP_WRITE_BIT);
    memset(map, 1, 100);
    glUnmapBuffer(target);

    // persistent mapping w/ explicit flush
    map = (GLubyte *)glMapBufferRange(target, 200, 300, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
    memset(map + 20, 2, 30);
    glFlushMappedBufferRange(target, 20, 30);
    memset(map + 50, 3, 50);
    glFlushMappedBufferRange(target, 50, 50);
    glUnmapBuffer(target);

    // persistent & coherent mapping
    map = (GLubyte *)glMapBufferRange(target, 500, 100, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | map_trace_explicit_bit);
    memset(map + 20, 4, 30);
    glNotifyMappedBufferRangeVMWX(map + 20, 30);
    memset(map + 50, 5, 50);
    glNotifyMappedBufferRangeVMWX(map + 50, 50);
    glUnmapBuffer(target);

    glBindBuffer(target, 0);

    glDeleteBuffers(1, &buffer);
}
Esempio n. 7
0
void
piglit_init(int argc, char **argv)
{
	int i;

	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "coherent")) {
			coherent = GL_TRUE;
			continue;
		}
		if (!strcmp(argv[i], "read")) {
			test = READ;
			continue;
		}
		if (!strcmp(argv[i], "draw")) {
			test = DRAW;
			continue;
		}
		if (!strcmp(argv[i], "client-storage")) {
			client_storage = GL_TRUE;
			continue;
		}

		printf("Unknown param: %s\n", argv[i]);
		piglit_report_result(PIGLIT_FAIL);
	}

	if (test == NONE) {
		puts("Wrong parameters.");
		piglit_report_result(PIGLIT_FAIL);
	}

#ifdef PIGLIT_USE_OPENGL
	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

	piglit_require_gl_version(15);
	piglit_require_extension("GL_ARB_buffer_storage");
        piglit_require_extension("GL_ARB_map_buffer_range");
	if (test == READ) {
		piglit_require_extension("GL_ARB_copy_buffer");
		piglit_require_extension("GL_ARB_sync");
	}
	if (!coherent) { /* for MemoryBarrier */
		piglit_require_extension("GL_ARB_shader_image_load_store");
	}
#else // PIGLIT_USE_OPENGL_ES3
       GLuint program;
       GLuint vertex_index;

       piglit_require_extension("GL_EXT_buffer_storage");

       /* Create program */
       program = piglit_build_simple_program(vs_source, fs_source);
       glUseProgram(program);
#endif

	glGenBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferStorage(GL_ARRAY_BUFFER, BUF_SIZE, NULL,
			GL_MAP_WRITE_BIT |
			GL_MAP_PERSISTENT_BIT |
			(coherent ? GL_MAP_COHERENT_BIT : 0) |
			GL_DYNAMIC_STORAGE_BIT |
			(client_storage ? GL_CLIENT_STORAGE_BIT : 0));

	piglit_check_gl_error(GL_NO_ERROR);

	map = glMapBufferRange(GL_ARRAY_BUFFER, 0, BUF_SIZE,
			       GL_MAP_WRITE_BIT |
			       GL_MAP_PERSISTENT_BIT |
			       (coherent ? GL_MAP_COHERENT_BIT : 0));

	piglit_check_gl_error(GL_NO_ERROR);

	if (!map)
		piglit_report_result(PIGLIT_FAIL);
#ifdef PIGLIT_USE_OPENGL_ES3
	/* Gen VAO */
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	/* Retrieve indices from vs */
	vertex_index = glGetAttribLocation(program, "vertex");

	/* Enable vertex attrib array */
	glEnableVertexAttribArray(vertex_index);
	glVertexAttribPointer(vertex_index, 3, GL_FLOAT, GL_FALSE, 0, 0);

	piglit_check_gl_error(GL_NO_ERROR);
#endif

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}
Esempio n. 8
0
// --------------------------------------------------------------------------------------------------------------------
bool UntexturedObjectsGLBindlessIndirect::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices,
                                               const std::vector<UntexturedObjectsProblem::Index>& _indices,
                                               size_t _objectCount)
{
    if (glBufferStorage == nullptr) {
        console::warn("Unable to initialize solution '%s', glBufferStorage() unavailable.", GetName().c_str());
        return false;
    }

    if (glGetBufferParameterui64vNV == nullptr ||
        glMakeBufferResidentNV == nullptr) {
        console::warn("Unable to initialize solution '%s', GL_NV_shader_buffer_load unavailable.", GetName().c_str());
        return false;
    }

    if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) {
        return false;
    }

    // Program
    const char* kUniformNames[] = { "ViewProjection", "World", nullptr };

    m_prog = CreateProgramT("cubes_gl_bindless_indirect_vs.glsl",
                            "cubes_gl_bindless_indirect_fs.glsl",
                            kUniformNames, &mUniformLocation);

    if (m_prog == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    m_ibs.resize(_objectCount);
    m_ib_addrs.resize(_objectCount);
    m_ib_sizes.resize(_objectCount);

    m_vbs.resize(_objectCount);
    m_vbo_addrs.resize(_objectCount);
    m_vbo_sizes.resize(_objectCount);

    m_commands.resize(_objectCount);

    glGenBuffers(_objectCount, &*m_ibs.begin());
    glGenBuffers(_objectCount, &*m_vbs.begin());

    for (size_t u = 0; u < _objectCount; ++u)
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibs[u]);
        glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), 0);
        glGetBufferParameterui64vNV(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_ib_addrs[u]);
        glMakeBufferResidentNV(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
        m_ib_sizes[u] = _indices.size() * sizeof(UntexturedObjectsProblem::Index);

        glBindBuffer(GL_ARRAY_BUFFER, m_vbs[u]);
        glBufferStorage(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), 0);
        glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_vbo_addrs[u]);
        glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY);
        m_vbo_sizes[u] = _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex);
    }

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);
    glBufferStorage(GL_SHADER_STORAGE_BUFFER, _objectCount * 64, nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT);
    m_transform_ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, _objectCount * 64, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);

    glGenBuffers(1, &m_cmd_buffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmd_buffer);
    glBufferStorage(GL_DRAW_INDIRECT_BUFFER, _objectCount * sizeof(Command), nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT);
    m_cmd_ptr = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _objectCount * sizeof(Command), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);

    m_queries.resize(4);
    glGenQueries(kQueryCount, &*m_queries.begin());

    return glGetError() == GL_NO_ERROR;
}
Esempio n. 9
0
/** Update shadowSplit values and make Cascade Bounding Box pointer valid.
* The function aunches two compute kernel that generates an histogram of the depth buffer value (between 0 and 250 with increment of 0.25)
* and get an axis aligned bounding box (from SunCamMatrix view) containing all depth buffer value.
* It also retrieves the result from the previous computations (in a Round Robin fashion) and update CBB pointer.
* \param width of the depth buffer
* \param height of the depth buffer
* TODO : The depth histogram part is commented out, needs to tweak it when I have some motivation
*/
void IrrDriver::UpdateSplitAndLightcoordRangeFromComputeShaders(size_t width, size_t height)
{
    // Value that should be kept between multiple calls
    static GLuint ssbo[2];
    static Histogram *Hist[2];
    static GLsync LightcoordBBFence = 0;
    static size_t currentHist = 0;
    static GLuint ssboSplit[2];
    static float tmpshadowSplit[5] = { 1., 5., 20., 50., 150. };

    if (!LightcoordBBFence)
    {
        glGenBuffers(2, ssbo);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[0]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        CBB[0] = (CascadeBoundingBox *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(CascadeBoundingBox), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[1]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        CBB[1] = (CascadeBoundingBox *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(CascadeBoundingBox), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);

/*        glGenBuffers(2, ssboSplit);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboSplit[0]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(Histogram), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        Hist[0] = (Histogram *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Histogram), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboSplit[1]);
        glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(Histogram), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
        Hist[1] = (Histogram *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Histogram), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);*/
    }

    // Use bounding boxes from last frame
    if (LightcoordBBFence)
    {
        while (glClientWaitSync(LightcoordBBFence, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_ALREADY_SIGNALED);
        glDeleteSync(LightcoordBBFence);
    }

/*    {
        memcpy(shadowSplit, tmpshadowSplit, 5 * sizeof(float));
        unsigned numpix = Hist[currentHist]->count;
        unsigned split = 0;
        unsigned i;
        for (i = 0; i < 1022; i++)
        {
            split += Hist[currentHist]->bin[i];
            if (split > numpix / 2)
                break;
        }
        tmpshadowSplit[1] = (float)++i / 4.;

        for (; i < 1023; i++)
        {
            split += Hist[currentHist]->bin[i];
            if (split > 3 * numpix / 4)
                break;
        }
        tmpshadowSplit[2] = (float)++i / 4.;

        for (; i < 1024; i++)
        {
            split += Hist[currentHist]->bin[i];
            if (split > 7 * numpix / 8)
                break;
        }
        tmpshadowSplit[3] = (float)++i / 4.;

        for (; i < 1024; i++)
        {
            split += Hist[currentHist]->bin[i];
        }

        tmpshadowSplit[0] = (float)(Hist[currentHist]->bin[1024] - 1) / 4.;
        tmpshadowSplit[4] = (float)(Hist[currentHist]->bin[1025] + 1) / 4.;
                printf("numpix is %d\n", numpix);
        printf("total : %d\n", split);
        printf("split 0 : %f\n", tmpshadowSplit[1]);
        printf("split 1 : %f\n", tmpshadowSplit[2]);
        printf("split 2 : %f\n", tmpshadowSplit[3]);
        printf("min %f max %f\n", tmpshadowSplit[0], tmpshadowSplit[4]);
        currentHist = (currentHist + 1) % 2;
    }*/

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo[currentCBB]);
//    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssboSplit[currentHist]);
    for (unsigned i = 0; i < 4; i++)
    {
        CBB[currentCBB][i].xmin = CBB[currentCBB][i].ymin = CBB[currentCBB][i].zmin = 1000;
        CBB[currentCBB][i].xmax = CBB[currentCBB][i].ymax = CBB[currentCBB][i].zmax = -1000;
    }
//    memset(Hist[currentHist], 0, sizeof(Histogram));
//    Hist[currentHist]->mindepth = 3000;
    glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
    glUseProgram(FullScreenShader::LightspaceBoundingBoxShader::getInstance()->Program);
    FullScreenShader::LightspaceBoundingBoxShader::getInstance()->SetTextureUnits(getDepthStencilTexture());
    FullScreenShader::LightspaceBoundingBoxShader::getInstance()->setUniforms(m_suncam->getViewMatrix(), tmpshadowSplit[1], tmpshadowSplit[2], tmpshadowSplit[3], tmpshadowSplit[4]);
    glDispatchCompute((int)width / 64, (int)height / 64, 1);

/*    glUseProgram(FullScreenShader::DepthHistogramShader::getInstance()->Program);
    FullScreenShader::DepthHistogramShader::getInstance()->SetTextureUnits(getDepthStencilTexture());
    FullScreenShader::DepthHistogramShader::getInstance()->setUniforms();
    glDispatchCompute((int)width / 32, (int)height / 32, 1);*/

    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
    LightcoordBBFence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    currentCBB = (currentCBB + 1) % 2;

}
Esempio n. 10
0
inline void buffer_storage(BufferType target, uint32 size, const void* data, BufferStorage flags)
{
    ARC_GL_CLEAR_ERRORS();
    glBufferStorage((GLenum)target, size, data, (GLbitfield)flags);
    ARC_GL_CHECK_FOR_ERRORS();
}
Esempio n. 11
0
/**
 * TODO: Test if you can pass a NULL mesh to Geometry.
 */
RenderableGeometry *renderableGeometryNew(Geometry geometry)
{
	RenderableGeometry *renderableGeometry = malloc(sizeof(RenderableGeometry));

	renderableGeometry->indices = 0;
	renderableGeometry->aabb.min = vec3(0.0f, 0.0f, 0.0f);
	renderableGeometry->aabb.max = vec3(0.0f, 0.0f, 0.0f);

	glGenVertexArrays(1, &renderableGeometry->vao);
	glGenBuffers(4, renderableGeometry->vbo);

	Mesh *mesh = NULL;

	if (geometry.type == GEOMETRY_MESH) {
		mesh = geometry.mesh;
	} else if (geometry.type == GEOMETRY_PLANE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_CUBE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_SPHERE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_CAPSULE) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_CYLINDER) {
		// Generate mesh
	} else if (geometry.type == GEOMETRY_RAY) {
		// Generate mesh
	}

	if (mesh != NULL) {
		renderableGeometry->indices = (GLsizei)mesh->indices.length;

		/**
		 * Define VAO.
		 */
		glBindVertexArray(renderableGeometry->vao);

		glEnableVertexAttribArray(0);
		glEnableVertexAttribArray(1);
		glEnableVertexAttribArray(2);

		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); 
		glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 0); 
		glVertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 0);
		
		/**
		 * Define VBOs.
		 */
		if (mesh->vertices.length > 0) {
			glBindBuffer(GL_ARRAY_BUFFER, renderableGeometry->vbo[0]);
			glBufferStorage(GL_ARRAY_BUFFER, mesh->vertices.length * sizeof(Vec3), (float*)mesh->vertices.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);	
		}

		if (mesh->uvs.length > 0) {
			glBindBuffer(GL_ARRAY_BUFFER, renderableGeometry->vbo[1]);
			glBufferStorage(GL_ARRAY_BUFFER, mesh->uvs.length * sizeof(Vec2), (float*)mesh->uvs.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}

		if (mesh->normals.length > 0) {
			glBindBuffer(GL_ARRAY_BUFFER, renderableGeometry->vbo[2]);
			glBufferStorage(GL_ARRAY_BUFFER, mesh->normals.length * sizeof(Vec3), (float*)mesh->normals.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}

		if (mesh->indices.length > 0) {
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderableGeometry->vbo[3]);
			glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, mesh->indices.length * sizeof(unsigned), (unsigned*)mesh->indices.data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
		}

		glBindVertexBuffer(0, renderableGeometry->vbo[0], 0, sizeof(Vec3));
		glBindVertexBuffer(1, renderableGeometry->vbo[1], 0, sizeof(Vec2));
		glBindVertexBuffer(2, renderableGeometry->vbo[2], 0, sizeof(Vec3));

		/**
		 * Unbind.
		 */
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
	}
	
	return renderableGeometry;
}
Esempio n. 12
0
Renderer::Renderer(const int width, const int height) : width(width), height(height), mvp{}
{
    glDebugMessageCallback(gl_debug_callback, NULL);

    const int max_vertices {100};

    const GLbitfield flags {GL_MAP_WRITE_BIT |
                            GL_MAP_PERSISTENT_BIT |
                            GL_MAP_COHERENT_BIT};
    /* factor 3 comes from euler characteristic */
    const size_t vbo_size {max_vertices * 3 * sizeof(GLfloat)};
    const size_t ebo_size {max_vertices * sizeof(GLuint)};
    const size_t vbo_lines_size {10 * 4 * sizeof(GLfloat)};

    glGenBuffers(2, vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferStorage(GL_ARRAY_BUFFER, vbo_size, NULL, flags);  
    vbo_mapped = glMapBufferRange(GL_ARRAY_BUFFER, 0, vbo_size, flags);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferStorage(GL_ARRAY_BUFFER, vbo_lines_size, NULL, flags);
    vbo_lines_mapped = glMapBufferRange(GL_ARRAY_BUFFER, 0, vbo_lines_size, flags);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, ebo_size, NULL, flags);
    ebo_mapped = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0 , ebo_size, flags);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glGenVertexArrays(2, vao);
    glBindVertexArray(vao[0]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

    /* velocity VAO */
    glBindVertexArray(vao[1]);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

    /* pass through shaders */
    const std::string vert_data = read_file("data/main.vert");
    const char *vert_data_ptr = vert_data.c_str();
    vert_prog[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vert_data_ptr);

    const std::string frag_data = read_file("data/main.frag");
    const char *frag_data_ptr = frag_data.c_str();
    frag_prog[0] = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &frag_data_ptr);

    glGenProgramPipelines(2, pipeline);
    
    glUseProgramStages(pipeline[0], GL_VERTEX_SHADER_BIT, vert_prog[0]);
    glUseProgramStages(pipeline[0], GL_FRAGMENT_SHADER_BIT, frag_prog[0]);

    /* debug arrows shaders */
    const std::string frag_velocity = read_file("data/velocity.frag");
    const char *frag_velocity_ptr = frag_velocity.c_str();
    frag_prog[1] = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &frag_velocity_ptr);

    glUseProgramStages(pipeline[1], GL_VERTEX_SHADER_BIT, vert_prog[0]);
    glUseProgramStages(pipeline[1], GL_FRAGMENT_SHADER_BIT, frag_prog[1]);
    

    /* set up uniforms */
    mvp.view = {20.0f / width, 0.0f, 0.0f, 0.0f,
                0.0f, 20.0f / height, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                -1.0f, -1.0f, 0.0f, 1.0f}; 

    glGenBuffers(1, &ubo);
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    glBufferStorage(GL_UNIFORM_BUFFER, sizeof(mvp), &mvp, GL_DYNAMIC_STORAGE_BIT);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);
    
    glUniformBlockBinding(vert_prog[0], glGetUniformBlockIndex(vert_prog[0], "MVP"), 0);
    glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, sizeof(mvp));
}
Esempio n. 13
0
//==============================================================================
void GlBuffer::create(GLenum target, U32 sizeInBytes,
	const void* dataPtr, GLbitfield flags)
{
	ANKI_ASSERT(!isCreated());

	if(target == GL_UNIFORM_BUFFER)
	{
		GLint64 maxBufferSize;
		glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);

		if(sizeInBytes > 16384)
		{
			ANKI_LOGW("The size (%u) of the uniform buffer is greater "
				"than the spec's min", sizeInBytes);
		} 
		else if(sizeInBytes > (PtrSize)maxBufferSize)
		{
			ANKI_LOGW("The size (%u) of the uniform buffer is greater "
				"than the implementation's min (%u)", sizeInBytes, 
				maxBufferSize);
		}
	}
	else if(target == GL_SHADER_STORAGE_BUFFER)
	{
		GLint64 maxBufferSize;
		glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxBufferSize);

		if(sizeInBytes > pow(2, 24))
		{
			ANKI_LOGW("The size (%u) of the uniform buffer is greater "
				"than the spec's min", sizeInBytes);
		} 
		else if(sizeInBytes > (PtrSize)maxBufferSize)
		{
			ANKI_LOGW("The size (%u) of the shader storage buffer is greater "
				"than the implementation's min (%u)", sizeInBytes, 
				maxBufferSize);
		}
	}

	m_target = target;
	m_size = sizeInBytes;

	ANKI_ASSERT(m_size > 0 && "Unacceptable size");

	// Create
	glGenBuffers(1, &m_glName);

	glBindBuffer(m_target, m_glName);
	glBufferStorage(m_target, m_size, dataPtr, flags);

	// Map if needed
	if((flags & GL_MAP_PERSISTENT_BIT) && (flags & GL_MAP_COHERENT_BIT))
	{
		const GLbitfield mapbits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT 
			| GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;

		m_persistentMapping = 
			glMapBufferRange(m_target, 0, sizeInBytes, flags & mapbits);
		ANKI_ASSERT(m_persistentMapping != nullptr);
	}
}
Esempio n. 14
0
// --------------------------------------------------------------------------------------------------------------------
bool UntexturedObjectsGLBufferStorage::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices,
                                            const std::vector<UntexturedObjectsProblem::Index>& _indices,
                                            size_t _objectCount)
{
    if (glBufferStorage == nullptr) {
        console::warn("Unable to initialize solution '%s', glBufferStorage() unavailable.", GetName().c_str());
        return false;
    }

    if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) {
        return false;
    }

    if (mUseShaderDrawParameters && !HasExtension("GL_ARB_shader_draw_parameters")) {
        console::warn("Unable to initialize solution, ARB_shader_draw_parameters is required but not available.");
        return false;
    }

    // Program
    const char* kUniformNames[] = { "ViewProjection", nullptr };

    m_prog = CreateProgramT("cubes_gl_buffer_storage_vs.glsl",
                            "cubes_gl_buffer_storage_fs.glsl",
                            mUseShaderDrawParameters ? std::string("#define USE_SHADER_DRAW_PARAMETERS 1\n") : std::string(""),
                            kUniformNames, &mUniformLocation);

    if (m_prog == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    glGenVertexArrays(1, &m_varray);
    glBindVertexArray(m_varray);

    // Buffers
    glGenBuffers(1, &m_vb);
    glBindBuffer(GL_ARRAY_BUFFER, m_vb);
    glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, pos));
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, color));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    // If we aren't using shader draw parameters, use the workaround instead.
    if (!mUseShaderDrawParameters) {
        std::vector<uint32_t> drawids(_objectCount);
        for (uint32_t i = 0; i < _objectCount; ++i) {
            drawids[i] = i;
        }

        glGenBuffers(1, &m_drawid);
        glBindBuffer(GL_ARRAY_BUFFER, m_drawid);
        glBufferData(GL_ARRAY_BUFFER, drawids.size() * sizeof(uint32_t), drawids.data(), GL_STATIC_DRAW);
        glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0);
        glVertexAttribDivisor(2, 1);
        glEnableVertexAttribArray(2);
    }

    glGenBuffers(1, &m_ib);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), GL_STATIC_DRAW);

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);
    glBufferStorage(GL_SHADER_STORAGE_BUFFER, _objectCount * 64, nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT);
    m_transform_ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, _objectCount * 64, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);

    glGenBuffers(1, &m_cmd_buffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmd_buffer);
    glBufferStorage(GL_DRAW_INDIRECT_BUFFER, _objectCount * sizeof(DrawElementsIndirectCommand), nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT);
    m_cmd_ptr = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _objectCount * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);

    // Set the command buffer size.
    m_commands.resize(_objectCount);

    return glGetError() == GL_NO_ERROR;
}
Esempio n. 15
0
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL44_nglBufferStorage(JNIEnv *env, jclass clazz, jint target, jlong size, jlong data, jint flags, jlong function_pointer) {
	const GLvoid *data_address = (const GLvoid *)(intptr_t)data;
	glBufferStoragePROC glBufferStorage = (glBufferStoragePROC)((intptr_t)function_pointer);
	glBufferStorage(target, size, data_address, flags);
}
Esempio n. 16
0
//==============================================================================
void BufferImpl::init(
	PtrSize size, BufferUsageBit usage, BufferAccessBit access)
{
	ANKI_ASSERT(!isCreated());
	m_usage = usage;
	m_access = access;

	///
	// Check size
	//

	ANKI_ASSERT(size > 0 && "Unacceptable size");

	// This is a guess, not very important since DSA doesn't care about it on
	// creation
	m_target = GL_ARRAY_BUFFER;

	if((usage & BufferUsageBit::UNIFORM) != BufferUsageBit::NONE)
	{
		GLint64 maxBufferSize;
		glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);

		if(size > 16384)
		{
			ANKI_LOGW("The size (%u) of the uniform buffer is greater "
					  "than the spec's min",
				size);
		}
		else if(size > PtrSize(maxBufferSize))
		{
			ANKI_LOGW("The size (%u) of the uniform buffer is greater "
					  "than the implementation's min (%u)",
				size,
				maxBufferSize);
		}

		m_target = GL_UNIFORM_BUFFER;
	}

	if((usage & BufferUsageBit::STORAGE) != BufferUsageBit::NONE)
	{
		GLint64 maxBufferSize;
		glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxBufferSize);

		if(size > pow(2, 24))
		{
			ANKI_LOGW("The size (%u) of the uniform buffer is greater "
					  "than the spec's min",
				size);
		}
		else if(size > PtrSize(maxBufferSize))
		{
			ANKI_LOGW("The size (%u) of the shader storage buffer is greater "
					  "than the implementation's min (%u)",
				size,
				maxBufferSize);
		}

		m_target = GL_SHADER_STORAGE_BUFFER;
	}

	m_size = size;

	//
	// Determine the creation flags
	//
	GLbitfield flags = 0;
	Bool shouldMap = false;
	if((access & BufferAccessBit::CLIENT_WRITE) != BufferAccessBit::NONE)
	{
		flags |= GL_DYNAMIC_STORAGE_BIT;
	}

	if((access & BufferAccessBit::CLIENT_MAP_WRITE) != BufferAccessBit::NONE)
	{
		flags |= GL_MAP_WRITE_BIT;
		flags |= GL_MAP_PERSISTENT_BIT;
		flags |= GL_MAP_COHERENT_BIT;

		shouldMap = true;
	}

	if((access & BufferAccessBit::CLIENT_MAP_READ) != BufferAccessBit::NONE)
	{
		flags |= GL_MAP_READ_BIT;
		flags |= GL_MAP_PERSISTENT_BIT;
		flags |= GL_MAP_COHERENT_BIT;

		shouldMap = true;
	}

	//
	// Create
	//
	glGenBuffers(1, &m_glName);
	glBindBuffer(m_target, m_glName);
	glBufferStorage(m_target, size, nullptr, flags);

	//
	// Map
	//
	if(shouldMap)
	{
		const GLbitfield MAP_BITS = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT
			| GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;

		m_persistentMapping =
			glMapBufferRange(m_target, 0, size, flags & MAP_BITS);
		ANKI_ASSERT(m_persistentMapping != nullptr);
	}
}
Esempio n. 17
0
	void OGLTexture1D::CreateHWResource(ArrayRef<ElementInitData> init_data, float4 const * clear_value_hint)
	{
		KFL_UNUSED(clear_value_hint);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		if (sample_count_ <= 1)
		{
			uint32_t const pbo_size = mipmap_start_offset_.back() * array_size_;
			if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
			{
				glTextureParameteri(texture_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				glNamedBufferStorage(pbo_, pbo_size, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);

				uint32_t const w0 = this->Width(0);

				if (array_size_ > 1)
				{
					glTextureStorage2D(texture_, num_mip_maps_, glinternalFormat, w0, array_size_);
				}
				else
				{
					glTextureStorage1D(texture_, num_mip_maps_, glinternalFormat, w0);
				}

				if (!init_data.empty())
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);
							GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									glCompressedTextureSubImage2D(texture_, level, 0, array_index,
										w, 1, glformat, image_size, data);
								}
								else
								{
									glCompressedTextureSubImage1D(texture_, level, 0,
										w, glformat, image_size, data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									glTextureSubImage2D(texture_, level, 0, array_index, w, 1,
										glformat, gltype, data);
								}
								else
								{
									glTextureSubImage1D(texture_, level, 0, w, glformat, gltype, data);
								}
							}
						}
					}
				}
			}
			else
			{
				auto& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
				
				re.BindTexture(0, target_type_, texture_);
				glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_);
				if (glloader_GL_VERSION_4_4() || glloader_GL_ARB_buffer_storage())
				{
					glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_DYNAMIC_STORAGE_BIT);
				}
				else
				{
					glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_STREAM_COPY);
				}
				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

				if (glloader_GL_VERSION_4_2() || glloader_GL_ARB_texture_storage())
				{
					uint32_t const w0 = this->Width(0);

					if (array_size_ > 1)
					{
						glTexStorage2D(target_type_, num_mip_maps_, glinternalFormat, w0, array_size_);
					}
					else
					{
						glTexStorage1D(target_type_, num_mip_maps_, glinternalFormat, w0);
					}

					if (!init_data.empty())
					{
						for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
						{
							for (uint32_t level = 0; level < num_mip_maps_; ++ level)
							{
								uint32_t const w = this->Width(level);
								GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

								if (IsCompressedFormat(format_))
								{
									uint32_t const block_size = NumFormatBytes(format_) * 4;
									GLsizei const image_size = ((w + 3) / 4) * block_size;

									if (array_size_ > 1)
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index,
											w, 1, glformat, image_size, data);
									}
									else
									{
										glCompressedTexSubImage1D(target_type_, level, 0,
											w, glformat, image_size, data);
									}
								}
								else
								{
									if (array_size_ > 1)
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, data);
									}
									else
									{
										glTexSubImage1D(target_type_, level, 0, w, glformat, gltype, data);
									}
								}
							}
						}
					}
				}
				else
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glCompressedTexImage2D(target_type_, level, glinternalFormat,
											w, array_size_, 0, image_size * array_size_, nullptr);
									}

									if (!init_data.empty())
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glCompressedTexImage1D(target_type_, level, glinternalFormat,
										w, 0, image_size,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr);
									}

									if (!init_data.empty())
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
						}
					}
				}
			}
		}
		else
		{
			glBindRenderbuffer(GL_RENDERBUFFER, texture_);
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1);
		}

		hw_res_ready_ = true;
	}