mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-10 19:08:39 +00:00
image header optimizations
This commit is contained in:
parent
5d7943016d
commit
d983df0158
|
|
@ -238,12 +238,14 @@ Asset* asset_archive_asset_load(const AssetArchive* archive, int32 id, AssetMana
|
|||
// @todo implement qoi encoding
|
||||
image_from_data(file.content, &texture->image);
|
||||
|
||||
asset->vram_size = texture->image.pixel_count * image_pixel_size_from_type(texture->image.pixel_type);
|
||||
asset->vram_size = texture->image.pixel_count * image_pixel_size_from_type(texture->image.image_settings);
|
||||
asset->ram_size = asset->vram_size + sizeof(Texture);
|
||||
|
||||
#if OPENGL
|
||||
image_flip_vertical(ring, &texture->image);
|
||||
texture->image.order_rows = IMAGE_ROW_ORDER_BOTTOM_TO_TOP;
|
||||
// If opengl, we always flip
|
||||
if (!(texture->image.image_settings & IMAGE_SETTING_BOTTOM_TO_TOP)) {
|
||||
image_flip_vertical(ring, &texture->image);
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
case ASSET_TYPE_AUDIO: {
|
||||
|
|
|
|||
|
|
@ -38,10 +38,8 @@ int32 audio_data_size(const Audio* audio)
|
|||
{
|
||||
return (int32) (audio->size
|
||||
+ sizeof(audio->sample_rate)
|
||||
+ sizeof(audio->sample_size)
|
||||
+ sizeof(audio->channels)
|
||||
+ sizeof(audio->bloc_size)
|
||||
+ sizeof(audio->byte_per_sec)
|
||||
+ sizeof(audio->size)
|
||||
);
|
||||
}
|
||||
|
|
@ -51,17 +49,13 @@ int32 audio_from_data(const byte* data, Audio* audio)
|
|||
audio->sample_rate = SWAP_ENDIAN_LITTLE(*((uint16 *) data));
|
||||
data += sizeof(audio->sample_rate);
|
||||
|
||||
audio->sample_size = *data;
|
||||
data += sizeof(audio->sample_size);
|
||||
audio->channels = (*data >> 4) & 0x0F;
|
||||
audio->bloc_size = *data & 0x0F;
|
||||
data += sizeof(byte);
|
||||
|
||||
audio->channels = *data;
|
||||
data += sizeof(audio->channels);
|
||||
audio->sample_size = audio->channels * audio->bloc_size;
|
||||
|
||||
audio->bloc_size = *data;
|
||||
data += sizeof(audio->bloc_size);
|
||||
|
||||
audio->byte_per_sec = SWAP_ENDIAN_LITTLE(*((uint32 *) data));
|
||||
data += sizeof(audio->byte_per_sec);
|
||||
audio->byte_per_sec = audio->sample_rate * audio->sample_size;
|
||||
|
||||
audio->size = SWAP_ENDIAN_LITTLE(*((uint32 *) data));
|
||||
data += sizeof(audio->size);
|
||||
|
|
@ -77,17 +71,9 @@ int32 audio_to_data(const Audio* audio, byte* data)
|
|||
*((uint16 *) data) = SWAP_ENDIAN_LITTLE(audio->sample_rate);
|
||||
data += sizeof(audio->sample_rate);
|
||||
|
||||
*data = audio->sample_size;
|
||||
data += sizeof(audio->sample_size);
|
||||
|
||||
*data = audio->channels;
|
||||
data += sizeof(audio->channels);
|
||||
|
||||
*data = audio->bloc_size;
|
||||
data += sizeof(audio->bloc_size);
|
||||
|
||||
*((uint32 *) data) = SWAP_ENDIAN_LITTLE(audio->byte_per_sec);
|
||||
data += sizeof(audio->byte_per_sec);
|
||||
// Reducing data footprint through bit fiddling
|
||||
*data = ((audio->channels & 0x0F) << 4) | (audio->bloc_size & 0x0F);
|
||||
data += sizeof(byte);
|
||||
|
||||
*((uint32 *) data) = SWAP_ENDIAN_LITTLE(audio->size);
|
||||
data += sizeof(audio->size);
|
||||
|
|
|
|||
|
|
@ -17,11 +17,6 @@ struct Audio {
|
|||
// usually 48000 or 44100
|
||||
uint16 sample_rate;
|
||||
|
||||
// bytes per bloc
|
||||
// channel count * bit
|
||||
// usually 2 * 16 = 4
|
||||
byte sample_size;
|
||||
|
||||
// audio channels
|
||||
// usually 2
|
||||
byte channels;
|
||||
|
|
@ -29,6 +24,12 @@ struct Audio {
|
|||
// usually 16 = 2
|
||||
byte bloc_size;
|
||||
|
||||
// bytes per bloc
|
||||
// channel count * bit
|
||||
// usually 2 * 16 = 4
|
||||
// channels * bloc_size
|
||||
byte sample_size;
|
||||
|
||||
// sample_rate * sample_size
|
||||
uint32 byte_per_sec;
|
||||
|
||||
|
|
|
|||
57
gpuapi/direct3d/ShaderUtils.h
Normal file
57
gpuapi/direct3d/ShaderUtils.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_GPUAPI_DIRECTX_SHADER_UTILS_H
|
||||
#define TOS_GPUAPI_DIRECTX_SHADER_UTILS_H
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../memory/RingMemory.h"
|
||||
#include "../../log/Log.h"
|
||||
|
||||
D3D12_SHADER_BYTECODE shader_make(ID3D12Device* device, const char* source, int32 source_size, RingMemory* ring)
|
||||
{
|
||||
// Create the shader object (bytecode)
|
||||
D3D12_SHADER_BYTECODE shaderBytecodeDesc = {};
|
||||
shaderBytecodeDesc.pShaderBytecode = source;
|
||||
shaderBytecodeDesc.BytecodeLength = source_size;
|
||||
|
||||
return shaderBytecodeDesc;
|
||||
}
|
||||
|
||||
ID3D12PipelineState* program_make(
|
||||
ID3D12Device* device,
|
||||
D3D12_SHADER_BYTECODE vertex_shader,
|
||||
D3D12_SHADER_BYTECODE fragment_shader,
|
||||
D3D12_SHADER_BYTECODE geometry_shader
|
||||
) {
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
|
||||
psoDesc.VS = vertex_shader;
|
||||
psoDesc.PS = fragment_shader;
|
||||
psoDesc.GS = geometry_shader;
|
||||
|
||||
ID3D12PipelineState* pipelineState = NULL;
|
||||
HRESULT hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
LOG("Failed to create program", true, true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pipelineState;
|
||||
}
|
||||
|
||||
inline
|
||||
void pipeline_use(ID3D12GraphicsCommandList* command_list, ID3D12PipelineState* pipelineState)
|
||||
{
|
||||
command_list->SetPipelineState(pipelineState);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -138,7 +138,7 @@ void load_texture_to_gpu(const Texture* texture, int32 mipmap_level = 0)
|
|||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
LOG_INCREMENT_BY(DEBUG_COUNTER_GPU_UPLOAD, texture->image.pixel_count * image_pixel_size_from_type(texture->image.pixel_type));
|
||||
LOG_INCREMENT_BY(DEBUG_COUNTER_GPU_UPLOAD, texture->image.pixel_count * image_pixel_size_from_type(texture->image.image_settings));
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -156,135 +156,6 @@ void texture_use_1D(const Texture* texture, uint32 texture_unit)
|
|||
glBindTexture(GL_TEXTURE_1D, (GLuint) texture->id);
|
||||
}
|
||||
|
||||
GLuint shader_make(GLenum type, const char* source, RingMemory* ring)
|
||||
{
|
||||
GLuint shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, (GLchar **) &source, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
|
||||
#if DEBUG || INTERNAL
|
||||
if (status == GL_FALSE) {
|
||||
GLint length;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
|
||||
|
||||
glGetShaderInfoLog(shader, length, NULL, info);
|
||||
LOG(info, true, true);
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
inline
|
||||
GLuint shader_load(GLenum type, const char* path, RingMemory* ring) {
|
||||
byte* temp = ring->head;
|
||||
|
||||
FileBody file;
|
||||
|
||||
// @todo consider to accept file as parameter and load file before
|
||||
file_read(path, &file, ring);
|
||||
GLuint result = shader_make(type, (const char *) file.content, ring);
|
||||
|
||||
// We can immediately dispose of it we can also reset our ring memory position
|
||||
ring->head = temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
int32 program_get_size(uint32 program)
|
||||
{
|
||||
int32 size;
|
||||
glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
GLuint program_make(
|
||||
GLuint vertex_shader,
|
||||
GLuint fragment_shader,
|
||||
GLint geometry_shader,
|
||||
RingMemory* ring
|
||||
) {
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
if (geometry_shader > -1) {
|
||||
glAttachShader(program, geometry_shader);
|
||||
}
|
||||
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
|
||||
#if DEBUG || INTERNAL
|
||||
if (status == GL_FALSE) {
|
||||
GLint length;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
|
||||
|
||||
glGetProgramInfoLog(program, length, NULL, info);
|
||||
LOG(info, true, true);
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
// @question really?
|
||||
if (geometry_shader > -1) {
|
||||
glDetachShader(program, geometry_shader);
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
|
||||
// @question really?
|
||||
if (geometry_shader > -1) {
|
||||
glDeleteShader(geometry_shader);
|
||||
}
|
||||
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
GLuint program_load(
|
||||
const char* path1,
|
||||
const char* path2,
|
||||
const char* path3,
|
||||
RingMemory* ring
|
||||
) {
|
||||
GLuint vertex_shader = shader_load(GL_VERTEX_SHADER, path1, ring);
|
||||
GLuint fragment_shader = shader_load(GL_FRAGMENT_SHADER, path2, ring);
|
||||
|
||||
GLint geometry_shader = -1;
|
||||
if (path3) {
|
||||
geometry_shader = shader_load(GL_GEOMETRY_SHADER, path3, ring);
|
||||
}
|
||||
|
||||
GLuint program = program_make(vertex_shader, fragment_shader, geometry_shader, ring);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
inline
|
||||
void shader_use(uint32 id)
|
||||
{
|
||||
glUseProgram(id);
|
||||
}
|
||||
|
||||
inline
|
||||
void draw_triangles_3d(VertexRef* vertices, GLuint buffer, int32 count) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
#define TOS_GPUAPI_OPENGL_SHADER_UTILS_H
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../math/matrix/MatrixFloat32.h"
|
||||
#include "../../memory/RingMemory.h"
|
||||
#include "../../log/Log.h"
|
||||
#include "Opengl.h"
|
||||
|
||||
// Set value based on shader uniform name
|
||||
|
|
@ -244,4 +245,98 @@ int32 shader_program_optimize(const char* input, char* output)
|
|||
return (int32) (write_ptr - output);
|
||||
}
|
||||
|
||||
GLuint shader_make(GLenum type, const char* source, RingMemory* ring)
|
||||
{
|
||||
GLuint shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, (GLchar **) &source, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
|
||||
#if DEBUG || INTERNAL
|
||||
if (status == GL_FALSE) {
|
||||
GLint length;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
|
||||
|
||||
glGetShaderInfoLog(shader, length, NULL, info);
|
||||
LOG(info, true, true);
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
inline
|
||||
int32 program_get_size(uint32 program)
|
||||
{
|
||||
int32 size;
|
||||
glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
GLuint program_make(
|
||||
GLuint vertex_shader,
|
||||
GLuint fragment_shader,
|
||||
GLint geometry_shader,
|
||||
RingMemory* ring
|
||||
) {
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
if (geometry_shader > -1) {
|
||||
glAttachShader(program, geometry_shader);
|
||||
}
|
||||
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
|
||||
#if DEBUG || INTERNAL
|
||||
if (status == GL_FALSE) {
|
||||
GLint length;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
|
||||
|
||||
glGetProgramInfoLog(program, length, NULL, info);
|
||||
LOG(info, true, true);
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
// @question really?
|
||||
if (geometry_shader > -1) {
|
||||
glDetachShader(program, geometry_shader);
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
|
||||
// @question really?
|
||||
if (geometry_shader > -1) {
|
||||
glDeleteShader(geometry_shader);
|
||||
}
|
||||
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
inline
|
||||
void pipeline_use(uint32 id)
|
||||
{
|
||||
glUseProgram(id);
|
||||
}
|
||||
|
||||
#endif
|
||||
143
gpuapi/vulkan/ShaderUtils.h
Normal file
143
gpuapi/vulkan/ShaderUtils.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_GPUAPI_VULKAN_SHADER_UTILS_H
|
||||
#define TOS_GPUAPI_VULKAN_SHADER_UTILS_H
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../memory/RingMemory.h"
|
||||
#include "../../log/Log.h"
|
||||
|
||||
inline uint32_t shader_get_uniform_location(VkWriteDescriptorSet* descriptor, VkDevice device, VkCommandBuffer commandBuffer, VkDescriptorSet descriptorSet, uint32_t binding, VkDescriptorType descriptorType)
|
||||
{
|
||||
VkWriteDescriptorSet descriptorWrite = {};
|
||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrite.dstSet = descriptorSet;
|
||||
descriptorWrite.dstBinding = binding;
|
||||
descriptorWrite.dstArrayElement = 0;
|
||||
descriptorWrite.descriptorType = descriptorType;
|
||||
descriptorWrite.descriptorCount = 1;
|
||||
descriptorWrite.pBufferInfo->buffer = 0;
|
||||
descriptorWrite.pBufferInfo->offset = 0;
|
||||
}
|
||||
|
||||
inline void shader_set_value(VkDevice device, VkCommandBuffer commandBuffer, VkDescriptorSet descriptorSet, uint32_t binding, VkDescriptorType descriptorType, int32_t value)
|
||||
{
|
||||
VkDescriptorBufferInfo bufferInfo = {};
|
||||
bufferInfo.buffer = {}; // You should have a buffer holding the value
|
||||
bufferInfo.offset = 0;
|
||||
bufferInfo.range = sizeof(value);
|
||||
|
||||
VkWriteDescriptorSet descriptorWrite = {};
|
||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrite.dstSet = descriptorSet;
|
||||
descriptorWrite.dstBinding = binding;
|
||||
descriptorWrite.dstArrayElement = 0;
|
||||
descriptorWrite.descriptorType = descriptorType;
|
||||
descriptorWrite.descriptorCount = 1;
|
||||
descriptorWrite.pBufferInfo = &bufferInfo;
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
||||
}
|
||||
|
||||
VkShaderModule shader_make(VkDevice device, const char* source, int32 source_size, RingMemory* ring)
|
||||
{
|
||||
// Create shader module create info
|
||||
VkShaderModuleCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
createInfo.codeSize = source_size;
|
||||
createInfo.pCode = (uint32 *) source;
|
||||
|
||||
// Create shader module
|
||||
VkShaderModule shaderModule;
|
||||
VkResult result = vkCreateShaderModule(device, &createInfo, NULL, &shaderModule);
|
||||
|
||||
if (result != VK_SUCCESS) {
|
||||
LOG("Failed to create shader module", true, true);
|
||||
ASSERT_SIMPLE(false);
|
||||
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
return shaderModule;
|
||||
}
|
||||
|
||||
VkPipeline program_make(
|
||||
VkDevice device,
|
||||
VkShaderModule vertex_shader,
|
||||
VkShaderModule fragment_shader,
|
||||
VkShaderModule geometry_shader,
|
||||
VkPipelineLayout pipeline_layout,
|
||||
VkRenderPass render_pass,
|
||||
RingMemory* ring
|
||||
) {
|
||||
VkPipelineShaderStageCreateInfo shaderStages[3];
|
||||
|
||||
// Vertex shader
|
||||
shaderStages[0] = {};
|
||||
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
shaderStages[0].module = vertex_shader;
|
||||
shaderStages[0].pName = "main";
|
||||
|
||||
// Fragment shader
|
||||
shaderStages[1] = {};
|
||||
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
shaderStages[1].module = fragment_shader;
|
||||
shaderStages[1].pName = "main";
|
||||
|
||||
VkPipelineShaderStageCreateInfo* geometryShaderStage = NULL;
|
||||
|
||||
// Optional Geometry shader
|
||||
if (geometry_shader != VK_NULL_HANDLE) {
|
||||
geometryShaderStage = &shaderStages[2];
|
||||
geometryShaderStage->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
geometryShaderStage->stage = VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
geometryShaderStage->module = geometry_shader;
|
||||
geometryShaderStage->pName = "main";
|
||||
}
|
||||
|
||||
// Create the pipeline
|
||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo = {};
|
||||
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
pipelineCreateInfo.stageCount = (geometry_shader != VK_NULL_HANDLE) ? 3 : 2;
|
||||
pipelineCreateInfo.pStages = shaderStages;
|
||||
pipelineCreateInfo.pInputAssemblyState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pVertexInputState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pViewportState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pRasterizationState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pMultisampleState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pDepthStencilState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pColorBlendState = NULL; // Define if needed
|
||||
pipelineCreateInfo.pDynamicState = NULL; // Define if needed
|
||||
pipelineCreateInfo.layout = pipeline_layout;
|
||||
pipelineCreateInfo.renderPass = render_pass;
|
||||
pipelineCreateInfo.subpass = 0; // Assumes 0 subpass
|
||||
pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
|
||||
VkPipeline graphicsPipeline;
|
||||
VkResult result = vkCreateGraphicsPipeline(device, VK_NULL_HANDLE, &pipelineCreateInfo, NULL, &graphicsPipeline);
|
||||
|
||||
if (result != VK_SUCCESS) {
|
||||
LOG("Failed to create program", true, true);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
return graphicsPipeline;
|
||||
}
|
||||
|
||||
inline
|
||||
void pipeline_use(VkCommandBuffer command_list, VkPipeline pipeline)
|
||||
{
|
||||
vkCmdBindPipeline(command_list, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -285,16 +285,12 @@ void image_bmp_generate(const FileBody* src_data, Image* image)
|
|||
uint32 pixel_bytes = src.dib_header.bits_per_pixel / 8;
|
||||
byte alpha_offset = pixel_bytes > 3;
|
||||
|
||||
if (pixel_bytes == 4) {
|
||||
image->pixel_type = (byte) PIXEL_TYPE_RGBA;
|
||||
} else if (pixel_bytes == 3) {
|
||||
image->pixel_type = (byte) PIXEL_TYPE_RGB;
|
||||
} else {
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
image->image_settings |= (image->image_settings & IMAGE_SETTING_CHANNEL_COUNT) == 0
|
||||
? pixel_bytes
|
||||
: image->image_settings & IMAGE_SETTING_CHANNEL_COUNT;
|
||||
|
||||
if (image->order_pixels == IMAGE_PIXEL_ORDER_BGRA
|
||||
&& image->order_rows == IMAGE_ROW_ORDER_BOTTOM_TO_TOP
|
||||
if ((image->image_settings & IMAGE_SETTING_PIXEL_BGR)
|
||||
&& (image->image_settings & IMAGE_SETTING_BOTTOM_TO_TOP)
|
||||
) {
|
||||
// @bug This doesn't consider the situation where we want alpha as a setting but the img doesn't have it
|
||||
// @bug This also copies possible padding which will corrupt the image
|
||||
|
|
@ -308,13 +304,9 @@ void image_bmp_generate(const FileBody* src_data, Image* image)
|
|||
|
||||
for (uint32 y = 0; y < src.dib_header.height; ++y) {
|
||||
uint32 row_pos1 = y * width_pixel_bytes;
|
||||
|
||||
uint32 row_pos2;
|
||||
if (image->order_rows == IMAGE_ROW_ORDER_TOP_TO_BOTTOM) {
|
||||
row_pos2 = (src.dib_header.height - y - 1) * width_pixel_bytes;
|
||||
} else {
|
||||
row_pos2 = y * width_pixel_bytes;
|
||||
}
|
||||
uint32 row_pos2 = image->image_settings & IMAGE_SETTING_BOTTOM_TO_TOP
|
||||
? y * width_pixel_bytes
|
||||
: (src.dib_header.height - y - 1) * width_pixel_bytes;
|
||||
|
||||
for (uint32 x = 0; x < width; ++x) {
|
||||
if (x >= image->width) {
|
||||
|
|
@ -324,20 +316,20 @@ void image_bmp_generate(const FileBody* src_data, Image* image)
|
|||
}
|
||||
|
||||
// Invert byte order
|
||||
if (image->order_pixels == IMAGE_PIXEL_ORDER_RGBA) {
|
||||
for (uint32 i = 0; i < pixel_rgb_bytes; ++i) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + i] = src.pixels[row_pos2 + x * pixel_bytes + pixel_rgb_bytes - i];
|
||||
}
|
||||
} else {
|
||||
if (image->image_settings & IMAGE_SETTING_PIXEL_BGR) {
|
||||
for (uint32 i = 0; i < pixel_rgb_bytes; ++i) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + i] = src.pixels[row_pos2 + x * pixel_bytes + i];
|
||||
}
|
||||
} else {
|
||||
for (uint32 i = 0; i < pixel_rgb_bytes; ++i) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + i] = src.pixels[row_pos2 + x * pixel_bytes + pixel_rgb_bytes - i];
|
||||
}
|
||||
}
|
||||
|
||||
// Add alpha channel at end of every RGB value
|
||||
// Add alpha channel at end of every RGB value (either the image already contains it or we have to add it manually)
|
||||
if (alpha_offset > 0) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + 3] = src.pixels[row_pos2 + x * pixel_bytes + pixel_bytes + 3];
|
||||
} else if (image->pixel_type == PIXEL_TYPE_RGBA) {
|
||||
} else if ((image->image_settings & IMAGE_SETTING_CHANNEL_COUNT) == 4) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + 3] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,35 +61,16 @@ void image_flip_vertical(RingMemory* ring, Image* image)
|
|||
}
|
||||
*/
|
||||
|
||||
image->order_rows = (byte) (!((bool) image->order_rows));
|
||||
image->image_settings ^= IMAGE_SETTING_BOTTOM_TO_TOP;
|
||||
}
|
||||
|
||||
inline
|
||||
int32 image_pixel_size_from_type(byte type)
|
||||
{
|
||||
switch (type) {
|
||||
case PIXEL_TYPE_RGBA: {
|
||||
return 4;
|
||||
} break;
|
||||
case PIXEL_TYPE_RGB: {
|
||||
return 3;
|
||||
} break;
|
||||
case PIXEL_TYPE_MONO: {
|
||||
return 1;
|
||||
} break;
|
||||
case PIXEL_TYPE_RGBA_F: {
|
||||
return 16;
|
||||
} break;
|
||||
case PIXEL_TYPE_RGB_F: {
|
||||
return 12;
|
||||
} break;
|
||||
case PIXEL_TYPE_MONO_F: {
|
||||
return 4;
|
||||
} break;
|
||||
default: {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
int32 channel_size = type & IMAGE_SETTING_CHANNEL_4_SIZE ? 4 : 1;
|
||||
int32 channel_count = type & IMAGE_SETTING_CHANNEL_COUNT;
|
||||
|
||||
return channel_size * channel_count;
|
||||
}
|
||||
|
||||
int32 image_from_data(const byte* data, Image* image)
|
||||
|
|
@ -102,20 +83,13 @@ int32 image_from_data(const byte* data, Image* image)
|
|||
image->height = SWAP_ENDIAN_LITTLE(*((uint32 *) pos));
|
||||
pos += sizeof(image->height);
|
||||
|
||||
image->pixel_count = SWAP_ENDIAN_LITTLE(*((uint32 *) pos));
|
||||
pos += sizeof(image->pixel_count);
|
||||
image->pixel_count = image->width * image->height;
|
||||
|
||||
image->order_pixels = *pos;
|
||||
pos += sizeof(image->order_pixels);
|
||||
|
||||
image->order_rows = *pos;
|
||||
pos += sizeof(image->order_rows);
|
||||
|
||||
image->pixel_type = *pos;
|
||||
pos += sizeof(image->pixel_type);
|
||||
image->image_settings = *pos;
|
||||
pos += sizeof(image->image_settings);
|
||||
|
||||
int32 image_size;
|
||||
memcpy(image->pixels, pos, image_size = (image_pixel_size_from_type(image->pixel_type) * image->pixel_count));
|
||||
memcpy(image->pixels, pos, image_size = (image_pixel_size_from_type(image->image_settings) * image->pixel_count));
|
||||
pos += image_size;
|
||||
|
||||
return (int32) (pos - data);
|
||||
|
|
@ -131,20 +105,11 @@ int32 image_to_data(const Image* image, byte* data)
|
|||
*((uint32 *) pos) = SWAP_ENDIAN_LITTLE(image->height);
|
||||
pos += sizeof(image->height);
|
||||
|
||||
*((uint32 *) pos) = SWAP_ENDIAN_LITTLE(image->pixel_count);
|
||||
pos += sizeof(image->pixel_count);
|
||||
|
||||
*pos = image->order_pixels;
|
||||
pos += sizeof(image->order_pixels);
|
||||
|
||||
*pos = image->order_rows;
|
||||
pos += sizeof(image->order_rows);
|
||||
|
||||
*pos = image->pixel_type;
|
||||
pos += sizeof(image->pixel_type);
|
||||
*pos = image->image_settings;
|
||||
pos += sizeof(image->image_settings);
|
||||
|
||||
int32 image_size;
|
||||
memcpy(pos, image->pixels, image_size = (image_pixel_size_from_type(image->pixel_type) * image->pixel_count));
|
||||
memcpy(pos, image->pixels, image_size = (image_pixel_size_from_type(image->image_settings) * image->pixel_count));
|
||||
pos += image_size;
|
||||
|
||||
return (int32) (pos - data);
|
||||
|
|
|
|||
|
|
@ -11,21 +11,11 @@
|
|||
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
#define IMAGE_PIXEL_ORDER_RGBA 0
|
||||
#define IMAGE_PIXEL_ORDER_BGRA 1
|
||||
|
||||
#define IMAGE_ROW_ORDER_TOP_TO_BOTTOM 0
|
||||
#define IMAGE_ROW_ORDER_BOTTOM_TO_TOP 1
|
||||
|
||||
enum PixelType
|
||||
{
|
||||
PIXEL_TYPE_RGBA, // 4 bytes
|
||||
PIXEL_TYPE_RGB, // 3 bytes
|
||||
PIXEL_TYPE_MONO, // 1 byte
|
||||
PIXEL_TYPE_RGBA_F, // 16 bytes
|
||||
PIXEL_TYPE_RGB_F, // 12 bytes
|
||||
PIXEL_TYPE_MONO_F, // 4 bytes
|
||||
};
|
||||
#define IMAGE_SETTING_PIXEL_BGR 0b10000000 // 0 = rgba, 1 = bgra
|
||||
#define IMAGE_SETTING_BOTTOM_TO_TOP 0b01000000 // 0 = ttb, 1 = btt
|
||||
#define IMAGE_SETTING_COLOR_MODE_SRGB 0b00100000 // 0 = rgb, 1 = srgb
|
||||
#define IMAGE_SETTING_CHANNEL_4_SIZE 0b00010000 // 0 = 1 byte, 1 = 4 byte (usually float)
|
||||
#define IMAGE_SETTING_CHANNEL_COUNT 0b00001111
|
||||
|
||||
// This struct also functions as a setting on how to load the image data
|
||||
// has_alpha is defined it forces an alpha channel even for bitmaps
|
||||
|
|
@ -35,12 +25,9 @@ enum PixelType
|
|||
struct Image {
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 pixel_count; // @question Do we even need this?
|
||||
uint32 pixel_count;
|
||||
|
||||
// Image settings
|
||||
byte order_pixels; // RGBA vs BGRA
|
||||
byte order_rows; // top-to-bottom vs bottom-to-top
|
||||
byte pixel_type; // Usually 4 or 3 bytes unless monochrome data
|
||||
byte image_settings;
|
||||
|
||||
byte* pixels; // owner of data
|
||||
};
|
||||
|
|
|
|||
|
|
@ -783,9 +783,7 @@ bool image_png_generate(const FileBody* src_data, Image* image, RingMemory* ring
|
|||
image->width = src.ihdr.width;
|
||||
image->height = src.ihdr.height;
|
||||
image->pixel_count = image->width * image->height;
|
||||
image->pixel_type = (byte) (src.ihdr.color_type == 6 ? PIXEL_TYPE_RGBA : PIXEL_TYPE_RGB);
|
||||
image->order_pixels = IMAGE_PIXEL_ORDER_RGBA;
|
||||
image->order_rows = IMAGE_ROW_ORDER_TOP_TO_BOTTOM;
|
||||
image->image_settings |= src.ihdr.color_type == 6 ? 4 : 3;
|
||||
|
||||
png_filter_reconstruct(src.ihdr.width, src.ihdr.height, src.ihdr.color_type, decompressed, finalized, steps);
|
||||
|
||||
|
|
|
|||
12
image/Qoi.h
12
image/Qoi.h
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
#include "Image.h"
|
||||
|
||||
#define QOI_OP_INDEX 0b00000000
|
||||
#define QOI_OP_DIFF 0b01000000
|
||||
|
|
@ -37,14 +38,7 @@ uint32 qoi_encode_size(QoiDescription* desc)
|
|||
return desc->width * desc->height * (desc->channels + 1) + QOI_HEADER_SIZE;
|
||||
}
|
||||
|
||||
int32 qoi_encode(const byte* data, byte* output, const QoiDescription* desc) {
|
||||
if (desc->width == 0 || desc->height == 0 ||
|
||||
desc->channels < 3 || desc->channels > 4 ||
|
||||
desc->colorspace > 1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32 qoi_encode(const Image* image, byte* output) {
|
||||
int32 p = 0;
|
||||
*((uint32 *) output[p]) = SWAP_ENDIAN_LITTLE(desc->width); p += 4;
|
||||
*((uint32 *) output[p]) = SWAP_ENDIAN_LITTLE(desc->height); p += 4;
|
||||
|
|
@ -130,7 +124,7 @@ uint32 qoi_decode_size(QoiDescription* desc, int32 channels)
|
|||
return desc->width * desc->height * channels;
|
||||
}
|
||||
|
||||
void qoi_decode(const byte* data, byte* output, int32 steps = 8)
|
||||
void qoi_decode(const byte* data, Image* image, int32 steps = 8)
|
||||
{
|
||||
int32 p = 0;
|
||||
uint32 width = SWAP_ENDIAN_LITTLE(*((uint32 *) &data[p])); p += 4;
|
||||
|
|
|
|||
32
image/Tga.h
32
image/Tga.h
|
|
@ -90,17 +90,13 @@ void image_tga_generate(const FileBody* src_data, Image* image)
|
|||
uint32 pixel_bytes = src.header.bits_per_pixel / 8;
|
||||
byte alpha_offset = pixel_bytes > 3;
|
||||
|
||||
if (pixel_bytes == 4) {
|
||||
image->pixel_type = (byte) PIXEL_TYPE_RGBA;
|
||||
} else if (pixel_bytes == 3) {
|
||||
image->pixel_type = (byte) PIXEL_TYPE_RGB;
|
||||
} else {
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
image->image_settings |= (image->image_settings & IMAGE_SETTING_CHANNEL_COUNT) == 0
|
||||
? pixel_bytes
|
||||
: image->image_settings & IMAGE_SETTING_CHANNEL_COUNT;
|
||||
|
||||
// We can check same settings through equality since we use the same values
|
||||
if (image->order_rows == src.header.vertical_ordering
|
||||
&& image->order_pixels == src.header.horizonal_ordering
|
||||
if ((image->image_settings & IMAGE_SETTING_BOTTOM_TO_TOP) == src.header.vertical_ordering
|
||||
&& src.header.horizonal_ordering == 0
|
||||
) {
|
||||
// @bug This doesn't consider the situation where we want alpha as a setting but the img doesn't have it
|
||||
memcpy((void *) image->pixels, src.pixels, image->pixel_count * pixel_bytes);
|
||||
|
|
@ -113,18 +109,12 @@ void image_tga_generate(const FileBody* src_data, Image* image)
|
|||
|
||||
for (uint32 y = 0; y < src.header.height; ++y) {
|
||||
uint32 row_pos1 = y * image->width * pixel_bytes;
|
||||
|
||||
uint32 row_pos2;
|
||||
if ((image->order_rows == IMAGE_ROW_ORDER_TOP_TO_BOTTOM && src.header.vertical_ordering == 1)
|
||||
|| (image->order_rows == IMAGE_ROW_ORDER_BOTTOM_TO_TOP && src.header.vertical_ordering == 0)
|
||||
) {
|
||||
row_pos2 = (src.header.height - y - 1) * image->width * pixel_bytes;
|
||||
} else {
|
||||
row_pos2 = y * width_pixel_bytes;
|
||||
}
|
||||
uint32 row_pos2 = (image->image_settings & IMAGE_SETTING_BOTTOM_TO_TOP) == src.header.vertical_ordering
|
||||
? y * width_pixel_bytes
|
||||
: (src.header.height - y - 1) * image->width * pixel_bytes;
|
||||
|
||||
for (uint32 x = 0; x < src.header.width; ++x) {
|
||||
if (image->order_pixels == src.header.horizonal_ordering) {
|
||||
if (src.header.horizonal_ordering == 0) {
|
||||
for (uint32 i = 0; i < pixel_rgb_bytes; ++i) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + i] = src.pixels[row_pos2 + x * pixel_bytes + i];
|
||||
}
|
||||
|
|
@ -134,10 +124,10 @@ void image_tga_generate(const FileBody* src_data, Image* image)
|
|||
}
|
||||
}
|
||||
|
||||
// Add alpha channel at end of every RGB value
|
||||
// Add alpha channel at end of every RGB value (either the image already contains it or we have to add it manually)
|
||||
if (alpha_offset > 0) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + 3] = src.pixels[row_pos2 + x * pixel_bytes + pixel_bytes + 3];
|
||||
} else if (image->pixel_type == PIXEL_TYPE_RGBA) {
|
||||
} else if ((image->image_settings & IMAGE_SETTING_CHANNEL_COUNT) == 4) {
|
||||
image->pixels[row_pos1 + x * pixel_bytes + 3] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
55
platform/win32/LeanWin32.h
Normal file
55
platform/win32/LeanWin32.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_LEAN_H
|
||||
#define TOS_PLATFORM_WIN32_LEAN_H
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#define NOGDICAPMASKS 1
|
||||
#define NOVIRTUALKEYCODES 1
|
||||
#define NOWINMESSAGES 1
|
||||
#define NOWINSTYLES 1
|
||||
#define NOSYSMETRICS 1
|
||||
#define NOMENUS 1
|
||||
#define NOICONS 1
|
||||
#define NOKEYSTATES 1
|
||||
#define NOSYSCOMMANDS 1
|
||||
#define NORASTEROPS 1
|
||||
#define NOSHOWWINDOW 1
|
||||
#define OEMRESOURCE 1
|
||||
#define NOATOM 1
|
||||
#define NOCLIPBOARD 1
|
||||
#define NOCOLOR 1
|
||||
#define NOCTLMGR 1
|
||||
#define NODRAWTEXT 1
|
||||
#define NOGDI 1
|
||||
#define NOKERNEL 1
|
||||
#define NOUSER 1
|
||||
#define NONLS 1
|
||||
#define NOMB 1
|
||||
#define NOMEMMGR 1
|
||||
#define NOMETAFILE 1
|
||||
#define NOMINMAX 1
|
||||
#define NOMSG 1
|
||||
#define NOOPENFILE 1
|
||||
#define NOSCROLL 1
|
||||
#define NOSERVICE 1
|
||||
#define NOSOUND 1
|
||||
#define NOTEXTMETRIC 1
|
||||
#define NOWH 1
|
||||
#define NOWINOFFSETS 1
|
||||
#define NOCOMM 1
|
||||
#define NOKANJI 1
|
||||
#define NOHELP 1
|
||||
#define NOPROFILER 1
|
||||
#define NODEFERWINDOWPOS 1
|
||||
#define NOMCX 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
// This file can remain but the callers should get adjusted
|
||||
// Obviously we would have to check at runtime if ABM is supported
|
||||
|
||||
// Left to right
|
||||
// Left to right (big endian)
|
||||
#define IS_BIT_SET_L2R(num, pos, bits) ((bool) ((num) & (1 << ((bits - 1) - (pos)))))
|
||||
#define BIT_SET_L2R(num, pos, bits) ((num) | ((uint32) 1 << ((bits - 1) - (pos))))
|
||||
#define BIT_UNSET_L2R(num, pos, bits) ((num) & ~((uint32) 1 << ((bits - 1) - (pos))))
|
||||
|
|
@ -27,11 +27,13 @@
|
|||
#define BITS_GET_32_L2R(num, pos, to_read) (((num) >> (32 - (pos) - (to_read))) & ((1U << (to_read)) - 1))
|
||||
#define BITS_GET_64_L2R(num, pos, to_read) (((num) >> (64 - (pos) - (to_read))) & ((1ULL << (to_read)) - 1))
|
||||
|
||||
#define BYTES_MERGE_2_L2R(num) (((num)[0] << 8) | (num)[1])
|
||||
#define BYTES_MERGE_4_L2R(num) (((num)[0] << 24) | ((num)[1] << 16) | ((num)[2] << 8) | (num)[3])
|
||||
#define BYTES_MERGE_8_L2R(num) (((uint64_t)(num)[0] << 56) | ((uint64_t)(num)[1] << 48) | ((uint64_t)(num)[2] << 40) | ((uint64_t)(num)[3] << 32) | ((uint64_t)(num)[4] << 24) | ((uint64_t)(num)[5] << 16) | ((uint64_t)(num)[6] << 8) | ((uint64_t)(num)[7]))
|
||||
// Merges an array of bytes as an int value (16bit, 32bit, 64bit)
|
||||
// Depending on the endianness of the system you could simply cast the array
|
||||
#define BYTES_MERGE_2_L2R(arr) (((arr)[0] << 8) | (arr)[1])
|
||||
#define BYTES_MERGE_4_L2R(arr) (((arr)[0] << 24) | ((arr)[1] << 16) | ((arr)[2] << 8) | (arr)[3])
|
||||
#define BYTES_MERGE_8_L2R(arr) (((uint64_t)(arr)[0] << 56) | ((uint64_t)(arr)[1] << 48) | ((uint64_t)(arr)[2] << 40) | ((uint64_t)(arr)[3] << 32) | ((uint64_t)(arr)[4] << 24) | ((uint64_t)(arr)[5] << 16) | ((uint64_t)(arr)[6] << 8) | ((uint64_t)(arr)[7]))
|
||||
|
||||
// Right to left
|
||||
// Right to left (little endian)
|
||||
#define IS_BIT_SET_R2L(num, pos) ((bool) ((num) & (1 << (pos))))
|
||||
#define BIT_SET_R2L(num, pos) ((num) | ((uint32) 1 << (pos)))
|
||||
#define BIT_UNSET_R2L(num, pos) ((num) & ~((uint32) 1 << (pos)))
|
||||
|
|
@ -43,9 +45,11 @@
|
|||
#define BITS_GET_32_R2L(num, pos, to_read) (((num) >> (pos)) & ((1U << (to_read)) - 1))
|
||||
#define BITS_GET_64_R2L(num, pos, to_read) (((num) >> (pos)) & ((1ULL << (to_read)) - 1))
|
||||
|
||||
#define BYTES_MERGE_2_R2L(num) (((num)[1] << 8) | (num)[0])
|
||||
#define BYTES_MERGE_4_R2L(num) (((num)[3] << 24) | ((num)[2] << 16) | ((num)[1] << 8) | (num)[0])
|
||||
#define BYTES_MERGE_8_R2L(num) (((uint64_t)(num)[7] << 56) | ((uint64_t)(num)[6] << 48) | ((uint64_t)(num)[5] << 40) | ((uint64_t)(num)[4] << 32) | ((uint64_t)(num)[3] << 24) | ((uint64_t)(num)[2] << 16) | ((uint64_t)(num)[1] << 8) | ((uint64_t)(num)[0]))
|
||||
// Merges an array of bytes as an int value (16bit, 32bit, 64bit)
|
||||
// Depending on the endianness of the system you could simply cast the array
|
||||
#define BYTES_MERGE_2_R2L(arr) (((arr)[1] << 8) | (arr)[0])
|
||||
#define BYTES_MERGE_4_R2L(arr) (((arr)[3] << 24) | ((arr)[2] << 16) | ((arr)[1] << 8) | (arr)[0])
|
||||
#define BYTES_MERGE_8_R2L(arr) (((uint64_t)(arr)[7] << 56) | ((uint64_t)(arr)[6] << 48) | ((uint64_t)(arr)[5] << 40) | ((uint64_t)(arr)[4] << 32) | ((uint64_t)(arr)[3] << 24) | ((uint64_t)(arr)[2] << 16) | ((uint64_t)(arr)[1] << 8) | ((uint64_t)(arr)[0]))
|
||||
|
||||
struct BitWalk {
|
||||
byte* pos;
|
||||
|
|
@ -278,37 +282,6 @@ void bits_flush(BitWalk* stream)
|
|||
// return bits;
|
||||
// }
|
||||
|
||||
inline
|
||||
uint32 bytes_merge(byte b0, byte b1, byte b2, byte b3) {
|
||||
uint32 result = 0;
|
||||
|
||||
result |= ((uint32) b0 << 24);
|
||||
result |= ((uint32) b1 << 16);
|
||||
result |= ((uint32) b2 << 8);
|
||||
result |= (uint32) b3;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
uint64 bytes_merge(
|
||||
byte b0, byte b1, byte b2, byte b3,
|
||||
byte b4, byte b5, byte b6, byte b7
|
||||
) {
|
||||
uint64 result = 0;
|
||||
|
||||
result |= ((uint64) b0 << 56);
|
||||
result |= ((uint64) b1 << 48);
|
||||
result |= ((uint64) b2 << 40);
|
||||
result |= ((uint64) b3 << 32);
|
||||
result |= ((uint64) b4 << 24);
|
||||
result |= ((uint64) b5 << 16);
|
||||
result |= ((uint64) b6 << 8);
|
||||
result |= (uint64) b7;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
inline int32 find_first_set_bit(int32 value) {
|
||||
if (value == 0) {
|
||||
|
|
@ -350,7 +323,7 @@ uint32 bits_reverse(uint32 data, uint32 count)
|
|||
return reversed;
|
||||
}
|
||||
|
||||
const int32 BIT_COUNT_LOOKUP_TABLE[256] = {
|
||||
static const int32 BIT_COUNT_LOOKUP_TABLE[256] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user