Skip to content

Commit

Permalink
Merge pull request #19 from matyalatte/dev
Browse files Browse the repository at this point in the history
v0.4.0 update
  • Loading branch information
matyalatte committed Apr 6, 2024
2 parents 210fda0 + 40320aa commit 809f24c
Show file tree
Hide file tree
Showing 28 changed files with 870 additions and 136 deletions.
15 changes: 9 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- name: Create Release Draft
id: create-release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.check-tag.outputs.tag }}
name: ${{ steps.check-tag.outputs.tag }}
Expand Down Expand Up @@ -58,22 +58,25 @@ jobs:
- name: build dll (for Windows)
if: runner.os=='Windows'
run: |
cd external/Texconv-Custom-DLL/batch_files
./build.bat
external/Texconv-Custom-DLL/batch_files/build_without_vcruntime.bat
cp external/Texconv-Custom-DLL/texconv.dll addons/blender_dds_addon/directx
external/build_astcenc.bat
cp external/astc-encoder/astcenc-sse2-shared.dll addons/blender_dds_addon/astcenc
- name: build shared library (for Unix)
if: runner.os!='Windows'
run: |
cd external/Texconv-Custom-DLL/shell_scripts
bash build.sh
bash external/Texconv-Custom-DLL/shell_scripts/build_universal.sh
cp external/Texconv-Custom-DLL/libtexconv.* addons/blender_dds_addon/directx
bash external/build_astcenc_${{ runner.os }}.sh
cp external/astc-encoder/libastcenc* addons/blender_dds_addon/astcenc
- name: Copy files
run: |
mkdir -p release
cp -r addons/${{ env.ZIP_NAME }} release
cp changelog.txt release/${{ env.ZIP_NAME }}
cp LICENSE release/${{ env.ZIP_NAME }}
cp external/Texconv-Custom-DLL/*texconv.* release/${{ env.ZIP_NAME }}/directx
shell: bash

- name: Archive Release
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,18 @@ jobs:
- name: build dll (for Windows)
if: runner.os=='Windows'
run: |
external/Texconv-Custom-DLL/batch_files/build.bat
external/Texconv-Custom-DLL/batch_files/build_without_vcruntime.bat
cp external/Texconv-Custom-DLL/texconv.dll addons/blender_dds_addon/directx
external/build_astcenc.bat
cp external/astc-encoder/astcenc-sse2-shared.dll addons/blender_dds_addon/astcenc
- name: build shared library (for Unix)
if: runner.os!='Windows'
run: |
bash external/Texconv-Custom-DLL/shell_scripts/build.sh
bash external/Texconv-Custom-DLL/shell_scripts/build_universal.sh
cp external/Texconv-Custom-DLL/libtexconv.* addons/blender_dds_addon/directx
bash external/build_astcenc_${{ runner.os }}.sh
cp external/astc-encoder/libastcenc* addons/blender_dds_addon/astcenc
- name: Set up Python v${{ env.python-version }}
uses: actions/setup-python@v5
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ htmlcov
# scripts
*.bat
*.sh
!external/build*.*

# textures
*.dds
Expand All @@ -30,4 +31,4 @@ htmlcov

# doc
*.txt
!changelog.txt
!changelog.txt
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "external/Texconv-Custom-DLL"]
path = external/Texconv-Custom-DLL
url = https://github.com/matyalatte/Texconv-Custom-DLL.git
[submodule "external/astc-encoder"]
path = external/astc-encoder
url = https://github.com/ARM-software/astc-encoder.git
4 changes: 3 additions & 1 deletion addons/blender_dds_addon/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

from .ui import import_dds, export_dds, custom_properties, preferences, texture_list
from .directx.texconv import unload_texconv
from .astcenc.astcenc import unload_astcenc

bl_info = {
'name': 'DDS textures',
'author': 'Matyalatte',
'version': (0, 3, 5),
'version': (0, 4, 0),
'blender': (2, 83, 20),
'location': 'Image Editor > Sidebar > DDS Tab',
'description': 'Import and export .dds files',
Expand Down Expand Up @@ -55,3 +56,4 @@ def unregister():
for module in modules:
module.unregister()
unload_texconv()
unload_astcenc()
185 changes: 185 additions & 0 deletions addons/blender_dds_addon/astcenc/astcenc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
"""Texture converter for ASTC formats.
Notes:
You need to build dll from https://github.com/ARM-software/astc-encoder.
And put the dll in the same directory as astcenc.py.
"""

import ctypes
import math
import multiprocessing
import os
from ..directx import util
from .structures import (ASTCENC_ERROR, ASTCENC_PRF,
ASTCENC_QUALITY, ASTCENC_FLG,
AstcencConfig, get_bgra_swizzle,
ASTCENC_TYPE, PointerToPointer,
AstcencImage)

DLL = None


def unload_astcenc():
global DLL
if DLL is None:
return

dll_close = util.get_dll_close()
if dll_close is None:
raise RuntimeError("Failed to unload DLL.")

handle = DLL._handle
dll_close.argtypes = [ctypes.c_void_p]
dll_close(handle)
DLL = None


class Astcenc:
"""ASTC Encoder."""

def __init__(self, dll_path=None, thread_count=-1):
self.load_dll(dll_path=dll_path)
self.config = AstcencConfig()
if (thread_count == -1):
self.thread_count = multiprocessing.cpu_count()
else:
self.thread_count = thread_count

def load_dll(self, dll_path=None):
global DLL
if DLL is not None:
self.dll = DLL
return

if dll_path is None:
dirname = os.path.dirname(os.path.realpath(__file__))
dll_path = util.find_local_library(dirname, "astcenc")

if (dll_path is None) or (not os.path.exists(dll_path)):
raise RuntimeError('astcenc not found.')

self.dll = ctypes.cdll.LoadLibrary(dll_path)
DLL = self.dll

def unload_dll(self):
unload_astcenc()
self.dll = None

def config_init(self, block_x, block_y, block_z=1,
profile=ASTCENC_PRF.LDR,
quality=ASTCENC_QUALITY.MEDIUM,
flags=ASTCENC_FLG.NONE):
self.config.block_x = block_x
self.config.block_y = block_y
self.config.profile = profile
error = self.dll.astcenc_config_init(
profile,
ctypes.c_uint(block_x),
ctypes.c_uint(block_y),
ctypes.c_uint(block_z),
ctypes.c_float(quality),
ctypes.c_uint(flags),
ctypes.byref(self.config)
)
if (error):
raise RuntimeError(f"Failed to initialize AstcencConfig ({self.get_error_string(error)})")

def context_alloc(self):
self.pcontext = ctypes.c_void_p()
error = self.dll.astcenc_context_alloc(
ctypes.byref(self.config),
ctypes.c_uint(self.thread_count),
ctypes.byref(self.pcontext)
)
if (error):
raise RuntimeError(f"Failed to allocate AstcencContext ({self.get_error_string(error)})")

def context_free(self):
self.dll.astcenc_context_free(self.pcontext)

def get_error_string(self, error):
if (error not in [err.value for err in ASTCENC_ERROR]):
return "UNDEFINED"
return ASTCENC_ERROR(error).name

def compress_image(self, size_x, size_y, data, size_z=1):
self.context_alloc()

image = AstcencImage()
image.dim_x = size_x
image.dim_y = size_y
image.dim_z = size_z
image.data_type = ASTCENC_TYPE.U8
data_buf = ctypes.create_string_buffer(data, len(data))
data_pbuf = (ctypes.c_void_p*1)(*[ctypes.cast(data_buf, ctypes.c_void_p)])
image.data = ctypes.cast(data_pbuf, PointerToPointer)

data_len = self.calc_compressed_buffer_size(size_x, size_y, size_z)
data_out = ctypes.create_string_buffer(data_len)

swizzle = get_bgra_swizzle()

for thread_index in range(self.thread_count):
error = self.dll.astcenc_compress_image(
self.pcontext,
ctypes.byref(image),
ctypes.byref(swizzle),
data_out,
data_len,
thread_index
)
if (error):
raise RuntimeError(f"Failed to compress an image as ASTC ({self.get_error_string(error)})")

error = self.dll.astcenc_compress_reset(self.pcontext)
if (error):
raise RuntimeError(f"Failed to reset AstcencContext ({self.get_error_string(error)})")

compressed = bytes(data_out)
self.context_free()
return compressed

def calc_compressed_buffer_size(self, size_x, size_y, size_z=1):
block_count_x = math.ceil(size_x / self.config.block_x)
block_count_y = math.ceil(size_y / self.config.block_y)
block_count_z = math.ceil(size_z / self.config.block_z)
block_count = block_count_x * block_count_y * block_count_z
return block_count * 16

def decompress_image(self, size_x, size_y, data, size_z=1):
self.context_alloc()

image = AstcencImage()
image.dim_x = size_x
image.dim_y = size_y
image.dim_z = size_z
image.data_type = ASTCENC_TYPE.U8
size = size_x * size_y * size_z * 4
buffer = ctypes.create_string_buffer(size)
pbuffer = (ctypes.c_void_p*1)(*[ctypes.cast(buffer, ctypes.c_void_p)])
image.data = ctypes.cast(pbuffer, PointerToPointer)

data_len = len(data)
data_in = ctypes.create_string_buffer(data, data_len)

swizzle = get_bgra_swizzle()

for thread_index in range(self.thread_count):
error = self.dll.astcenc_decompress_image(
self.pcontext,
data_in,
data_len,
ctypes.byref(image),
ctypes.byref(swizzle),
thread_index
)
if (error):
raise RuntimeError(f"Failed to decompress an ASTC image ({self.get_error_string(error)})")

error = self.dll.astcenc_decompress_reset(self.pcontext)
if (error):
raise RuntimeError(f"Failed to reset AstcencContext ({self.get_error_string(error)})")

decompressed = bytes(buffer)
self.context_free()
return decompressed
Loading

0 comments on commit 809f24c

Please sign in to comment.