forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			148 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			148 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | #include "ComputeImpl.h"
 | ||
|  | #include "ogl.h"
 | ||
|  | #include <Kore/Compute/Compute.h>
 | ||
|  | #include <Kore/Graphics3/Graphics.h>
 | ||
|  | #include <Kore/Math/Core.h>
 | ||
|  | #include <stdio.h>
 | ||
|  | 
 | ||
|  | using namespace Kore; | ||
|  | 
 | ||
|  | #if defined(KINC_WINDOWS) || (defined(KINC_LINUX) && defined(GL_VERSION_4_3)) || (defined(KINC_ANDROID) && defined(GL_ES_VERSION_3_1))
 | ||
|  | #define HAS_COMPUTE
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | ComputeShaderImpl::ComputeShaderImpl(void *source, int length) : _length(length) { | ||
|  | 	_source = new char[length + 1]; | ||
|  | 	for (int i = 0; i < length; ++i) { | ||
|  | 		_source[i] = ((char *)source)[i]; | ||
|  | 	} | ||
|  | 	_source[length] = 0; | ||
|  | 
 | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	_id = glCreateShader(GL_COMPUTE_SHADER); | ||
|  | 	glCheckErrors(); | ||
|  | 	glShaderSource(_id, 1, &_source, nullptr); | ||
|  | 	glCompileShader(_id); | ||
|  | 
 | ||
|  | 	int result; | ||
|  | 	glGetShaderiv(_id, GL_COMPILE_STATUS, &result); | ||
|  | 	if (result != GL_TRUE) { | ||
|  | 		int length; | ||
|  | 		glGetShaderiv(_id, GL_INFO_LOG_LENGTH, &length); | ||
|  | 		char *errormessage = new char[length]; | ||
|  | 		glGetShaderInfoLog(_id, length, nullptr, errormessage); | ||
|  | 		log(Error, "GLSL compiler error: %s\n", errormessage); | ||
|  | 		delete[] errormessage; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	_programid = glCreateProgram(); | ||
|  | 	glAttachShader(_programid, _id); | ||
|  | 	glLinkProgram(_programid); | ||
|  | 
 | ||
|  | 	glGetProgramiv(_programid, GL_LINK_STATUS, &result); | ||
|  | 	if (result != GL_TRUE) { | ||
|  | 		int length; | ||
|  | 		glGetProgramiv(_programid, GL_INFO_LOG_LENGTH, &length); | ||
|  | 		char *errormessage = new char[length]; | ||
|  | 		glGetProgramInfoLog(_programid, length, nullptr, errormessage); | ||
|  | 		log(Error, "GLSL linker error: %s\n", errormessage); | ||
|  | 		delete[] errormessage; | ||
|  | 	} | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | ComputeShaderImpl::~ComputeShaderImpl() { | ||
|  | 	delete[] _source; | ||
|  | 	_source = nullptr; | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	glDeleteProgram(_programid); | ||
|  | 	glDeleteShader(_id); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | ComputeShader::ComputeShader(void *_data, int length) : ComputeShaderImpl(_data, length) {} | ||
|  | 
 | ||
|  | ComputeConstantLocation ComputeShader::getConstantLocation(const char *name) { | ||
|  | 	ComputeConstantLocation location; | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	location.location = glGetUniformLocation(_programid, name); | ||
|  | 	glCheckErrors2(); | ||
|  | 	if (location.location < 0) { | ||
|  | 		log(Warning, "Uniform %s not found.", name); | ||
|  | 	} | ||
|  | #endif
 | ||
|  | 	return location; | ||
|  | } | ||
|  | 
 | ||
|  | ComputeTextureUnit ComputeShader::getTextureUnit(const char *name) { | ||
|  | 	ComputeTextureUnit unit; | ||
|  | 	unit.unit = 0; | ||
|  | 	return unit; | ||
|  | } | ||
|  | 
 | ||
|  | void Compute::setFloat(ComputeConstantLocation location, float value) { | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	glUniform1f(location.location, value); | ||
|  | 	glCheckErrors2(); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void Compute::setBuffer(ShaderStorageBuffer *buffer, int index) { | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer->bufferId); | ||
|  | 	glCheckErrors2(); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void Compute::setTexture(ComputeTextureUnit unit, Graphics4::Texture *texture, Access access) { | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	glActiveTexture(GL_TEXTURE0 + unit.unit); | ||
|  | 	glCheckErrors2(); | ||
|  | 	GLenum glaccess = access == Access::Read ? GL_READ_ONLY : (access == Access::Write ? GL_WRITE_ONLY : GL_READ_WRITE); | ||
|  | 	glBindImageTexture(0, texture->texture, 0, GL_FALSE, 0, glaccess, GL_RGBA32F); | ||
|  | 	glCheckErrors2(); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void Compute::setTexture(ComputeTextureUnit unit, Graphics4::RenderTarget *target, Access access) {} | ||
|  | 
 | ||
|  | void Compute::setSampledTexture(ComputeTextureUnit unit, Graphics4::Texture *texture) {} | ||
|  | 
 | ||
|  | void Compute::setSampledTexture(ComputeTextureUnit unit, Graphics4::RenderTarget *target) {} | ||
|  | 
 | ||
|  | void Compute::setSampledDepthTexture(ComputeTextureUnit unit, Graphics4::RenderTarget *target) {} | ||
|  | 
 | ||
|  | void Compute::setTextureAddressing(ComputeTextureUnit unit, Graphics4::TexDir dir, Graphics4::TextureAddressing addressing) {} | ||
|  | 
 | ||
|  | void Compute::setTexture3DAddressing(ComputeTextureUnit unit, Graphics4::TexDir dir, Graphics4::TextureAddressing addressing) {} | ||
|  | 
 | ||
|  | void Compute::setTextureMagnificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {} | ||
|  | 
 | ||
|  | void Compute::setTexture3DMagnificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {} | ||
|  | 
 | ||
|  | void Compute::setTextureMinificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {} | ||
|  | 
 | ||
|  | void Compute::setTexture3DMinificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {} | ||
|  | 
 | ||
|  | void Compute::setTextureMipmapFilter(ComputeTextureUnit unit, Graphics4::MipmapFilter filter) {} | ||
|  | 
 | ||
|  | void Compute::setTexture3DMipmapFilter(ComputeTextureUnit unit, Graphics4::MipmapFilter filter) {} | ||
|  | 
 | ||
|  | void Compute::setShader(ComputeShader *shader) { | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	glUseProgram(shader->_programid); | ||
|  | 	glCheckErrors2(); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void Compute::compute(int x, int y, int z) { | ||
|  | #ifdef HAS_COMPUTE
 | ||
|  | 	glDispatchCompute(x, y, z); | ||
|  | 	glCheckErrors2(); | ||
|  | 	glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); | ||
|  | 	glCheckErrors2(); | ||
|  | 	glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); | ||
|  | 	glCheckErrors2(); | ||
|  | #endif
 | ||
|  | } |