diff --git a/Makefile b/Makefile index 859c597d..8142a1be 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,11 @@ all: + $(MAKE) -C third_party $(MAKE) -C hw $(MAKE) -C sim $(MAKE) -C driver $(MAKE) -C runtime $(MAKE) -C tests - + clean: $(MAKE) -C hw clean $(MAKE) -C sim clean diff --git a/hw/rtl/tex_unit/VX_tex_define.vh b/hw/rtl/tex_unit/VX_tex_define.vh index 34564b39..a3e1a926 100644 --- a/hw/rtl/tex_unit/VX_tex_define.vh +++ b/hw/rtl/tex_unit/VX_tex_define.vh @@ -24,11 +24,12 @@ `define TEX_BLEND_FRAC 8 `define TEX_BLEND_ONE (2 ** `TEX_BLEND_FRAC) -`define TEX_FORMAT_R8G8B8A8 `TEX_FORMAT_BITS'(0) +`define TEX_FORMAT_A8R8G8B8 `TEX_FORMAT_BITS'(0) `define TEX_FORMAT_R5G6B5 `TEX_FORMAT_BITS'(1) -`define TEX_FORMAT_R4G4B4A4 `TEX_FORMAT_BITS'(2) -`define TEX_FORMAT_L8A8 `TEX_FORMAT_BITS'(3) -`define TEX_FORMAT_L8 `TEX_FORMAT_BITS'(4) -`define TEX_FORMAT_A8 `TEX_FORMAT_BITS'(5) +`define TEX_FORMAT_A1R5G5B5 `TEX_FORMAT_BITS'(2) +`define TEX_FORMAT_A4R4G4B4 `TEX_FORMAT_BITS'(3) +`define TEX_FORMAT_A8L8 `TEX_FORMAT_BITS'(4) +`define TEX_FORMAT_L8 `TEX_FORMAT_BITS'(5) +`define TEX_FORMAT_A8 `TEX_FORMAT_BITS'(6) `endif \ No newline at end of file diff --git a/hw/rtl/tex_unit/VX_tex_format.sv b/hw/rtl/tex_unit/VX_tex_format.sv index 91e0e6f8..e299ed17 100644 --- a/hw/rtl/tex_unit/VX_tex_format.sv +++ b/hw/rtl/tex_unit/VX_tex_format.sv @@ -13,25 +13,31 @@ module VX_tex_format #( always @(*) begin case (format) - `TEX_FORMAT_R8G8B8A8: begin + `TEX_FORMAT_A8R8G8B8: begin texel_out_r[07:00] = texel_in[7:0]; texel_out_r[15:08] = texel_in[15:8]; texel_out_r[23:16] = texel_in[23:16]; texel_out_r[31:24] = texel_in[31:24]; end `TEX_FORMAT_R5G6B5: begin - texel_out_r[07:00] = {texel_in[15:11], texel_in[15:13]}; + texel_out_r[07:00] = {texel_in[4:0], texel_in[4:2]}; texel_out_r[15:08] = {texel_in[10:5], texel_in[10:9]}; - texel_out_r[23:16] = {texel_in[4:0], texel_in[4:2]}; + texel_out_r[23:16] = {texel_in[15:11], texel_in[15:13]}; texel_out_r[31:24] = 8'hff; end - `TEX_FORMAT_R4G4B4A4: begin - texel_out_r[07:00] = {texel_in[11:8], texel_in[15:12]}; + `TEX_FORMAT_A1R5G5B5: begin + texel_out_r[07:00] = {texel_in[4:0], texel_in[4:2]}; + texel_out_r[15:08] = {texel_in[9:5], texel_in[9:7]}; + texel_out_r[23:16] = {texel_in[14:10], texel_in[14:12]}; + texel_out_r[31:24] = {8{texel_in[15]}}; + end + `TEX_FORMAT_A4R4G4B4: begin + texel_out_r[07:00] = {2{texel_in[3:0]}}; texel_out_r[15:08] = {2{texel_in[7:4]}}; - texel_out_r[23:16] = {2{texel_in[3:0]}}; + texel_out_r[23:16] = {2{texel_in[11:8]}}; texel_out_r[31:24] = {2{texel_in[15:12]}}; end - `TEX_FORMAT_L8A8: begin + `TEX_FORMAT_A8L8: begin texel_out_r[07:00] = texel_in[7:0]; texel_out_r[15:08] = texel_in[7:0]; texel_out_r[23:16] = texel_in[7:0]; @@ -45,9 +51,9 @@ module VX_tex_format #( end //`TEX_FORMAT_A8 default: begin - texel_out_r[07:00] = 0; - texel_out_r[15:08] = 0; - texel_out_r[23:16] = 0; + texel_out_r[07:00] = 8'hff; + texel_out_r[15:08] = 8'hff; + texel_out_r[23:16] = 8'hff; texel_out_r[31:24] = texel_in[7:0]; end endcase diff --git a/hw/rtl/tex_unit/VX_tex_stride.sv b/hw/rtl/tex_unit/VX_tex_stride.sv index 0e1eca6a..3f1427bb 100644 --- a/hw/rtl/tex_unit/VX_tex_stride.sv +++ b/hw/rtl/tex_unit/VX_tex_stride.sv @@ -12,13 +12,14 @@ module VX_tex_stride #( always @(*) begin case (format) - `TEX_FORMAT_A8: log_stride_r = 0; - `TEX_FORMAT_L8: log_stride_r = 0; - `TEX_FORMAT_L8A8: log_stride_r = 1; - `TEX_FORMAT_R5G6B5: log_stride_r = 1; - `TEX_FORMAT_R4G4B4A4: log_stride_r = 1; - //`TEX_FORMAT_R8G8B8A8 - default: log_stride_r = 2; + `TEX_FORMAT_A8R8G8B8: log_stride_r = 2; + `TEX_FORMAT_R5G6B5, + `TEX_FORMAT_A1R5G5B5, + `TEX_FORMAT_A4R4G4B4, + `TEX_FORMAT_A8L8: log_stride_r = 1; + // `TEX_FORMAT_L8: + // `TEX_FORMAT_A8: + default: log_stride_r = 0; endcase end diff --git a/hw/syn/quartus/core/Makefile b/hw/syn/quartus/core/Makefile index b976110c..d209c80d 100644 --- a/hw/syn/quartus/core/Makefile +++ b/hw/syn/quartus/core/Makefile @@ -2,6 +2,7 @@ PROJECT = Core TOP_LEVEL_ENTITY = VX_core SRC_FILE = VX_core.v RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/fpu_core/Makefile b/hw/syn/quartus/fpu_core/Makefile index 291d8124..26ca51ac 100644 --- a/hw/syn/quartus/fpu_core/Makefile +++ b/hw/syn/quartus/fpu_core/Makefile @@ -2,6 +2,7 @@ PROJECT = VX_fpu_fpga TOP_LEVEL_ENTITY = VX_fpu_fpga SRC_FILE = VX_fpu_fpga.v RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src RTL_INCLUDE = $(FPU_INCLUDE);$(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces PROJECT_FILES = $(PROJECT).qpf $(PROJECT).qsf diff --git a/hw/syn/quartus/pipeline/Makefile b/hw/syn/quartus/pipeline/Makefile index e4cad107..665f7829 100644 --- a/hw/syn/quartus/pipeline/Makefile +++ b/hw/syn/quartus/pipeline/Makefile @@ -2,6 +2,7 @@ PROJECT = VX_pipeline TOP_LEVEL_ENTITY = VX_pipeline SRC_FILE = VX_pipeline.v RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top1/Makefile b/hw/syn/quartus/top1/Makefile index 374f84e1..9494b2d3 100644 --- a/hw/syn/quartus/top1/Makefile +++ b/hw/syn/quartus/top1/Makefile @@ -2,6 +2,7 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top16/Makefile b/hw/syn/quartus/top16/Makefile index 78f4df68..836e3558 100644 --- a/hw/syn/quartus/top16/Makefile +++ b/hw/syn/quartus/top16/Makefile @@ -2,6 +2,7 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top2/Makefile b/hw/syn/quartus/top2/Makefile index f8801373..d4c6abbc 100644 --- a/hw/syn/quartus/top2/Makefile +++ b/hw/syn/quartus/top2/Makefile @@ -2,6 +2,7 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH=$(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top32/Makefile b/hw/syn/quartus/top32/Makefile index cea702f5..d07a515c 100644 --- a/hw/syn/quartus/top32/Makefile +++ b/hw/syn/quartus/top32/Makefile @@ -2,6 +2,7 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top4/Makefile b/hw/syn/quartus/top4/Makefile index bfe734a7..af33661c 100644 --- a/hw/syn/quartus/top4/Makefile +++ b/hw/syn/quartus/top4/Makefile @@ -2,6 +2,7 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top64/Makefile b/hw/syn/quartus/top64/Makefile index 604f794f..1d60b214 100644 --- a/hw/syn/quartus/top64/Makefile +++ b/hw/syn/quartus/top64/Makefile @@ -1,7 +1,8 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv -RTL_DIR=../../../../rtl +RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party #FAMILY = "Arria 10" #DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FAMILY = "Stratix 10" DEVICE = 1SX280HN2F43E2VG FPU_CORE_PATH=$(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/top8/Makefile b/hw/syn/quartus/top8/Makefile index 0614e0d5..b2efcc6d 100644 --- a/hw/syn/quartus/top8/Makefile +++ b/hw/syn/quartus/top8/Makefile @@ -2,6 +2,7 @@ PROJECT = vortex_afu TOP_LEVEL_ENTITY = vortex_afu SRC_FILE = vortex_afu.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(RTL_DIR)/afu;$(RTL_DIR)/afu/ccip;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/unittest/Makefile b/hw/syn/quartus/unittest/Makefile index 3b1bc6da..975ec0a1 100644 --- a/hw/syn/quartus/unittest/Makefile +++ b/hw/syn/quartus/unittest/Makefile @@ -2,6 +2,7 @@ PROJECT = Unittest TOP_LEVEL_ENTITY = VX_core_req_bank_sel SRC_FILE = VX_core_req_bank_sel.v RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/hw/syn/quartus/vortex/Makefile b/hw/syn/quartus/vortex/Makefile index 6874cce3..b2046cf8 100644 --- a/hw/syn/quartus/vortex/Makefile +++ b/hw/syn/quartus/vortex/Makefile @@ -2,6 +2,7 @@ PROJECT = Vortex TOP_LEVEL_ENTITY = Vortex SRC_FILE = Vortex.sv RTL_DIR = ../../../../rtl +THIRD_PARTY_DIR = ../../../../../third_party FAMILY = "Arria 10" DEVICE = 10AX115N3F40E2SG @@ -11,7 +12,7 @@ FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/arria10 #DEVICE = 1SX280HN2F43E2VG #FPU_CORE_PATH = $(RTL_DIR)/fp_cores/altera/stratix10 -FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(RTL_DIR)/fp_cores/fpnew/src;$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include;$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src +FPU_INCLUDE = $(RTL_DIR)/fp_cores;$(FPU_CORE_PATH);$(THIRD_PARTY_DIR)/fpnew/src;$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include;$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src TEX_INCLUDE = $(RTL_DIR)/tex_unit RTL_INCLUDE = $(RTL_DIR);$(RTL_DIR)/libs;$(RTL_DIR)/interfaces;$(RTL_DIR)/cache;$(FPU_INCLUDE);$(TEX_INCLUDE) diff --git a/runtime/Makefile b/runtime/Makefile index c329e531..d72eb665 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -26,7 +26,7 @@ $(PROJECT).dump: $(PROJECT).a $(CC) $(CFLAGS) -c $< -o $@ $(PROJECT).a: $(OBJS) - $(AR) rcs $(PROJECT).a $^ + $(AR) rcs $@ $^ .depend: $(SRCS) $(CC) $(CFLAGS) -MM $^ > .depend; diff --git a/sim/Makefile b/sim/Makefile index eca60c0b..e0361709 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -1,11 +1,9 @@ all: - $(MAKE) -C common $(MAKE) -C simX $(MAKE) -C rtlsim $(MAKE) -C vlsim clean: - $(MAKE) -C common clean $(MAKE) -C simX clean $(MAKE) -C rtlsim clean $(MAKE) -C vlsim clean \ No newline at end of file diff --git a/sim/common/Makefile b/sim/common/Makefile deleted file mode 100644 index b17dc25b..00000000 --- a/sim/common/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: - SPECIALIZE_TYPE=RISCV SOFTFLOAT_OPTS="-fPIC -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 -DSOFTFLOAT_FAST_DIV64TO32" $(MAKE) -C softfloat/build/Linux-x86_64-GCC - -clean: - $(MAKE) -C softfloat/build/Linux-x86_64-GCC clean \ No newline at end of file diff --git a/sim/common/fixed.h b/sim/common/fixed.h deleted file mode 100644 index 8ef60d9a..00000000 --- a/sim/common/fixed.h +++ /dev/null @@ -1,419 +0,0 @@ -#pragma once - -#include -#include -#include - -template -class Fixed { -private: - - template - struct Cast { - private: - template struct Tag {}; - - inline static T Convert(T2 value, Tag) { - return static_cast(value) << (F - F2); - } - - inline static T Convert(T2 value, Tag) { - return static_cast(value) >> (F2 - F); - } - - inline static T Convert(T2 value, Tag) { - return static_cast(value << (F - F2)); - } - - inline static T Convert(T2 value, Tag) { - return static_cast(value >> (F2 - F)); - } - - public: - inline static T Convert(T2 value) { - return Convert(value, Tag<(sizeof(T2) > sizeof(T)), (F2 > F)>{}); - } - }; - -public: - using data_type = T; - - static constexpr uint32_t FRAC = F; - static constexpr uint32_t INT = sizeof(T) * 8 - FRAC; - static constexpr uint32_t HFRAC = FRAC >> 1; - static constexpr T ONE = static_cast(1) << FRAC; - static constexpr T MASK = ONE - 1; - static constexpr T IMASK = ~MASK; - static constexpr T HALF = ONE >> 1; - static constexpr T TWO = ONE << 1; - - Fixed() {} - - explicit Fixed(int64_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(uint64_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(int32_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(uint32_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(int16_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(uint16_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(int8_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - explicit Fixed(uint8_t rhs) - : data_(static_cast(rhs << FRAC)) { - assert((static_cast(rhs) << FRAC) == data_); - } - - template - explicit Fixed(Fixed rhs) - : data_(Cast::Convert(rhs.data())) - {} - - explicit Fixed(float rhs) - : data_(static_cast(rhs * ONE)) { - assert(data_ == static_cast(rhs * ONE)); - } - - bool operator==(Fixed rhs) const { - return (data_ == rhs.data_); - } - - bool operator!=(Fixed rhs) const { - return (data_ != rhs.data_); - } - - bool operator<(Fixed rhs) const { - return (data_ < rhs.data_); - } - - bool operator<=(Fixed rhs) const { - return (data_ <= rhs.data_); - } - - bool operator>(Fixed rhs) const { - return (data_ > rhs.data_); - } - - bool operator>=(Fixed rhs) const { - return (data_ >= rhs.data_); - } - - Fixed operator-() const { - return make(-data_); - } - - Fixed operator+=(Fixed rhs) { - *this = (*this) + rhs; - return *this; - } - - Fixed operator-=(Fixed rhs) { - *this = (*this) - rhs; - return *this; - } - - Fixed operator*=(Fixed rhs) { - *this = (*this) * rhs; - return *this; - } - - Fixed operator/=(Fixed rhs) { - *this = (*this) / rhs; - return *this; - } - - template - Fixed operator*=(Fixed rhs) { - *this = (*this) * rhs; - return *this; - } - - template - Fixed operator/=(Fixed rhs) { - *this = (*this) / rhs; - return *this; - } - - Fixed operator*=(int32_t rhs) { - *this = (*this) * rhs; - return *this; - } - - Fixed operator*=(uint32_t rhs) { - *this = (*this) * rhs; - return *this; - } - - Fixed operator*=(float rhs) { - *this = (*this) * rhs; - return *this; - } - - Fixed operator/=(int32_t rhs) { - *this = (*this) / rhs; - return *this; - } - - Fixed operator/=(uint32_t rhs) { - *this = (*this) / rhs; - return *this; - } - - Fixed operator/=(float rhs) { - *this = (*this) / rhs; - return *this; - } - - friend Fixed operator+(Fixed lhs, Fixed rhs) { - assert((static_cast(lhs.data_) + rhs.data_) == - (lhs.data_ + rhs.data_)); - return Fixed::make(lhs.data_ + rhs.data_); - } - - friend Fixed operator-(Fixed lhs, Fixed rhs) { - assert((static_cast(lhs.data_) - rhs.data_) == - (lhs.data_ - rhs.data_)); - return Fixed::make(lhs.data_ - rhs.data_); - } - - friend Fixed operator*(Fixed lhs, Fixed rhs) { - return Fixed::make((static_cast(lhs.data_) * rhs.data_) >> FRAC); - } - - template - friend Fixed operator*(Fixed lhs, Fixed rhs) { - return Fixed::make((static_cast(lhs.data_) * rhs.data()) >> F2); - } - - friend Fixed operator/(Fixed lhs, Fixed rhs) { - assert(rhs.data_ != 0); - return Fixed::make((static_cast(lhs.data_) << FRAC) / rhs.data_); - } - - template - friend Fixed operator/(Fixed lhs, Fixed rhs) { - assert(rhs.data() != 0); - return Fixed::make((static_cast(lhs.data_) << F2) / rhs.data()); - } - - friend Fixed operator*(Fixed lhs, float rhs) { - return static_cast(lhs) * rhs; - } - - friend Fixed operator*(float lhs, Fixed rhs) { - return lhs * static_cast(rhs); - } - - friend Fixed operator/(Fixed lhs, float rhs) { - return static_cast(lhs) / rhs; - } - - friend Fixed operator/(float lhs, Fixed rhs) { - return lhs / static_cast(rhs); - } - - friend Fixed operator*(Fixed lhs, char rhs) { - return lhs * static_cast(rhs); - } - - friend Fixed operator*(char lhs, Fixed rhs) { - return rhs * lhs; - } - - friend Fixed operator/(Fixed lhs, char rhs) { - return lhs / static_cast(rhs); - } - - friend Fixed operator/(char lhs, Fixed rhs) { - return rhs / lhs; - } - - friend Fixed operator*(Fixed lhs, uint8_t rhs) { - return lhs * static_cast(rhs); - } - - friend Fixed operator*(uint8_t lhs, Fixed rhs) { - return rhs * lhs; - } - - friend Fixed operator/(Fixed lhs, uint8_t rhs) { - return lhs / static_cast(rhs); - } - - friend Fixed operator/(uint8_t lhs, Fixed rhs) { - return rhs / lhs; - } - - friend Fixed operator*(Fixed lhs, short rhs) { - return lhs * static_cast(rhs); - } - - friend Fixed operator*(short lhs, Fixed rhs) { - return rhs * lhs; - } - - friend Fixed operator/(Fixed lhs, short rhs) { - return lhs / static_cast(rhs); - } - - friend Fixed operator/(short lhs, Fixed rhs) { - return rhs / lhs; - } - - friend Fixed operator*(Fixed lhs, uint16_t rhs) { - return lhs * static_cast(rhs); - } - - friend Fixed operator*(uint16_t lhs, Fixed rhs) { - return rhs * lhs; - } - - friend Fixed operator/(Fixed lhs, uint16_t rhs) { - return lhs / static_cast(rhs); - } - - friend Fixed operator/(uint16_t lhs, Fixed rhs) { - return rhs / lhs; - } - - friend Fixed operator*(Fixed lhs, int32_t rhs) { - auto value = static_cast(lhs.data_ * rhs); - assert((lhs.data_ * static_cast(rhs)) == value); - return Fixed::make(value); - } - - friend Fixed operator*(int32_t lhs, Fixed rhs) { - return rhs * lhs; - } - - friend Fixed operator/(Fixed lhs, int32_t rhs) { - assert(rhs); - auto value = static_cast(lhs.data_ / rhs); - return Fixed::make(value); - } - - friend Fixed operator/(int32_t lhs, Fixed rhs) { - return rhs / lhs; - } - - friend Fixed operator*(Fixed lhs, uint32_t rhs) { - auto value = static_cast(lhs.data_ << rhs); - assert((lhs.data_ << static_cast(rhs)) == value); - return Fixed::make(value); - } - - friend Fixed operator*(uint32_t lhs, Fixed rhs) { - return rhs * lhs; - } - - friend Fixed operator/(Fixed lhs, uint32_t rhs) { - assert(rhs); - auto value = static_cast(lhs.data_ / rhs); - return Fixed::make(value); - } - - friend Fixed operator/(uint32_t lhs, Fixed rhs) { - return rhs / lhs; - } - - friend Fixed operator<<(Fixed lhs, int32_t rhs) { - auto value = static_cast(lhs.data_ << rhs); - assert((lhs.data_ << static_cast(rhs)) == value); - return Fixed::make(value); - } - - friend Fixed operator>>(Fixed lhs, int32_t rhs) { - auto value = static_cast(lhs.data_ >> rhs); - return Fixed::make(value); - } - - friend Fixed operator<<(Fixed lhs, uint32_t rhs) { - auto value = static_cast(lhs.data_ << rhs); - assert((lhs.data_ << static_cast(rhs)) == value); - return Fixed::make(value); - } - - friend Fixed operator>>(Fixed lhs, uint32_t rhs) { - auto value = static_cast(lhs.data_ >> rhs); - return Fixed::make(value); - } - - static Fixed make(T value) { - Fixed ret; - ret.data_ = value; - return ret; - } - - explicit operator int64_t() const { - return static_cast(data_ >> F); - } - - explicit operator uint64_t() const { - return static_cast(data_ >> F); - } - - explicit operator int32_t() const { - return static_cast(data_ >> F); - } - - explicit operator uint32_t() const { - return static_cast(data_ >> F); - } - - explicit operator int16_t() const { - return static_cast(data_ >> F); - } - - explicit operator uint16_t() const { - return static_cast(data_ >> F); - } - - explicit operator int8_t() const { - return static_cast(data_ >> F); - } - - explicit operator uint8_t() const { - return static_cast(data_ >> F); - } - - template - explicit operator Fixed() const { - return Fixed(*this); - } - - explicit operator float() const { - return static_cast(data_) / (static_cast(1) << F); - } - - T data() const { - return data_; - } - -private: - T data_; -}; \ No newline at end of file diff --git a/sim/common/rvfloats.cpp b/sim/common/rvfloats.cpp index c23cb8da..17fab394 100644 --- a/sim/common/rvfloats.cpp +++ b/sim/common/rvfloats.cpp @@ -3,8 +3,8 @@ extern "C" { #include -#include -#include +#include +#include <../RISCV/specialize.h> } #define F32_SIGN 0x80000000 diff --git a/sim/common/texturing.h b/sim/common/texturing.h index 8d76519e..9b0e4526 100644 --- a/sim/common/texturing.h +++ b/sim/common/texturing.h @@ -1,10 +1,11 @@ #pragma once #include -#include #include #include +using namespace cocogfx; + enum class WrapMode { Clamp, Repeat, @@ -12,10 +13,11 @@ enum class WrapMode { }; enum class TexFormat { - R8G8B8A8, - R5G6B5, - R4G4B4A4, - L8A8, + A8R8G8B8, + R5G6B5, + A1R5G5B5, + A4R4G4B4, + A8L8, L8, A8, }; @@ -34,11 +36,12 @@ T Clamp(Fixed fx, WrapMode mode) { inline uint32_t Stride(TexFormat format) { switch (format) { - case TexFormat::R8G8B8A8: + case TexFormat::A8R8G8B8: return 4; case TexFormat::R5G6B5: - case TexFormat::R4G4B4A4: - case TexFormat::L8A8: + case TexFormat::A1R5G5B5: + case TexFormat::A4R4G4B4: + case TexFormat::A8L8: return 2; case TexFormat::L8: case TexFormat::A8: @@ -53,61 +56,68 @@ inline void Unpack8888(TexFormat format, uint32_t texel, uint32_t* lo, uint32_t* hi) { + int r, g, b, a; switch (format) { - case TexFormat::R8G8B8A8: - *lo = texel & 0x00ff00ff; - *hi = (texel >> 8) & 0x00ff00ff; + case TexFormat::A8R8G8B8: + r = (texel >> 16) & 0xff; + g = (texel >> 8) & 0xff; + b = texel & 0xff; + a = texel >> 24; break; - case TexFormat::R5G6B5: - case TexFormat::R4G4B4A4: - *lo = texel; - *hi= 0; + case TexFormat::R5G6B5: + r = ((texel >> 11) << 3) | (texel >> 13); + g = ((texel >> 3) & 0xfc) | ((texel >> 9) & 0x3); + b = ((texel & 0x1f) << 3) | ((texel & 0x1c) >> 2); + a = 0xff; break; - case TexFormat::L8A8: - *lo = (texel | (texel << 8)) & 0x00ff00ff; - *hi = 0; + case TexFormat::A1R5G5B5: + r = ((texel >> 7) & 0xf8) | ((texel << 1) >> 13); + g = ((texel >> 2) & 0xf8) | ((texel >> 7) & 7); + b = ((texel & 0x1f) << 3) | ((texel & 0x1c) >> 2); + a = 0xff * (texel >> 15); + break; + case TexFormat::A4R4G4B4: + r = ((texel >> 4) & 0xf0) | ((texel >> 8) & 0x0f); + g = ((texel & 0xf0) >> 0) | ((texel & 0xf0) >> 4); + b = ((texel & 0x0f) << 4) | ((texel & 0x0f) >> 0); + a = ((texel >> 8) & 0xf0) | (texel >> 12); + break; + case TexFormat::A8L8: + r = texel & 0xff; + g = r; + b = r; + a = texel >> 8; break; case TexFormat::L8: - *lo = (texel | (texel << 16)) & 0x07e0f81f; - *hi = 0; + r = texel & 0xff; + g = r; + b = r; + a = 0xff; break; case TexFormat::A8: - *lo = (texel | (texel << 12)) & 0x0f0f0f0f; - *hi = 0; + r = 0xff; + g = 0xff; + b = 0xff; + a = texel & 0xff; break; default: std::abort(); - } + } + *lo = (r << 16) + b; + *hi = (a << 16) + g; } -inline uint32_t Pack8888(TexFormat format, uint32_t lo, uint32_t hi) { - switch (format) { - case TexFormat::R8G8B8A8: - return (hi << 8) | lo; - case TexFormat::R5G6B5: - case TexFormat::R4G4B4A4: - return lo; - case TexFormat::L8A8: - return (lo | (lo >> 8)) & 0xffff; - case TexFormat::L8: - return (lo | (lo >> 16)) & 0xffff; - case TexFormat::A8: - return (lo | (lo >> 12)) & 0xffff; - default: - std::abort(); - return 0; - } +inline void Unpack8888(uint32_t texel, uint32_t* lo, uint32_t* hi) { + *lo = texel & 0x00ff00ff; + *hi = (texel >> 8) & 0x00ff00ff; } -inline void Lerp8888(uint32_t al, - uint32_t ah, - uint32_t bl, - uint32_t bh, - uint32_t frac, - uint32_t* lo, - uint32_t* hi) { - *lo = (al + (((bl - al) * frac) >> 8)) & 0x00ff00ff; - *hi = (ah + (((bh - ah) * frac) >> 8)) & 0x00ff00ff; +inline uint32_t Pack8888(uint32_t lo, uint32_t hi) { + return (hi << 8) | lo; +} + +inline uint32_t Lerp8888(uint32_t a, uint32_t b, uint32_t f) { + return (a + (((b - a) * f) >> 8)) & 0x00ff00ff; } template @@ -185,25 +195,28 @@ inline uint32_t TexFilterLinear( ) { uint32_t c01l, c01h; { - uint32_t c0l, c0h; - uint32_t c1l, c1h; + uint32_t c0l, c0h, c1l, c1h; Unpack8888(format, texel00, &c0l, &c0h); Unpack8888(format, texel01, &c1l, &c1h); - Lerp8888(c0l, c0h, c1l, c1h, alpha, &c01l, &c01h); + c01l = Lerp8888(c0l, c1l, alpha); + c01h = Lerp8888(c0h, c1h, alpha); } uint32_t c23l, c23h; { - uint32_t c2l, c2h; - uint32_t c3l, c3h; + uint32_t c2l, c2h, c3l, c3h; Unpack8888(format, texel10, &c2l, &c2h); Unpack8888(format, texel11, &c3l, &c3h); - Lerp8888(c2l, c2h, c3l, c3h, alpha, &c23l, &c23h); + c23l = Lerp8888(c2l, c3l, alpha); + c23h = Lerp8888(c2h, c3h, alpha); } - uint32_t cl, ch; - Lerp8888(c01l, c01h, c23l, c23h, beta, &cl, &ch); - uint32_t color = Pack8888(TexFormat::R8G8B8A8, cl, ch); + uint32_t color; + { + uint32_t cl = Lerp8888(c01l, c23l, beta); + uint32_t ch = Lerp8888(c01h, c23h, beta); + color = Pack8888(cl, ch); + } //printf("*** texel00=0x%x, texel01=0x%x, texel10=0x%x, texel11=0x%x, color=0x%x\n", texel00, texel01, texel10, texel11, color); @@ -211,9 +224,12 @@ inline uint32_t TexFilterLinear( } inline uint32_t TexFilterPoint(TexFormat format, uint32_t texel) { - uint32_t cl, ch; - Unpack8888(format, texel, &cl, &ch); - uint32_t color = Pack8888(TexFormat::R8G8B8A8, cl, ch); + uint32_t color; + { + uint32_t cl, ch; + Unpack8888(format, texel, &cl, &ch); + color = Pack8888(cl, ch); + } //printf("*** texel=0x%x, color=0x%x\n", texel, color); diff --git a/sim/rtlsim/Makefile b/sim/rtlsim/Makefile index 662fbf1d..df9970d5 100644 --- a/sim/rtlsim/Makefile +++ b/sim/rtlsim/Makefile @@ -1,12 +1,13 @@ -RTL_DIR=../../hw/rtl -DPI_DIR=../../hw/dpi +RTL_DIR = ../../hw/rtl +DPI_DIR = ../../hw/dpi +THIRD_PARTY_DIR = ../../third_party CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors -Wno-array-bounds CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I../../../hw -I../../common -CXXFLAGS += -I../../common/softfloat/source/include +CXXFLAGS += -I../$(THIRD_PARTY_DIR)/softfloat/source/include -LDFLAGS += ../../common/softfloat/build/Linux-x86_64-GCC/softfloat.a +LDFLAGS += ../$(THIRD_PARTY_DIR)/softfloat/build/Linux-x86_64-GCC/softfloat.a # control RTL debug tracing states DBG_TRACE_FLAGS += -DDBG_TRACE_PIPELINE @@ -24,7 +25,7 @@ DBG_TRACE_FLAGS += -DDBG_TRACE_TEX DBG_FLAGS += $(DBG_TRACE_FLAGS) -FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src +FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include -I$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src -I$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(THIRD_PARTY_DIR)/fpnew/src TEX_INCLUDE = -I$(RTL_DIR)/tex_unit RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache -I$(RTL_DIR)/simulate $(FPU_INCLUDE) $(TEX_INCLUDE) @@ -90,7 +91,7 @@ $(PROJECT): $(SRCS) static: $(SRCS) verilator --build $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' -LDFLAGS '$(LDFLAGS)' - $(AR) rcs lib$(PROJECT).a obj_dir/*.o ../common/softfloat/build/Linux-x86_64-GCC/*.o + $(AR) rcs lib$(PROJECT).a obj_dir/*.o $(THIRD_PARTY_DIR)/softfloat/build/Linux-x86_64-GCC/*.o clean-static: rm -rf lib$(PROJECT).a obj_dir diff --git a/sim/simX/Makefile b/sim/simX/Makefile index 7ea54863..b3312bb0 100644 --- a/sim/simX/Makefile +++ b/sim/simX/Makefile @@ -1,12 +1,14 @@ RTL_DIR = ../hw/rtl +THIRD_PARTY_DIR = ../../third_party CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I. -I../common -I../../hw -CXXFLAGS += -I../common/softfloat/source/include +CXXFLAGS += -I$(THIRD_PARTY_DIR)/softfloat/source/include +CXXFLAGS += -I$(THIRD_PARTY_DIR)/cocogfx/include CXXFLAGS += $(CONFIGS) -LDFLAGS += ../common/softfloat/build/Linux-x86_64-GCC/softfloat.a +LDFLAGS += $(THIRD_PARTY_DIR)/softfloat/build/Linux-x86_64-GCC/softfloat.a -L$(THIRD_PARTY_DIR)/cocogfx -lcocogfx TOP = vx_cache_sim @@ -38,7 +40,7 @@ obj_dir/%.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ static: $(OBJS) - $(AR) rcs lib$(PROJECT).a $(OBJS) ../common/softfloat/build/Linux-x86_64-GCC/*.o + $(AR) rcs lib$(PROJECT).a $(OBJS) $(THIRD_PARTY_DIR)/softfloat/build/Linux-x86_64-GCC/*.o .depend: $(SRCS) $(CXX) $(CXXFLAGS) -MM $^ > .depend; diff --git a/sim/simX/tex_unit.cpp b/sim/simX/tex_unit.cpp index d73bd728..bfbcef1a 100644 --- a/sim/simX/tex_unit.cpp +++ b/sim/simX/tex_unit.cpp @@ -4,6 +4,7 @@ #include using namespace vortex; +using namespace cocogfx; enum class FilterMode { Point, diff --git a/sim/vlsim/Makefile b/sim/vlsim/Makefile index 57e114a2..879bd954 100644 --- a/sim/vlsim/Makefile +++ b/sim/vlsim/Makefile @@ -1,13 +1,14 @@ RTL_DIR = ../../hw/rtl DPI_DIR = ../../hw/dpi -SCRIPT_DIR=../../hw/scripts +SCRIPT_DIR = ../../hw/scripts +THIRD_PARTY_DIR = ../../third_party CXXFLAGS += -std=c++11 -Wall -Wextra -Wfatal-errors -Wno-array-bounds CXXFLAGS += -fPIC -Wno-maybe-uninitialized CXXFLAGS += -I.. -I../../../hw -I../../common -CXXFLAGS += -I../../common/softfloat/source/include +CXXFLAGS += -I../$(THIRD_PARTY_DIR)/softfloat/source/include -LDFLAGS += -shared ../../common/softfloat/build/Linux-x86_64-GCC/softfloat.a +LDFLAGS += -shared ../$(THIRD_PARTY_DIR)/softfloat/build/Linux-x86_64-GCC/softfloat.a # control RTL debug tracing states DBG_TRACE_FLAGS += -DDBG_TRACE_PIPELINE @@ -29,7 +30,7 @@ SRCS = ../common/util.cpp ../common/mem.cpp ../common/rvfloats.cpp SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp SRCS += fpga.cpp opae_sim.cpp -FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src +FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include -I$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src -I$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(THIRD_PARTY_DIR)/fpnew/src TEX_INCLUDE = -I$(RTL_DIR)/tex_unit RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache $(FPU_INCLUDE) $(TEX_INCLUDE) RTL_INCLUDE += -I$(RTL_DIR)/afu -I$(RTL_DIR)/afu/ccip @@ -98,7 +99,7 @@ $(PROJECT).so: $(SRCS) vortex_afu.h static: $(SRCS) vortex_afu.h verilator --build $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' -LDFLAGS '$(LDFLAGS)' - $(AR) rcs $(PROJECT).a obj_dir/*.o ../common/softfloat/build/Linux-x86_64-GCC/*.o + $(AR) rcs $(PROJECT).a obj_dir/*.o $(THIRD_PARTY_DIR)/softfloat/build/Linux-x86_64-GCC/*.o clean-static: rm -rf $(PROJECT).a obj_dir vortex_afu.h diff --git a/sim/vlsim/vortex_afu.h b/sim/vlsim/vortex_afu.h new file mode 100644 index 00000000..1a1dee44 --- /dev/null +++ b/sim/vlsim/vortex_afu.h @@ -0,0 +1,49 @@ +// auto-generated by gen_config.py. DO NOT EDIT +// Generated at 2021-11-25 13:43:13.259966 + +// Translated from VX_config.vh: + +#ifndef __VORTEX_AFU__ +#define __VORTEX_AFU__ + + + +#define PLATFORM_PROVIDES_LOCAL_MEMORY + +#ifndef PLATFORM_PARAM_LOCAL_MEMORY_BANKS +#define PLATFORM_PARAM_LOCAL_MEMORY_BANKS 2 +#endif + +#ifndef PLATFORM_PARAM_LOCAL_MEMORY_ADDR_WIDTH +#define PLATFORM_PARAM_LOCAL_MEMORY_ADDR_WIDTH 26 +#endif + +#ifndef PLATFORM_PARAM_LOCAL_MEMORY_DATA_WIDTH +#define PLATFORM_PARAM_LOCAL_MEMORY_DATA_WIDTH 512 +#endif + +#ifndef PLATFORM_PARAM_LOCAL_MEMORY_BURST_CNT_WIDTH +#define PLATFORM_PARAM_LOCAL_MEMORY_BURST_CNT_WIDTH 4 +#endif + + + +#define AFU_ACCEL_NAME "vortex_afu" +#define AFU_ACCEL_UUID 0x35f9452b_25c2_434c_93d5_6f8c60db361c + +#define AFU_IMAGE_CMD_MEM_READ 1 +#define AFU_IMAGE_CMD_MEM_WRITE 2 +#define AFU_IMAGE_CMD_RUN 3 +#define AFU_IMAGE_MMIO_CMD_TYPE 10 +#define AFU_IMAGE_MMIO_DATA_SIZE 16 +#define AFU_IMAGE_MMIO_IO_ADDR 12 +#define AFU_IMAGE_MMIO_MEM_ADDR 14 +#define AFU_IMAGE_MMIO_SCOPE_READ 20 +#define AFU_IMAGE_MMIO_SCOPE_WRITE 22 +#define AFU_IMAGE_MMIO_DEV_CAPS 24 +#define AFU_IMAGE_MMIO_STATUS 18 + +#define AFU_IMAGE_POWER 0 +#define AFU_TOP_IFC "ccip_std_afu_avalon_mm" + +#endif diff --git a/tests/regression/tex/Makefile b/tests/regression/tex/Makefile index 1a771373..fd9f195d 100644 --- a/tests/regression/tex/Makefile +++ b/tests/regression/tex/Makefile @@ -10,7 +10,7 @@ VX_DP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objdump VX_CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy VX_CFLAGS += -std=c++11 -march=rv32imf -mabi=ilp32f -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections -VX_CFLAGS += -DENABLE_SW -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw -I$(VORTEX_RT_PATH)/../sim/common +VX_CFLAGS += -DENABLE_SW -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw -I$(VORTEX_RT_PATH)/../sim/common -I$(VORTEX_RT_PATH)/../third_party/cocogfx/include VX_LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a @@ -19,15 +19,13 @@ VX_SRCS = kernel.c #CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors CXXFLAGS += -std=c++11 -O0 -g -Wall -Wextra -Wfatal-errors -CXXFLAGS += -DLUPNG_USE_ZLIB +CXXFLAGS += -I$(VORTEX_DRV_PATH)/include -I$(VORTEX_RT_PATH)/../hw -I$(VORTEX_RT_PATH)/../sim/common -I$(VORTEX_RT_PATH)/../third_party/cocogfx/include -CXXFLAGS += -I$(VORTEX_DRV_PATH)/include -I$(VORTEX_RT_PATH)/../hw -I$(VORTEX_RT_PATH)/../sim/common - -LDFLAGS += -L$(VORTEX_DRV_PATH)/stub -lvortex -lz +LDFLAGS += -L$(VORTEX_DRV_PATH)/stub -lvortex $(VORTEX_RT_PATH)/../third_party/cocogfx/libcocogfx.a -lz PROJECT = tex -SRCS = main.cpp utils.cpp tga.cpp lupng.c +SRCS = main.cpp utils.cpp all: $(PROJECT) kernel.bin kernel.dump diff --git a/tests/regression/tex/blitter.h b/tests/regression/tex/blitter.h deleted file mode 100644 index e05f64b8..00000000 --- a/tests/regression/tex/blitter.h +++ /dev/null @@ -1,268 +0,0 @@ -// -// Copyright (c) Blaise Tine. All rights reserved. -// -// -// Use of this sample source code is subject to the terms of the Microsoft -// license agreement under which you licensed this sample source code. If -// you did not accept the terms of the license agreement, you are not -// authorized to use this sample source code. For the terms of the license, -// please see the license agreement between you and Microsoft or, if applicable, -// see the LICENSE.RTF on your install media or the root of your tools -// installation. -// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR -// INDEMNITIES. -// -#pragma once - -#include "surfacedesc.h" - -class BlitTable { -public: - typedef int (*PfnCopy)(const SurfaceDesc &dstDesc, - uint32_t dstOffsetX, - uint32_t dstOffsetY, - uint32_t copyWidth, - uint32_t copyHeight, - const SurfaceDesc &srcDesc, - uint32_t srcOffsetX, - uint32_t srcOffsetY); - - BlitTable() { - for (uint32_t s = 0; s < FORMAT_COLOR_SIZE_; ++s) { - for (uint32_t d = 0; d < FORMAT_COLOR_SIZE_; ++d) { - copyFuncs_[s][d] = CopyInvalid; - } - } - - for (uint32_t s = 0; s < FORMAT_COLOR_SIZE_; ++s) { - switch (s) { - case FORMAT_A8: - case FORMAT_L8: - copyFuncs_[s][s] = CopyFast; - break; - - case FORMAT_A8L8: - copyFuncs_[FORMAT_A8L8][FORMAT_A8] = Copy; - copyFuncs_[FORMAT_A8L8][FORMAT_A8L8] = CopyFast; - break; - - case FORMAT_R5G6B5: - copyFuncs_[FORMAT_R5G6B5][FORMAT_L8] = Copy; - copyFuncs_[FORMAT_R5G6B5][FORMAT_R5G6B5] = CopyFast; - copyFuncs_[FORMAT_R5G6B5][FORMAT_R8G8B8] = - Copy; - copyFuncs_[FORMAT_R5G6B5][FORMAT_B8G8R8] = - Copy; - copyFuncs_[FORMAT_R5G6B5][FORMAT_A8B8G8R8] = - Copy; - copyFuncs_[FORMAT_R5G6B5][FORMAT_A8R8G8B8] = - Copy; - break; - - case FORMAT_A1R5G5B5: - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_L8] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8L8] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_R8G8B8] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8R8G8B8] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_R5G5B5A1] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_R4G4B4A4] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_B8G8R8] = - Copy; - copyFuncs_[FORMAT_A1R5G5B5][FORMAT_A8B8G8R8] = - Copy; - break; - - case FORMAT_A4R4G4B4: - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_L8] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8L8] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_R8G8B8] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8R8G8B8] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_R5G5B5A1] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_R4G4B4A4] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_B8G8R8] = - Copy; - copyFuncs_[FORMAT_A4R4G4B4][FORMAT_A8B8G8R8] = - Copy; - break; - - case FORMAT_R8G8B8: - copyFuncs_[FORMAT_R8G8B8][FORMAT_L8] = Copy; - copyFuncs_[FORMAT_R8G8B8][FORMAT_R5G6B5] = - Copy; - copyFuncs_[FORMAT_R8G8B8][FORMAT_R8G8B8] = CopyFast; - copyFuncs_[FORMAT_R8G8B8][FORMAT_B8G8R8] = - Copy; - copyFuncs_[FORMAT_R8G8B8][FORMAT_A8B8G8R8] = - Copy; - copyFuncs_[FORMAT_R8G8B8][FORMAT_A8R8G8B8] = - Copy; - break; - - case FORMAT_A8R8G8B8: - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_L8] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8L8] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R5G6B5] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R8G8B8] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8R8G8B8] = CopyFast; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R5G5B5A1] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_R4G4B4A4] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_B8G8R8] = - Copy; - copyFuncs_[FORMAT_A8R8G8B8][FORMAT_A8B8G8R8] = - Copy; - break; - - case FORMAT_R5G5B5A1: - copyFuncs_[FORMAT_R5G5B5A1][FORMAT_A8] = - Copy; - copyFuncs_[FORMAT_R5G5B5A1][FORMAT_L8] = - Copy; - copyFuncs_[FORMAT_R5G5B5A1][FORMAT_A8L8] = - Copy; - copyFuncs_[FORMAT_R5G5B5A1][FORMAT_RGB] = - Copy; - copyFuncs_[FORMAT_R5G5B5A1][FORMAT_ARGB] = - Copy; - break; - - case FORMAT_R4G4B4A4: - copyFuncs_[FORMAT_R4G4B4A4][FORMAT_A8] = - Copy; - copyFuncs_[FORMAT_R4G4B4A4][FORMAT_L8] = - Copy; - copyFuncs_[FORMAT_R4G4B4A4][FORMAT_A8L8] = - Copy; - copyFuncs_[FORMAT_R4G4B4A4][FORMAT_RGB] = - Copy; - copyFuncs_[FORMAT_R4G4B4A4][FORMAT_ARGB] = - Copy; - break; - - case FORMAT_B8G8R8: - copyFuncs_[FORMAT_B8G8R8][FORMAT_L8] = Copy; - copyFuncs_[FORMAT_B8G8R8][FORMAT_RGB] = Copy; - break; - - case FORMAT_A8B8G8R8: - copyFuncs_[FORMAT_A8B8G8R8][FORMAT_A8] = - Copy; - copyFuncs_[FORMAT_A8B8G8R8][FORMAT_L8] = - Copy; - copyFuncs_[FORMAT_A8B8G8R8][FORMAT_A8L8] = - Copy; - copyFuncs_[FORMAT_A8B8G8R8][FORMAT_RGB] = - Copy; - copyFuncs_[FORMAT_A8B8G8R8][FORMAT_ARGB] = - Copy; - break; - } - } - } - - PfnCopy get(uint32_t srcFormat, uint32_t dstFormat) const { - assert(srcFormat < FORMAT_COLOR_SIZE_); - assert(dstFormat < FORMAT_COLOR_SIZE_); - return copyFuncs_[srcFormat][dstFormat]; - } - -private: - template - static int Copy(const SurfaceDesc &dstDesc, - uint32_t dstOffsetX, - uint32_t dstOffsetY, - uint32_t copyWidth, - uint32_t copyHeight, - const SurfaceDesc &srcDesc, - uint32_t srcOffsetX, - uint32_t srcOffsetY) { - auto srcBPP = TFormatInfo::CBSIZE; - auto dstBPP = TFormatInfo::CBSIZE; - auto srcNextLine = srcDesc.Pitch; - auto dstNextLine = dstDesc.Pitch; - - auto pbSrc = srcDesc.pBits + srcOffsetX * srcBPP + srcOffsetY * srcDesc.Pitch; - auto pbDst = dstDesc.pBits + dstOffsetX * dstBPP + dstOffsetY * dstDesc.Pitch; - - while (copyHeight--) { - auto pSrc = reinterpret_cast::TYPE *>(pbSrc); - for (auto *pDst = reinterpret_cast::TYPE *>( - pbDst), - *const pEnd = pDst + copyWidth; - pDst != pEnd; ++pDst, ++pSrc) { - auto tmp = Format::ConvertFrom(pSrc); - Format::ConvertTo(pDst, tmp); - } - - pbSrc += srcNextLine; - pbDst += dstNextLine; - } - return 0; - } - - template - static int CopyFast(const SurfaceDesc &dstDesc, - uint32_t dstOffsetX, - uint32_t dstOffsetY, - uint32_t copyWidth, - uint32_t copyHeight, - const SurfaceDesc &srcDesc, - uint32_t srcOffsetX, - uint32_t srcOffsetY) { - auto nBPP = sizeof(Type); - auto srcNextLine = srcDesc.Pitch; - auto dstNextLine = dstDesc.Pitch; - - auto pbSrc = srcDesc.pBits + srcOffsetX * nBPP + srcOffsetY * srcDesc.Pitch; - auto pbDst = dstDesc.pBits + dstOffsetX * nBPP + dstOffsetY * dstDesc.Pitch; - - while (copyHeight--) { - auto pSrc = reinterpret_cast(pbSrc); - for (auto *pDst = reinterpret_cast(pbDst), *const pEnd = pDst + copyWidth; - pDst != pEnd; ++pDst, ++pSrc) { - *pDst = *pSrc; - } - pbSrc += srcNextLine; - pbDst += dstNextLine; - } - return 0; - } - - static int CopyInvalid(const SurfaceDesc & /*dstDesc*/, - uint32_t /*dstOffsetX*/, - uint32_t /*dstOffsetY*/, - uint32_t /*copyWidth*/, - uint32_t /*copyHeight*/, - const SurfaceDesc & /*srcDesc*/, - uint32_t /*srcOffsetX*/, - uint32_t /*srcOffsetY*/) - { - std::cout << "Error: invalid format" << std::endl; - return -1; - } - - PfnCopy copyFuncs_[FORMAT_COLOR_SIZE_][FORMAT_COLOR_SIZE_]; -}; \ No newline at end of file diff --git a/tests/regression/tex/color.h b/tests/regression/tex/color.h deleted file mode 100644 index 708565a3..00000000 --- a/tests/regression/tex/color.h +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright (c) Blaise Tine. All rights reserved. -// -// -// Use of this sample source code is subject to the terms of the Microsoft -// license agreement under which you licensed this sample source code. If -// you did not accept the terms of the license agreement, you are not -// authorized to use this sample source code. For the terms of the license, -// please see the license agreement between you and Microsoft or, if applicable, -// see the LICENSE.RTF on your install media or the root of your tools -// installation. -// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR -// INDEMNITIES. -// -#pragma once - -#include -#include - -struct ColorARGB { - union { - struct { - uint32_t value; - }; - struct { - uint8_t b, g, r, a; - }; - struct { - uint8_t m[4]; - }; - }; - - ColorARGB() {} - - ColorARGB(int a, int r, int g, int b) { - assert((a >= 0) && (a <= 0xff)); - assert((r >= 0) && (r <= 0xff)); - assert((g >= 0) && (g <= 0xff)); - assert((b >= 0) && (b <= 0xff)); - - this->b = static_cast(b); - this->g = static_cast(g); - this->r = static_cast(r); - this->a = static_cast(a); - } - - ColorARGB(int r, int g, int b) { - assert((r >= 0) && (r <= 0xff)); - assert((g >= 0) && (g <= 0xff)); - assert((b >= 0) && (b <= 0xff)); - - this->b = static_cast(b); - this->g = static_cast(g); - this->r = static_cast(r); - } - - ColorARGB(int value) { - this->value = value; - } - - void operator=(const ColorARGB &rhs) { - this->value = rhs.value; - } - - operator uint32_t() const { - return this->value; - } -}; \ No newline at end of file diff --git a/tests/regression/tex/common.h b/tests/regression/tex/common.h index 1a7f53d0..00d7148f 100644 --- a/tests/regression/tex/common.h +++ b/tests/regression/tex/common.h @@ -15,7 +15,6 @@ typedef struct { uint8_t src_logwidth; uint8_t src_logheight; uint32_t src_addr; - float lod; uint32_t mip_offs[TEX_LOD_MAX+1]; uint32_t dst_width; uint32_t dst_height; diff --git a/tests/regression/tex/format.h b/tests/regression/tex/format.h deleted file mode 100644 index 4ee8268e..00000000 --- a/tests/regression/tex/format.h +++ /dev/null @@ -1,1022 +0,0 @@ -// -// Copyright (c) Blaise Tine. All rights reserved. -// -// -// Use of this sample source code is subject to the terms of the Microsoft -// license agreement under which you licensed this sample source code. If -// you did not accept the terms of the license agreement, you are not -// authorized to use this sample source code. For the terms of the license, -// please see the license agreement between you and Microsoft or, if applicable, -// see the LICENSE.RTF on your install media or the root of your tools -// installation. -// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR -// INDEMNITIES. -// -#pragma once - -#include "int24.h" -#include "color.h" -#include - -enum ePixelFormat { - FORMAT_UNKNOWN, - FORMAT_A8, - FORMAT_L8, - FORMAT_A8L8, - FORMAT_R5G6B5, - FORMAT_A8R8G8B8, - FORMAT_A1R5G5B5, - FORMAT_R8G8B8, - FORMAT_A4R4G4B4, - FORMAT_A8B8G8R8, - FORMAT_R5G5B5A1, - FORMAT_B8G8R8, - FORMAT_R4G4B4A4, - FORMAT_COLOR_SIZE_, - FORMAT_D16 = FORMAT_COLOR_SIZE_, - FORMAT_X8S8D16, - FORMAT_PAL4_B8G8R8, - FORMAT_PAL4_A8B8G8R8, - FORMAT_PAL4_R5G6B5, - FORMAT_PAL4_R4G4B4A4, - FORMAT_PAL4_R5G5B5A1, - FORMAT_PAL8_B8G8R8, - FORMAT_PAL8_A8B8G8R8, - FORMAT_PAL8_R5G6B5, - FORMAT_PAL8_R4G4B4A4, - FORMAT_PAL8_R5G5B5A1, - FORMAT_SIZE_, -}; - -#define FORMAT_A FORMAT_A8 -#define FORMAT_RGB FORMAT_R5G6B5 -#define FORMAT_RGB_ FORMAT_R8G8B8 -#define FORMAT_ARGB FORMAT_A8R8G8B8 -#define FORMAT_ARGB_ FORMAT_A4R4G4B4 - -template -struct TFormatInfo {}; - -template <> -struct TFormatInfo { - typedef uint8_t TYPE; - - enum { - CBSIZE = 0, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 4, - RED = 4, - GREEN = 4, - BLUE = 4, - LERP = 4, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 4, - RED = 4, - GREEN = 4, - BLUE = 4, - LERP = 4, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 1, - RED = 5, - GREEN = 5, - BLUE = 5, - LERP = 5, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 1, - RED = 5, - GREEN = 5, - BLUE = 5, - LERP = 5, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - RED = 5, - GREEN = 6, - BLUE = 5, - LERP = 5, - }; -}; - -template <> -struct TFormatInfo { - typedef uint24_t TYPE; - - enum { - CBSIZE = 3, - RED = 8, - GREEN = 8, - BLUE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint24_t TYPE; - - enum { - CBSIZE = 3, - RED = 8, - GREEN = 8, - BLUE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint32_t TYPE; - - enum { - CBSIZE = 4, - ALPHA = 8, - RED = 8, - GREEN = 8, - BLUE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint32_t TYPE; - - enum { - CBSIZE = 4, - ALPHA = 8, - RED = 8, - GREEN = 8, - BLUE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint8_t TYPE; - - enum { - CBSIZE = 1, - ALPHA = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint8_t TYPE; - - enum { - CBSIZE = 1, - LUMINANCE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 8, - LUMINANCE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - DEPTH = 16, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 4, - DEPTH = 16, - STENCIL = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 3, - RED = 8, - GREEN = 8, - BLUE = 8, - PALETTE = 4, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 4, - ALPHA = 8, - RED = 8, - GREEN = 8, - BLUE = 8, - PALETTE = 4, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - RED = 5, - GREEN = 6, - BLUE = 5, - PALETTE = 4, - LERP = 5, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 4, - RED = 4, - GREEN = 4, - BLUE = 4, - PALETTE = 4, - LERP = 4, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 1, - RED = 5, - GREEN = 5, - BLUE = 5, - PALETTE = 4, - LERP = 5, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 3, - RED = 8, - GREEN = 8, - BLUE = 8, - PALETTE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 4, - ALPHA = 8, - RED = 8, - GREEN = 8, - BLUE = 8, - PALETTE = 8, - LERP = 8, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - RED = 5, - GREEN = 6, - BLUE = 5, - PALETTE = 8, - LERP = 5, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 4, - RED = 4, - GREEN = 4, - BLUE = 4, - PALETTE = 8, - LERP = 4, - }; -}; - -template <> -struct TFormatInfo { - typedef uint16_t TYPE; - - enum { - CBSIZE = 2, - ALPHA = 1, - RED = 5, - GREEN = 5, - BLUE = 5, - PALETTE = 8, - LERP = 5, - }; -}; - -/////////////////////////////////////////////////////////////////////////////// - -#define DEF_GET_ENUM_VALUE(Name, Default) \ - template \ - struct enum_get_##Name { \ - static constexpr int value = Default; \ - }; \ - template \ - struct enum_get_##Name::type> { \ - static constexpr int value = T::Name; \ - } - -#define __formatInfo(format) \ - { \ - TFormatInfo::CBSIZE, FormatSize>::RED, \ - FormatSize>::GREEN, \ - FormatSize>::BLUE, \ - FormatSize>::ALPHA, \ - FormatSize>::LUMINANCE, \ - FormatSize>::DEPTH, \ - FormatSize>::STENCIL, \ - FormatSize>::PALETTE, \ - FormatSize>::LERP \ - } - -/////////////////////////////////////////////////////////////////////////////// - -struct FormatInfo { - uint8_t BytePerPixel; - uint8_t Red; - uint8_t Green; - uint8_t Blue; - uint8_t Alpha; - uint8_t Luminance; - uint8_t Depth; - uint8_t Stencil; - uint8_t PaletteBits; - uint8_t LerpBits; -}; - -template -class FormatSize { -protected: - DEF_GET_ENUM_VALUE(RED, 0); - DEF_GET_ENUM_VALUE(GREEN, 0); - DEF_GET_ENUM_VALUE(BLUE, 0); - DEF_GET_ENUM_VALUE(ALPHA, 0); - DEF_GET_ENUM_VALUE(LUMINANCE, 0); - DEF_GET_ENUM_VALUE(DEPTH, 0); - DEF_GET_ENUM_VALUE(STENCIL, 0); - DEF_GET_ENUM_VALUE(PALETTE, 0); - DEF_GET_ENUM_VALUE(LERP, 0); - -public: - enum { - RED = enum_get_RED::value, - GREEN = enum_get_GREEN::value, - BLUE = enum_get_BLUE::value, - ALPHA = enum_get_ALPHA::value, - LUMINANCE = enum_get_LUMINANCE::value, - DEPTH = enum_get_DEPTH::value, - STENCIL = enum_get_STENCIL::value, - PALETTE = enum_get_PALETTE::value, - LERP = enum_get_LERP::value, - - RGB = RED + GREEN + BLUE + LUMINANCE, - RGBA = RGB + ALPHA - }; -}; - -namespace Format { - -inline static const FormatInfo &GetInfo(ePixelFormat pixelFormat) { - static const FormatInfo sc_formatInfos[FORMAT_SIZE_] = { - __formatInfo(FORMAT_UNKNOWN), - __formatInfo(FORMAT_A8), - __formatInfo(FORMAT_L8), - __formatInfo(FORMAT_A8L8), - __formatInfo(FORMAT_RGB), - __formatInfo(FORMAT_ARGB), - __formatInfo(FORMAT_A1R5G5B5), - __formatInfo(FORMAT_RGB_), - __formatInfo(FORMAT_ARGB_), - __formatInfo(FORMAT_R4G4B4A4), - __formatInfo(FORMAT_R5G5B5A1), - __formatInfo(FORMAT_B8G8R8), - __formatInfo(FORMAT_A8B8G8R8), - __formatInfo(FORMAT_D16), - __formatInfo(FORMAT_X8S8D16), - __formatInfo(FORMAT_PAL4_B8G8R8), - __formatInfo(FORMAT_PAL4_A8B8G8R8), - __formatInfo(FORMAT_PAL4_R5G6B5), - __formatInfo(FORMAT_PAL4_R4G4B4A4), - __formatInfo(FORMAT_PAL4_R5G5B5A1), - __formatInfo(FORMAT_PAL8_B8G8R8), - __formatInfo(FORMAT_PAL8_A8B8G8R8), - __formatInfo(FORMAT_PAL8_R5G6B5), - __formatInfo(FORMAT_PAL8_R4G4B4A4), - __formatInfo(FORMAT_PAL8_R5G5B5A1), - }; - assert(pixelFormat < FORMAT_SIZE_); - return sc_formatInfos[pixelFormat]; -} - -#undef __formatInfo -#undef DEF_GET_ENUM_VALUE - -typedef ColorARGB (*pfn_convert_from)(const void *pIn); - -typedef void (*pfn_convert_to)(void *pOut, const ColorARGB &in); - -template -static uint32_t ConvertTo(const ColorARGB &color); - -template -static void ConvertTo(void *pOut, const ColorARGB &in) { - *reinterpret_cast::TYPE *>(pOut) = - static_cast::TYPE>( - ConvertTo(in)); -} - -template -static ColorARGB ConvertFrom(uint32_t in); - -template -static ColorARGB ConvertFrom(const void *pIn) { - return ConvertFrom( - *reinterpret_cast::TYPE *>(pIn)); -} - -inline static pfn_convert_to GetConvertTo(ePixelFormat pixelFormat) { - switch (pixelFormat) { - case FORMAT_A8: - return &ConvertTo; - case FORMAT_L8: - return &ConvertTo; - case FORMAT_A8L8: - return &ConvertTo; - case FORMAT_R5G6B5: - return &ConvertTo; - case FORMAT_A1R5G5B5: - return &ConvertTo; - case FORMAT_A4R4G4B4: - return &ConvertTo; - case FORMAT_R8G8B8: - return &ConvertTo; - case FORMAT_A8R8G8B8: - return &ConvertTo; - case FORMAT_R5G5B5A1: - return &ConvertTo; - case FORMAT_R4G4B4A4: - return &ConvertTo; - case FORMAT_B8G8R8: - return &ConvertTo; - case FORMAT_A8B8G8R8: - return &ConvertTo; - case FORMAT_D16: - return &ConvertTo; - case FORMAT_X8S8D16: - return &ConvertTo; - default: - return &ConvertTo; - } - return nullptr; -} - -inline static pfn_convert_from GetConvertFrom(ePixelFormat pixelFormat, - bool bForceAlpha) { - if (bForceAlpha) { - switch (pixelFormat) { - case FORMAT_A8: - return &ConvertFrom; - case FORMAT_L8: - return &ConvertFrom; - case FORMAT_A8L8: - return &ConvertFrom; - case FORMAT_R5G6B5: - return &ConvertFrom; - case FORMAT_A1R5G5B5: - return &ConvertFrom; - case FORMAT_A4R4G4B4: - return &ConvertFrom; - case FORMAT_R8G8B8: - return &ConvertFrom; - case FORMAT_A8R8G8B8: - return &ConvertFrom; - case FORMAT_R5G5B5A1: - return &ConvertFrom; - case FORMAT_R4G4B4A4: - return &ConvertFrom; - case FORMAT_B8G8R8: - return &ConvertFrom; - case FORMAT_A8B8G8R8: - return &ConvertFrom; - case FORMAT_D16: - return &ConvertFrom; - case FORMAT_X8S8D16: - return &ConvertFrom; - default: - return &ConvertFrom; - } - } else { - switch (pixelFormat) { - case FORMAT_A8: - return &ConvertFrom; - case FORMAT_L8: - return &ConvertFrom; - case FORMAT_A8L8: - return &ConvertFrom; - case FORMAT_R5G6B5: - return &ConvertFrom; - case FORMAT_A1R5G5B5: - return &ConvertFrom; - case FORMAT_A4R4G4B4: - return &ConvertFrom; - case FORMAT_R8G8B8: - return &ConvertFrom; - case FORMAT_A8R8G8B8: - return &ConvertFrom; - case FORMAT_R5G5B5A1: - return &ConvertFrom; - case FORMAT_R4G4B4A4: - return &ConvertFrom; - case FORMAT_B8G8R8: - return &ConvertFrom; - case FORMAT_A8B8G8R8: - return &ConvertFrom; - case FORMAT_D16: - return &ConvertFrom; - case FORMAT_X8S8D16: - return &ConvertFrom; - default: - return &ConvertFrom; - } - } - - return nullptr; -} - -inline static uint32_t GetNativeFormat(ePixelFormat pixelFormat) { - switch (pixelFormat) { - case FORMAT_PAL4_B8G8R8: - case FORMAT_PAL8_B8G8R8: - return FORMAT_B8G8R8; - - case FORMAT_PAL4_A8B8G8R8: - case FORMAT_PAL8_A8B8G8R8: - return FORMAT_A8B8G8R8; - - case FORMAT_PAL4_R5G6B5: - case FORMAT_PAL8_R5G6B5: - return FORMAT_R5G6B5; - - case FORMAT_PAL4_R4G4B4A4: - case FORMAT_PAL8_R4G4B4A4: - return FORMAT_R4G4B4A4; - - case FORMAT_PAL4_R5G5B5A1: - case FORMAT_PAL8_R5G5B5A1: - return FORMAT_R5G5B5A1; - - default: - return pixelFormat; - } -} - -/////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &/*in*/) { - return 0; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t /*in*/) { - return 0; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t /*in*/) { - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return ((in.r & 0xf8) << 8) | ((in.g & 0xfc) << 3) | (in.b >> 3); -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.r = ((in >> 11) << 3) | (in >> 13); - ret.g = ((in >> 3) & 0xfc) | ((in >> 9) & 0x3); - ret.b = ((in & 0x1f) << 3) | ((in & 0x1c) >> 2); - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff; - ret.r = ((in >> 11) << 3) | (in >> 13); - ret.g = ((in >> 3) & 0xfc) | ((in >> 9) & 0x3); - ret.b = ((in & 0x1f) << 3) | ((in & 0x1c) >> 2); - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return (in.a ? 0x8000 : 0) | ((in.r & 0xf8) << 7) | ((in.g & 0xf8) << 2) | - (in.b >> 3); -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff * (in >> 15); - ret.r = ((in >> 7) & 0xf8) | ((in << 1) >> 13); - ret.g = ((in >> 2) & 0xf8) | ((in >> 7) & 7); - ret.b = ((in & 0x1f) << 3) | ((in & 0x1c) >> 2); - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff * (in >> 15); - ret.r = ((in >> 7) & 0xf8) | ((in << 1) >> 13); - ret.g = ((in >> 2) & 0xf8) | ((in >> 7) & 7); - ret.b = ((in & 0x1f) << 3) | ((in & 0x1c) >> 2); - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return ((in.r & 0xf8) << 8) | ((in.g & 0xf8) << 3) | ((in.b & 0xf8) >> 2) | - (in.a ? 0x1 : 0); -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff * (in & 0x1); - ret.r = ((in >> 8) & 0xf8) | (in >> 13); - ret.g = ((in >> 3) & 0xf8) | ((in >> 8) & 7); - ret.b = ((in & 0x3e) << 2) | ((in & 0x3e) >> 3); - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff * (in & 0x1); - ret.r = ((in >> 8) & 0xf8) | (in >> 13); - ret.g = ((in >> 3) & 0xf8) | ((in >> 8) & 7); - ret.b = ((in & 0x3e) << 2) | ((in & 0x3e) >> 3); - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return ((in.a & 0xf0) << 8) | ((in.r & 0xf0) << 4) | ((in.g & 0xf0) << 0) | - (in.b >> 4); -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = ((in >> 8) & 0xf0) | (in >> 12); - ret.r = ((in >> 4) & 0xf0) | ((in >> 8) & 0x0f); - ret.g = ((in & 0xf0) >> 0) | ((in & 0xf0) >> 4); - ret.b = ((in & 0x0f) << 4) | ((in & 0x0f) >> 0); - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = ((in >> 8) & 0xf0) | (in >> 12); - ret.r = ((in >> 4) & 0xf0) | ((in >> 8) & 0x0f); - ret.g = ((in & 0xf0) >> 0) | ((in & 0xf0) >> 4); - ret.b = ((in & 0x0f) << 4) | ((in & 0x0f) >> 0); - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return ((in.r & 0xf0) << 8) | ((in.g & 0xf0) << 4) | ((in.b & 0xf0) << 0) | - (in.a >> 4); -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = ((in & 0x0f) << 4) | ((in & 0x0f) >> 0); - ret.r = ((in >> 8) & 0xf0) | (in >> 12); - ret.g = ((in >> 4) & 0xf0) | ((in >> 8) & 0x0f); - ret.b = ((in & 0xf0) >> 0) | ((in & 0xf0) >> 4); - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = ((in & 0x0f) << 4) | ((in & 0x0f) >> 0); - ret.r = ((in >> 8) & 0xf0) | (in >> 12); - ret.g = ((in >> 4) & 0xf0) | ((in >> 8) & 0x0f); - ret.b = ((in & 0xf0) >> 0) | ((in & 0xf0) >> 4); - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return (in.r << 16) | (in.g << 8) | in.b; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.r = in >> 16; - ret.g = (in >> 8) & 0xff; - ret.b = in & 0xff; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff; - ret.r = in >> 16; - ret.g = (in >> 8) & 0xff; - ret.b = in & 0xff; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return (in.b << 16) | (in.g << 8) | in.r; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.r = in & 0xff; - ret.g = (in >> 8) & 0xff; - ret.b = in >> 16; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff; - ret.r = in & 0xff; - ret.g = (in >> 8) & 0xff; - ret.b = in >> 16; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return (in.a << 24) | (in.r << 16) | (in.g << 8) | in.b; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in >> 24; - ret.r = (in >> 16) & 0xff; - ret.g = (in >> 8) & 0xff; - ret.b = in & 0xff; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in >> 24; - ret.r = (in >> 16) & 0xff; - ret.g = (in >> 8) & 0xff; - ret.b = in & 0xff; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return (in.a << 24) | (in.b << 16) | (in.g << 8) | in.r; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in >> 24; - ret.r = in & 0xff; - ret.g = (in >> 8) & 0xff; - ret.b = (in >> 16) & 0xff; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in >> 24; - ret.r = in & 0xff; - ret.g = (in >> 8) & 0xff; - ret.b = (in >> 16) & 0xff; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return in.a; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return in.r; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.r = in; - ret.g = in; - ret.b = in; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = 0xff; - ret.r = in; - ret.g = in; - ret.b = in; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return (in.a << 8) | in.r; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in >> 8; - ret.r = in & 0xff; - ret.g = in & 0xff; - ret.b = in & 0xff; - return ret; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.a = in >> 8; - ret.r = in & 0xff; - ret.g = in & 0xff; - ret.b = in & 0xff; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return in.value; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.value = in; - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -template <> -inline uint32_t ConvertTo(const ColorARGB &in) { - return in.b; -} - -template <> -inline ColorARGB ConvertFrom(uint32_t in) { - ColorARGB ret; - ret.value = in; - return ret; -} - -} // namespace Format \ No newline at end of file diff --git a/tests/regression/tex/int24.h b/tests/regression/tex/int24.h deleted file mode 100644 index b08537a7..00000000 --- a/tests/regression/tex/int24.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) Blaise Tine. All rights reserved. -// -// -// Use of this sample source code is subject to the terms of the Microsoft -// license agreement under which you licensed this sample source code. If -// you did not accept the terms of the license agreement, you are not -// authorized to use this sample source code. For the terms of the license, -// please see the license agreement between you and Microsoft or, if applicable, -// see the LICENSE.RTF on your install media or the root of your tools -// installation. -// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR -// INDEMNITIES. -// -#pragma once - -#include - -struct uint24_t { - uint8_t m[3]; - - explicit uint24_t(uint32_t value) { - m[0] = (value >> 0) & 0xff; - m[1] = (value >> 8) & 0xff; - m[2] = (value >> 16) & 0xff; - } - - explicit uint24_t(uint8_t x, uint8_t y, uint8_t z) { - m[0] = x; - m[1] = y; - m[2] = z; - } - - operator uint32_t() const { - return (m[2] << 16) | (m[1] << 8) | m[0]; - } -}; diff --git a/tests/regression/tex/kernel.c b/tests/regression/tex/kernel.c index 9aaaad24..88aec50c 100644 --- a/tests/regression/tex/kernel.c +++ b/tests/regression/tex/kernel.c @@ -10,6 +10,7 @@ typedef struct { uint32_t tile_height; float deltaX; float deltaY; + float minification; } tile_arg_t; template @@ -35,10 +36,10 @@ void kernel_body(int task_id, tile_arg_t* arg) { uint8_t* dst_ptr = (uint8_t*)(state->dst_addr + xoffset * state->dst_stride + yoffset * state->dst_pitch); - Fixed<16> xlod(state->lod); + Fixed<16> xj(arg->minification); - /*vx_printf("task_id=%d, deltaX=%f, deltaY=%f, tile_width=%d, tile_height=%d\n", - task_id, arg->deltaX, arg->deltaY, arg->tile_width, arg->tile_height);*/ + /*vx_printf("task_id=%d, tile_width=%d, tile_height=%d, deltaX=%f, deltaY=%f, minification=%f\n", + task_id, arg->tile_width, arg->tile_height, arg->deltaX, arg->deltaY, arg->minification);*/ float fv = (yoffset + 0.5f) * arg->deltaY; for (uint32_t y = 0; y < arg->tile_height; ++y) { @@ -47,13 +48,7 @@ void kernel_body(int task_id, tile_arg_t* arg) { for (uint32_t x = 0; x < arg->tile_width; ++x) { Fixed xu(fu); Fixed xv(fv); - uint32_t color; - #ifdef ENABLE_SW - if (state->use_sw) - color = tex_load_sw(state, xu, xv, xlod); - else - #endif - color = tex_load_hw(state, xu, xv, xlod); + uint32_t color = tex_load(state, xu, xv, xj); //vx_printf("task_id=%d, x=%d, y=%d, fu=%f, fv=%f, xu=0x%x, xv=0x%x, color=0x%x\n", task_id, x, y, fu, fv, xu.data(), xv.data(), color); dst_row[x] = color; fu += arg->deltaX; @@ -76,7 +71,7 @@ int main() { csr_write(CSR_TEX(0, TEX_STATE_ADDR), arg->src_addr); static_for_t()([&](int i) { csr_write(CSR_TEX(0, TEX_STATE_MIPOFF(i)), arg->mip_offs[i]); - }); + }); tile_arg_t targ; targ.state = arg; @@ -84,6 +79,14 @@ int main() { targ.tile_height = (arg->dst_height + arg->num_tasks - 1) / arg->num_tasks; targ.deltaX = 1.0f / arg->dst_width; targ.deltaY = 1.0f / arg->dst_height; + + { + uint32_t src_width = (1 << arg->src_logwidth); + uint32_t src_height = (1 << arg->src_logheight); + float width_ratio = float(src_width) / arg->dst_width; + float height_ratio = float(src_height) / arg->dst_height; + targ.minification = std::max(width_ratio, height_ratio); + } vx_spawn_tasks(arg->num_tasks, (vx_spawn_tasks_cb)kernel_body, &targ); /*for (uint32_t t=0; t < arg->num_tasks; ++t) { diff --git a/tests/regression/tex/lupng.c b/tests/regression/tex/lupng.c deleted file mode 100644 index f612fbc9..00000000 --- a/tests/regression/tex/lupng.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Jan Solanti - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include - -#ifndef LUPNG_USE_ZLIB -#include -#else -#include -#endif - -#include "lupng.h" - -#define PNG_NONE 0 -#define PNG_IHDR 0x01 -#define PNG_PLTE 0x02 -#define PNG_IDAT 0x04 -#define PNG_IEND 0x08 - -#define PNG_GRAYSCALE 0 -#define PNG_TRUECOLOR 2 -/* 24bpp RGB palette */ -#define PNG_PALETTED 3 -#define PNG_GRAYSCALE_ALPHA 4 -#define PNG_TRUECOLOR_ALPHA 6 - -#define PNG_FILTER_NONE 0 -#define PNG_FILTER_SUB 1 -#define PNG_FILTER_UP 2 -#define PNG_FILTER_AVERAGE 3 -#define PNG_FILTER_PAETH 4 - -#define PNG_SIG_SIZE 8 - -#define PNG_DONE 1 -#define PNG_OK 0 -#define PNG_ERROR -1 - -#define BUF_SIZE 8192 -#define MAX(x, y) (x > y ? x : y) - -#if defined(_MSC_VER) -#define LU_INLINE __inline /* MS-specific inline */ -#else -#define LU_INLINE inline /* rest of the world... */ -#endif - -#define SIZE_T_MAX_POSITIVE ( ((size_t)-1) >> 1 ) - -/******************************************************** - * CRC computation as per PNG spec - ********************************************************/ - -/* Precomputed table of CRCs of all 8-bit messages - using the polynomial from the PNG spec, 0xEDB88320L. */ -static const uint32_t crcTable[] = -{ - 0x0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x76DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0xEDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x9B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x1DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x6B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0xF00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x86D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x3B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x4DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0xD6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0xA00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x26D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x5005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0xCB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -/* Update a running CRC with the bytes buf[0..len-1]--the CRC - should be initialized to all 1's, and the transmitted value - is the 1's complement of the final running CRC (see the - crc() routine below)). */ -static uint32_t updateCrc(uint32_t crc, unsigned char *buf, - size_t len) -{ - uint32_t c = crc; - size_t n; - - for (n = 0; n < len; n++) - c = crcTable[(c ^ buf[n]) & 0xFF] ^ (c >> 8); - - return c; -} - -/* Return the CRC of the bytes buf[0..len-1]. */ -static uint32_t crc(unsigned char *buf, size_t len) -{ - return updateCrc(0xFFFFFFFFL, buf, len) ^ 0xFFFFFFFFL; -} - - - -/******************************************************** - * Helper structs - ********************************************************/ - -typedef struct -{ - uint32_t length; - uint8_t *type; - uint8_t *data; - uint32_t crc; -} PngChunk; - -typedef struct { - const LuUserContext *userCtx; - int8_t chunksFound; - - /* IHDR info */ - int32_t width; - int32_t height; - uint8_t depth; - uint8_t colorType; - uint8_t channels; - uint8_t compression; - uint8_t filter; - uint8_t interlace; - - /* PLTE info */ - uint32_t paletteItems; - uint8_t *palette; - - /* fields used for (de)compression & (de-)filtering */ - z_stream stream; - size_t scanlineBytes; - int32_t currentCol; - int32_t currentRow; - uint32_t currentElem; - size_t currentByte; - int bytesPerPixel; - uint8_t *currentScanline; - uint8_t *previousScanline; - uint8_t currentFilter; - uint8_t interlacePass; - size_t compressedBytes; - - /* used for constructing 16 bit deep pixels */ - int tmpCount; - uint8_t tmpBytes[2]; - - /* the output image */ - LuImage *img; - const LuImage *cimg; /* constant pointer version */ -} PngInfoStruct; - -/* helper macro to output warning via user context of the info struct */ -#define LUPNG_WARN_UC(uc,...) do { if ((uc)->warnProc) { (uc)->warnProc((uc)->warnProcUserPtr, __VA_ARGS__); }} while(0) -#define LUPNG_WARN(info,...) LUPNG_WARN_UC((info)->userCtx, __VA_ARGS__) - -/* PNG header: */ -static const uint8_t PNG_SIG[] = -/* P N G \r \n SUB \n */ -{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; - -static const int startingRow[] = { 0, 0, 0, 4, 0, 2, 0, 1 }; -static const int startingCol[] = { 0, 0, 4, 0, 2, 0, 1, 0 }; -static const int rowIncrement[] = { 1, 8, 8, 8, 4, 4, 2, 2 }; -static const int colIncrement[] = { 1, 8, 8, 4, 4, 2, 2, 1 }; - - - -/******************************************************** - * Helper functions - ********************************************************/ - -static LU_INLINE void releaseChunk(PngChunk *chunk, const LuUserContext *userCtx) -{ - /* Only release chunk->type since chunk->data points to the same memory. */ - userCtx->freeProc(chunk->type, userCtx->freeProcUserPtr); - userCtx->freeProc(chunk, userCtx->freeProcUserPtr); -} - -static LU_INLINE uint32_t swap32(uint32_t n) -{ - union { - unsigned char np[4]; - uint32_t i; - } u; - u.i = n; - - return ((uint32_t)u.np[0] << 24) | - ((uint32_t)u.np[1] << 16) | - ((uint32_t)u.np[2] << 8) | - (uint32_t)u.np[3]; -} - -static LU_INLINE uint16_t swap16(uint16_t n) -{ - union { - unsigned char np[2]; - uint16_t i; - } u; - u.i = n; - - return ((uint16_t)u.np[0] << 8) | (uint16_t)u.np[1]; -} - -static int bytesEqual(const uint8_t *a, const uint8_t *b, size_t count) -{ - size_t i; - for (i = 0; i < count; ++i) - { - if (*(a+i) != *(b+i)) - return 0; - } - - return 1; -} - -static void* internalMalloc(size_t size, void *userPtr) -{ - (void)userPtr; /* not used */ - return malloc(size); -} - -static void internalFree(void *ptr, void *userPtr) -{ - (void)userPtr; /* not used */ - free(ptr); -} - -static void internalPrintf(void *userPtr, const char *fmt, ...) -{ - FILE *outStream = (FILE*)userPtr; - va_list args; - - va_start(args, fmt); - vfprintf(outStream, fmt, args); - va_end(args); - fputc('\n', outStream); -} - -static size_t internalFread(void *ptr, size_t size, size_t count, void *userPtr) -{ - return fread(ptr, size, count, (FILE *)userPtr); -} - -static size_t internalFwrite(const void *ptr, size_t size, size_t count, void *userPtr) -{ - return fwrite(ptr, size, count, (FILE *)userPtr); -} - -/******************************************************** - * Png filter functions - ********************************************************/ -static LU_INLINE int absi(int val) -{ - return val > 0 ? val : -val; -} - -static LU_INLINE uint8_t raw(PngInfoStruct *info, size_t col) -{ - if (col > SIZE_T_MAX_POSITIVE) - return 0; - return info->currentScanline[col]; -} - -static LU_INLINE uint8_t prior(PngInfoStruct *info, size_t col) -{ - if (info->currentRow <= startingRow[info->interlacePass] || col > SIZE_T_MAX_POSITIVE) - return 0; - return info->previousScanline[col]; -} - - -static LU_INLINE uint8_t paethPredictor(uint8_t a, uint8_t b, uint8_t c) -{ - unsigned int A = a, B = b, C = c; - int p = (int)A + (int)B - (int)C; - int pa = absi(p - (int)A); - int pb = absi(p - (int)B); - int pc = absi(p - (int)C); - - if (pa <= pb && pa <= pc) - return a; - if (pb <= pc) - return b; - return c; -} - -static LU_INLINE uint8_t deSub(PngInfoStruct *info, uint8_t filtered) -{ - return filtered + raw(info, info->currentByte-info->bytesPerPixel); -} - -static LU_INLINE uint8_t deUp(PngInfoStruct *info, uint8_t filtered) -{ - return filtered + prior(info, info->currentByte); -} - -static LU_INLINE uint8_t deAverage(PngInfoStruct *info, uint8_t filtered) -{ - uint16_t avg = (uint16_t)(raw(info, info->currentByte-info->bytesPerPixel) - + prior(info, info->currentByte)); - avg >>= 1; - return filtered + avg; -} - -static LU_INLINE uint8_t dePaeth(PngInfoStruct *info, uint8_t filtered) -{ - return filtered + paethPredictor( - raw(info, info->currentByte-info->bytesPerPixel), - prior(info, info->currentByte), - prior(info, info->currentByte-info->bytesPerPixel)); -} - -static LU_INLINE uint8_t none(PngInfoStruct *info) -{ - return raw(info, info->currentByte); -} - -static LU_INLINE uint8_t sub(PngInfoStruct *info) -{ - return raw(info, info->currentByte) - raw(info, info->currentByte-info->bytesPerPixel); -} - -static LU_INLINE uint8_t up(PngInfoStruct *info) -{ - return raw(info, info->currentByte) - prior(info, info->currentByte); -} - -static LU_INLINE uint8_t average(PngInfoStruct *info) -{ - uint16_t avg = (uint16_t)(raw(info, info->currentByte-info->bytesPerPixel) - + prior(info, info->currentByte)); - avg >>= 1; - return raw(info, info->currentByte) - avg; -} - -static LU_INLINE uint8_t paeth(PngInfoStruct *info) -{ - return raw(info, info->currentByte) - paethPredictor( - raw(info, info->currentByte-info->bytesPerPixel), - prior(info, info->currentByte), - prior(info, info->currentByte-info->bytesPerPixel)); -} - - - -/******************************************************** - * Actual implementation - ********************************************************/ -static LU_INLINE int parseIhdr(PngInfoStruct *info, PngChunk *chunk) -{ - if (info->chunksFound) - { - LUPNG_WARN(info,"PNG: malformed PNG file!"); - return PNG_ERROR; - } - - info->chunksFound |= PNG_IHDR; - info->width = swap32(*(uint32_t *)chunk->data); - info->height = swap32(*((uint32_t *)chunk->data + 1)); - info->depth = *(chunk->data + 8); - info->colorType = *(chunk->data + 9); - info->compression = *(chunk->data + 10); - info->filter = *(chunk->data + 11); - info->interlace = *(chunk->data + 12); - - switch (info->colorType) - { - case PNG_GRAYSCALE: - info->channels = 1; - break; - case PNG_TRUECOLOR: - info->channels = 3; - break; - case PNG_PALETTED: - info->channels = 3; - break; - case PNG_GRAYSCALE_ALPHA: - info->channels = 2; - break; - case PNG_TRUECOLOR_ALPHA: - info->channels = 4; - break; - default: - LUPNG_WARN(info,"PNG: illegal color type: %u", - (unsigned int)info->colorType); - return PNG_ERROR; - break; - } - - if (info->width <= 0 || info->height <= 0) - { - LUPNG_WARN(info, "PNG: illegal dimensions"); - return PNG_ERROR; - } - - if ((info->colorType != PNG_GRAYSCALE && info->colorType != PNG_PALETTED && - info->depth < 8) || - (info->colorType == PNG_PALETTED && info->depth == 16) || - info->depth > 16) - { - LUPNG_WARN(info, "PNG: illegal bit depth for color type"); - return PNG_ERROR; - } - - if (info->compression) - { - LUPNG_WARN(info,"PNG: unknown compression method: %u", - (unsigned int)info->compression); - return PNG_ERROR; - } - - if (info->filter) - { - LUPNG_WARN(info,"PNG: unknown filter scheme: %u", - (unsigned int)info->filter); - return PNG_ERROR; - } - - memset(&(info->stream), 0, sizeof(info->stream)); - if(inflateInit(&(info->stream)) != Z_OK) - { - LUPNG_WARN(info, "PNG: inflateInit failed!"); - return PNG_ERROR; - } - info->img = luImageCreate(info->width, info->height, - info->channels, info->depth < 16 ? 8 : 16, NULL, info->userCtx); - info->cimg = info->img; - info->scanlineBytes = MAX((info->width * info->channels * info->depth) >> 3, 1); - info->currentScanline = (uint8_t *)info->userCtx->allocProc(info->scanlineBytes, info->userCtx->allocProcUserPtr); - info->previousScanline = (uint8_t *)info->userCtx->allocProc(info->scanlineBytes, info->userCtx->allocProcUserPtr); - info->currentCol = -1; - info->interlacePass = info->interlace ? 1 : 0; - info->bytesPerPixel = MAX((info->channels * info->depth) >> 3, 1); - if (!info->img || !info->currentScanline || !info->previousScanline) - { - LUPNG_WARN(info, "PNG: memory allocation failed!"); - return PNG_ERROR; - } - - return PNG_OK; -} - -static LU_INLINE int parsePlte(PngInfoStruct *info, PngChunk *chunk) -{ - if (info->chunksFound & PNG_PLTE) - { - LUPNG_WARN(info, "PNG: too many palette chunks in file!"); - return PNG_ERROR; - } - info->chunksFound |= PNG_PLTE; - - if (info->chunksFound & PNG_IDAT || !(info->chunksFound & PNG_IHDR)) - { - LUPNG_WARN(info, "PNG: malformed PNG file!"); - return PNG_ERROR; - } - - if (info->colorType == PNG_GRAYSCALE || info->colorType == PNG_GRAYSCALE_ALPHA) - { - LUPNG_WARN(info, "PNG: palettes are not allowed in grayscale images!"); - return PNG_ERROR; - } - - if (chunk->length % 3 != 0) - { - LUPNG_WARN(info, "PNG: invalid palette size!"); - return PNG_ERROR; - } - - info->paletteItems = chunk->length/3; - info->palette = (uint8_t *)info->userCtx->allocProc(chunk->length,info->userCtx->allocProcUserPtr); - if (!info->palette) - { - LUPNG_WARN(info, "PNG: memory allocation failed!"); - return PNG_ERROR; - } - memcpy(info->palette, chunk->data, chunk->length); - - return PNG_OK; -} - -static LU_INLINE void stretchBits(uint8_t inByte, uint8_t outBytes[8], int depth) -{ - int i; - switch (depth) { - case 1: - for (i = 0; i < 8; ++i) - outBytes[i] = (inByte >> (7-i)) & 0x01; - break; - - case 2: - outBytes[0] = (inByte >> 6) & 0x03; - outBytes[1] = (inByte >> 4) & 0x03; - outBytes[2] = (inByte >> 2) & 0x03; - outBytes[3] = inByte & 0x03; - break; - - case 4: - outBytes[0] = (inByte >> 4) & 0x0F; - outBytes[1] = inByte & 0x0F; - break; - - default: - break; - } -} - -/* returns: 1 if at end of scanline, 0 otherwise */ -static LU_INLINE int insertByte(PngInfoStruct *info, uint8_t byte) -{ - int advance = 0; - const uint8_t scale[] = {0x00, 0xFF, 0x55, 0x00, 0x11, 0x00, 0x00, 0x00}; - - /* for paletted images currentElem will always be 0 */ - size_t idx = info->currentRow * info->width * info->channels - + info->currentCol * info->channels - + info->currentElem; - - if (info->colorType != PNG_PALETTED) - { - if (info->depth == 8) - info->cimg->data[idx] = byte; - - else if (info->depth < 8) - info->cimg->data[idx] = byte * scale[info->depth]; - - else /* depth == 16 */ - { - info->tmpBytes[info->tmpCount] = byte; - if (info->tmpCount) /* just inserted 2nd byte */ - { - uint16_t val = *(uint16_t *)info->tmpBytes; - val = swap16(val); - info->tmpCount = 0; - - ((uint16_t *)(info->cimg->data))[idx] = val; - } - else - { - ++info->tmpCount; - return 0; - } - } - - ++info->currentElem; - if (info->currentElem >= info->channels) - { - advance = 1; - info->currentElem = 0; - } - } - else - { - /* The spec limits palette size to 256 entries */ - if (byte < info->paletteItems) - { - info->cimg->data[idx ] = info->palette[3*byte ]; - info->cimg->data[idx+1] = info->palette[3*byte+1]; - info->cimg->data[idx+2] = info->palette[3*byte+2]; - } - else - { - LUPNG_WARN(info,"PNG: invalid palette index encountered!"); - } - advance = 1; - } - - if (advance) - { - /* advance to next pixel */ - info->currentCol += colIncrement[info->interlacePass]; - - if (info->currentCol >= info->width) - { - uint8_t *tmp = info->currentScanline; - info->currentScanline = info->previousScanline; - info->previousScanline = tmp; - - info->currentCol = -1; - info->currentByte = 0; - - info->currentRow += rowIncrement[info->interlacePass]; - if (info->currentRow >= info->height && info->interlace) - { - ++info->interlacePass; - while (startingCol[info->interlacePass] >= info->width || - startingRow[info->interlacePass] >= info->height) - ++info->interlacePass; - info->currentRow = startingRow[info->interlacePass]; - } - return 1; - } - } - - return 0; -} - -static LU_INLINE int parseIdat(PngInfoStruct *info, PngChunk *chunk) -{ - unsigned char filtered[BUF_SIZE]; - int status = Z_OK; - - if (!(info->chunksFound & PNG_IHDR)) - { - LUPNG_WARN(info,"PNG: malformed PNG file!"); - return PNG_ERROR; - } - - if (info->colorType == PNG_PALETTED && !(info->chunksFound & PNG_PLTE)) - { - LUPNG_WARN(info,"PNG: palette required but missing!"); - return PNG_ERROR; - } - - info->chunksFound |= PNG_IDAT; - info->stream.next_in = (unsigned char *)chunk->data; - info->stream.avail_in = chunk->length; - do - { - size_t decompressed; - size_t i; - - info->stream.next_out = filtered; - info->stream.avail_out = BUF_SIZE; - status = inflate(&(info->stream), Z_NO_FLUSH); - decompressed = BUF_SIZE - info->stream.avail_out; - - if (status != Z_OK && - status != Z_STREAM_END && - status != Z_BUF_ERROR && - status != Z_NEED_DICT) - { - LUPNG_WARN(info, "PNG: inflate error!"); - return PNG_ERROR; - } - - for (i = 0; - i < decompressed && info->currentCol < info->width && info->currentRow < info->height; - ++i) - { - if (info->currentCol < 0) - { - info->currentCol = startingCol[info->interlacePass]; - info->currentFilter = filtered[i]; - } - else - { - uint8_t rawByte = 0; - uint8_t fullBytes[8] = {0}; - switch (info->currentFilter) - { - case PNG_FILTER_NONE: - rawByte = filtered[i]; - break; - case PNG_FILTER_SUB: - rawByte = deSub(info, filtered[i]); - break; - case PNG_FILTER_UP: - rawByte = deUp(info, filtered[i]); - break; - case PNG_FILTER_AVERAGE: - rawByte = deAverage(info, filtered[i]); - break; - case PNG_FILTER_PAETH: - rawByte = dePaeth(info, filtered[i]); - break; - default: - break; - } - - info->currentScanline[info->currentByte] = rawByte; - ++info->currentByte; - - if (info->depth < 8) - { - int j; - stretchBits(rawByte, fullBytes, info->depth); - for (j = 0; j < 8/info->depth; ++j) - if(insertByte(info, fullBytes[j])) - break; - } - else - insertByte(info, rawByte); - } - } - } while ((info->stream.avail_in > 0 || info->stream.avail_out == 0) - && info->currentCol < info->width && info->currentRow < info->height); - - return PNG_OK; -} - -static LU_INLINE PngChunk *readChunk(PngInfoStruct *info) -{ - PngChunk *chunk = (PngChunk *)info->userCtx->allocProc(sizeof(PngChunk),info->userCtx->allocProcUserPtr); - size_t read = 0; - if (!chunk) - { - LUPNG_WARN(info,"PNG: memory allocation failed!"); - return NULL; - } - - info->userCtx->readProc((void *)&chunk->length, 4, 1, info->userCtx->readProcUserPtr); - chunk->length = swap32(chunk->length); - if (chunk->length+4 < chunk->length) - { - LUPNG_WARN(info, "PNG: chunk claims to be absurdly large"); - info->userCtx->freeProc(chunk, info->userCtx->freeProcUserPtr); - return NULL; - } - - // Store chunk type and contents in the same buffer for convenience - chunk->type = (uint8_t *)info->userCtx->allocProc(chunk->length + 4, info->userCtx->allocProcUserPtr); - if (!chunk->type) - { - LUPNG_WARN(info,"PNG: memory allocation failed!"); - info->userCtx->freeProc(chunk, info->userCtx->freeProcUserPtr); - return NULL; - } - chunk->data = chunk->type + 4; - info->userCtx->readProc((void *)chunk->type, 1, chunk->length + 4, info->userCtx->readProcUserPtr); - read = info->userCtx->readProc((void *)&chunk->crc, 4, 1, info->userCtx->readProcUserPtr); - chunk->crc = swap32(chunk->crc); - - for (int i = 0; i < 4; ++i) - { - char byte = chunk->type[i]; - if ((byte < 'a' || byte > 'z') && (byte < 'A' || byte > 'Z')) - { - LUPNG_WARN(info, "PNG: invalid chunk name, possibly unprintable"); - releaseChunk(chunk, info->userCtx); - return NULL; - } - } - if (read != 1) - { - LUPNG_WARN(info, "PNG: read error"); - releaseChunk(chunk, info->userCtx); - return NULL; - } - - if (crc(chunk->type, chunk->length+4) != chunk->crc) - { - LUPNG_WARN(info, "PNG: CRC mismatch in \'%.4s\' chunk", (char *)chunk->type); - releaseChunk(chunk, info->userCtx); - return NULL; - } - - return chunk; -} - -static LU_INLINE int handleChunk(PngInfoStruct *info, PngChunk *chunk) -{ - /* critical chunk */ - if (!(chunk->type[0] & 0x20)) - { - if (bytesEqual(chunk->type, (const uint8_t *)"IHDR", 4)) - return parseIhdr(info, chunk); - if (bytesEqual(chunk->type, (const uint8_t *)"PLTE", 4)) - return parsePlte(info, chunk); - if (bytesEqual(chunk->type, (const uint8_t *)"IDAT", 4)) - return parseIdat(info, chunk); - if (bytesEqual(chunk->type, (const uint8_t *)"IEND", 4)) - { - info->chunksFound |= PNG_IEND; - if (!(info->chunksFound & PNG_IDAT)) - { - LUPNG_WARN(info, "PNG: no IDAT chunk found"); - return PNG_ERROR; - } - return PNG_DONE; - } - } - /* ignore ancillary chunks for now */ - - return PNG_OK; -} - -LuImage *luPngReadUC(const LuUserContext *userCtx) -{ - - uint8_t signature[PNG_SIG_SIZE]; - int status = PNG_ERROR; - - PngInfoStruct info; - memset(&info, 0, sizeof(PngInfoStruct)); - info.userCtx = userCtx; - - if (!userCtx->skipSig) - { - info.userCtx->readProc((void *)signature, 1, PNG_SIG_SIZE, info.userCtx->readProcUserPtr); - status = bytesEqual(signature, PNG_SIG, PNG_SIG_SIZE) ? PNG_OK : PNG_ERROR; - } - - if (status == PNG_OK) - { - PngChunk *chunk; - while ((chunk = readChunk(&info))) - { - status = handleChunk(&info, chunk); - releaseChunk(chunk, info.userCtx); - - if (status != PNG_OK) - break; - } - } - else - LUPNG_WARN(&info, "PNG: invalid header"); - - userCtx->freeProc(info.currentScanline, userCtx->freeProcUserPtr); - userCtx->freeProc(info.previousScanline, userCtx->freeProcUserPtr); - userCtx->freeProc(info.palette, userCtx->freeProcUserPtr); - inflateEnd(&info.stream); - - if (status == PNG_DONE) - return info.img; - else - if (info.img) - luImageRelease(info.img, info.userCtx); - - return NULL; -} - -LuImage *luPngRead(PngReadProc readProc, void *userPtr, int skipSig) -{ - LuUserContext userCtx; - - luUserContextInitDefault(&userCtx); - userCtx.readProc = readProc; - userCtx.readProcUserPtr = userPtr; - userCtx.skipSig = skipSig; - return luPngReadUC(&userCtx); -} - -LuImage *luPngReadFile(const char *filename, LuUserContext *userCtx) -{ - LuUserContext tmp_userCtx; - if (userCtx == NULL) { - luUserContextInitDefault(&tmp_userCtx); - userCtx = &tmp_userCtx; - } - - LuImage *img; - FILE *f = fopen(filename,"rb"); - - if (f) { - userCtx->readProc = internalFread; - userCtx->readProcUserPtr = f; - img = luPngReadUC(userCtx); - fclose(f); - } else { - LUPNG_WARN_UC(userCtx, "PNG: failed to open '%s'", filename); - img = NULL; - } - - return img; -} - -static LU_INLINE int writeIhdr(PngInfoStruct *info) -{ - static uint8_t buf[17]; - static const uint8_t colorType[] = { - PNG_GRAYSCALE, - PNG_GRAYSCALE_ALPHA, - PNG_TRUECOLOR, - PNG_TRUECOLOR_ALPHA - }; - size_t written = 0; - PngChunk c; - - if (info->cimg->channels > 4) - { - LUPNG_WARN(info, "PNG: too many channels in image"); - return PNG_ERROR; - } - - c.length = swap32(13); - c.type = buf; /* 4 (type) + 4 + 4 + 5x1 */ - c.data = c.type + 4; - - memcpy((void *)c.type, (void *)"IHDR", 4); - *(uint32_t *)(c.data) = swap32((uint32_t)info->cimg->width); - *(uint32_t *)(c.data + 4) = swap32((uint32_t)info->cimg->height); - *(c.data + 8) = info->cimg->depth; - *(c.data + 9) = colorType[info->cimg->channels-1]; - *(c.data + 10) = 0; /* compression method */ - *(c.data + 11) = 0; /* filter method */ - *(c.data + 12) = 0; /* interlace method: none */ - - c.crc = swap32(crc(c.type, 17)); - - written += info->userCtx->writeProc((void *)&c.length, 4, 1, info->userCtx->writeProcUserPtr) * 4; - written += info->userCtx->writeProc((void *)c.type, 1, 4, info->userCtx->writeProcUserPtr); - written += info->userCtx->writeProc((void *)c.data, 1, 13, info->userCtx->writeProcUserPtr); - written += info->userCtx->writeProc((void *)&c.crc, 4, 1, info->userCtx->writeProcUserPtr) * 4; - - if (written != 25) - { - LUPNG_WARN(info, "PNG: write error"); - return PNG_ERROR; - } - - return PNG_OK; -} - -static LU_INLINE int writeIdat(PngInfoStruct *info, uint8_t *buf, size_t buflen) -{ - size_t written = 0; - PngChunk c; - - c.length = swap32((uint32_t)(buflen-4)); - c.crc = swap32(crc(buf, buflen)); - - written += info->userCtx->writeProc((void *)&c.length, 4, 1, info->userCtx->writeProcUserPtr) * 4; - written += info->userCtx->writeProc((void *)buf, 1, buflen, info->userCtx->writeProcUserPtr); - written += info->userCtx->writeProc((void *)&c.crc, 4, 1, info->userCtx->writeProcUserPtr) * 4; - - if (written != buflen+8) - { - LUPNG_WARN(info, "PNG: write error"); - return PNG_ERROR; - } - - return PNG_OK; -} - -static LU_INLINE void advanceBytep(PngInfoStruct *info, int is16bit) -{ - if (is16bit) - { - if (info->currentByte%2) - --info->currentByte; - else - info->currentByte+=3; - } - else - ++info->currentByte; -} - -static LU_INLINE size_t filterScanline(PngInfoStruct *info, - uint8_t(*f)(PngInfoStruct *info), - uint8_t filter, - uint8_t *filterCandidate, - int is16bit) -{ - size_t curSum = 0; - size_t fc; - - filterCandidate[0] = filter; - for (info->currentByte = is16bit ? 1 : 0, fc = 1; - info->currentByte < info->scanlineBytes; ++fc, advanceBytep(info, is16bit) ) - { - uint8_t val = f(info); - filterCandidate[fc] = val; - curSum += val; - } - - return curSum; -} - -/* - * Processes the input image and calls writeIdat for every BUF_SIZE compressed - * bytes. - */ -static LU_INLINE int processPixels(PngInfoStruct *info) -{ - uint8_t idatBuf[BUF_SIZE+4] = {'I', 'D', 'A', 'T'}; - uint8_t *compressed = idatBuf+4; - uint8_t *filterCandidate = (uint8_t *)info->userCtx->allocProc(info->scanlineBytes+1, info->userCtx->allocProcUserPtr); - uint8_t *bestCandidate = (uint8_t *)info->userCtx->allocProc(info->scanlineBytes+1, info->userCtx->allocProcUserPtr); - size_t minSum = (size_t)-1, curSum = 0; - int status = Z_OK; - int is16bit = info->cimg->depth == 16; - - if (!filterCandidate || !bestCandidate) - { - LUPNG_WARN(info, "PNG: memory allocation failed!"); - } - - memset(&(info->stream), 0, sizeof(info->stream)); - if(deflateInit(&(info->stream), info->userCtx->compressionLevel) != Z_OK) - { - LUPNG_WARN(info, "PNG: deflateInit failed!"); - info->userCtx->freeProc(filterCandidate, info->userCtx->freeProcUserPtr); - info->userCtx->freeProc(bestCandidate, info->userCtx->freeProcUserPtr); - return PNG_ERROR; - } - - info->stream.avail_out = BUF_SIZE; - info->stream.next_out = compressed; - - for (info->currentRow = 0; info->currentRow < info->cimg->height; - ++info->currentRow) - { - int flush = (info->currentRow < info->cimg->height-1) ? - Z_NO_FLUSH : Z_FINISH; - minSum = (size_t)-1; - - /* - * 1st time it doesn't matter, the filters never look at the previous - * scanline when processing row 0. And next time it'll be valid. - */ - info->previousScanline = info->currentScanline; - info->currentScanline = info->cimg->data + (info->currentRow*info->scanlineBytes); - - /* - * Try to choose the best filter for each scanline. - * Breaks in case of overflow, but hey it's just a heuristic. - */ - for (info->currentFilter = PNG_FILTER_NONE; info->currentFilter <= PNG_FILTER_PAETH; ++info->currentFilter) - { - - switch (info->currentFilter) - { - case PNG_FILTER_NONE: - curSum = filterScanline(info, none, PNG_FILTER_NONE, filterCandidate, is16bit); - break; - - case PNG_FILTER_SUB: - curSum = filterScanline(info, sub, PNG_FILTER_SUB, filterCandidate, is16bit); - break; - - case PNG_FILTER_UP: - curSum = filterScanline(info, up, PNG_FILTER_UP, filterCandidate, is16bit); - break; - - case PNG_FILTER_AVERAGE: - curSum = filterScanline(info, average, PNG_FILTER_AVERAGE, filterCandidate, is16bit); - break; - - case PNG_FILTER_PAETH: - curSum = filterScanline(info, paeth, PNG_FILTER_PAETH, filterCandidate, is16bit); - break; - - default: - break; - } - - if (curSum < minSum || !info->currentFilter) - { - uint8_t *tmp = bestCandidate; - bestCandidate = filterCandidate; - filterCandidate = tmp; - minSum = curSum; - } - } - - info->stream.avail_in = (unsigned int)info->scanlineBytes+1; - info->stream.next_in = bestCandidate; - - /* compress bestCandidate */ - do - { - status = deflate(&info->stream, flush); - - if (info->stream.avail_out < BUF_SIZE) - { - writeIdat(info, idatBuf, BUF_SIZE-info->stream.avail_out+4); - info->stream.next_out = compressed; - info->stream.avail_out = BUF_SIZE; - } - } while ((flush == Z_FINISH && status != Z_STREAM_END) - || (flush == Z_NO_FLUSH && info->stream.avail_in)); - } - - info->userCtx->freeProc(filterCandidate, info->userCtx->freeProcUserPtr); - info->userCtx->freeProc(bestCandidate, info->userCtx->freeProcUserPtr); - - return PNG_OK; -} - -static LU_INLINE int writeIend(PngInfoStruct *info) -{ - PngChunk c = { 0, (uint8_t *)"IEND", 0, 0 }; - size_t written = 0; - c.crc = swap32(crc(c.type, 4)); - - written += info->userCtx->writeProc((void *)&c.length, 4, 1, info->userCtx->writeProcUserPtr) * 4; - written += info->userCtx->writeProc((void *)c.type, 1, 4, info->userCtx->writeProcUserPtr); - written += info->userCtx->writeProc((void *)&c.crc, 4, 1, info->userCtx->writeProcUserPtr) * 4; - - if (written != 12) - { - LUPNG_WARN(info, "PNG: write error"); - return PNG_ERROR; - } - - return PNG_OK; -} - -int luPngWriteUC(const LuUserContext *userCtx, const LuImage *img) -{ - PngInfoStruct info; - memset(&info, 0, sizeof(PngInfoStruct)); - info.userCtx = userCtx; - info.cimg = img; - info.bytesPerPixel = (info.cimg->channels * info.cimg->depth) >> 3; - - if (info.userCtx->writeProc((void *)PNG_SIG, 1, PNG_SIG_SIZE, info.userCtx->writeProcUserPtr) != PNG_SIG_SIZE) - { - LUPNG_WARN(&info, "PNG: write error"); - return PNG_ERROR; - } - - if (writeIhdr(&info) != PNG_OK) - return PNG_ERROR; - - info.scanlineBytes = (info.cimg->depth >> 3) * info.cimg->channels * info.cimg->width; - if (processPixels(&info) != PNG_OK) - { - deflateEnd(&(info.stream)); - return PNG_ERROR; - } - - deflateEnd(&(info.stream)); - return writeIend(&info); -} - -int luPngWrite(PngWriteProc writeProc, void *userPtr, const LuImage *img) -{ - LuUserContext userCtx; - - luUserContextInitDefault(&userCtx); - userCtx.writeProc = writeProc; - userCtx.writeProcUserPtr = userPtr; - return luPngWriteUC(&userCtx, img); -} - -int luPngWriteFile(const char *filename, const LuImage *img) -{ - LuUserContext userCtx; - FILE *f; - - if (!img) - { - return PNG_ERROR; - } - - f = fopen(filename,"wb"); - luUserContextInitDefault(&userCtx); - if (f) - { - userCtx.writeProc = internalFwrite; - userCtx.writeProcUserPtr = f; - luPngWriteUC(&userCtx, img); - fclose(f); - } - else - { - LUPNG_WARN_UC(&userCtx, "PNG: failed to open '%s'", filename); - return PNG_ERROR; - } - - return PNG_OK; -} - -void luImageRelease(LuImage *img, const LuUserContext *userCtx) -{ - LuUserContext ucDefault; - - if (userCtx == NULL) - { - luUserContextInitDefault(&ucDefault); - userCtx = &ucDefault; - } - - userCtx->freeProc(img->data, userCtx->freeProcUserPtr); - if (userCtx->overrideImage != img) - userCtx->freeProc(img, userCtx->freeProcUserPtr); -} - -LuImage *luImageCreate(size_t width, size_t height, uint8_t channels, uint8_t depth, - uint8_t *buffer, const LuUserContext *userCtx) -{ - LuImage *img; - LuUserContext ucDefault; - - if (userCtx == NULL) { - luUserContextInitDefault(&ucDefault); - userCtx = &ucDefault; - } - - if (depth != 8 && depth != 16) - { - LUPNG_WARN_UC(userCtx,"Image: only bit depths 8 and 16 are supported!"); - return NULL; - } - if (width > 0x7FFFFFFF || height > 0x7FFFFFFF) { - LUPNG_WARN_UC(userCtx, "Image: only 32 bit signed image dimensions are supported!"); - return NULL; - } - - if (userCtx->overrideImage) - img = userCtx->overrideImage; - else - img = (LuImage *)userCtx->allocProc(sizeof(LuImage), userCtx->allocProcUserPtr); - if (!img) - return NULL; - - img->width = (int32_t)width; - img->height = (int32_t)height; - img->channels = channels; - img->depth = depth; - img->dataSize = (size_t)((depth >> 3) * width * height * channels); - if (buffer) - img->data = buffer; - else - img->data = (uint8_t *)userCtx->allocProc(img->dataSize, userCtx->allocProcUserPtr); - - if (img->data == NULL) - { - luImageRelease(img, userCtx); - return NULL; - } - - return img; -} - -uint8_t *luImageExtractBufAndRelease(LuImage *img, const LuUserContext *userCtx) -{ - uint8_t *data; - LuUserContext ucDefault; - - if (userCtx == NULL) { - luUserContextInitDefault(&ucDefault); - userCtx = &ucDefault; - } - - if (img) - { - data = img->data; - img->data = NULL; - luImageRelease(img, userCtx); - } - else - { - data = NULL; - } - - return data; -} - -void luUserContextInitDefault(LuUserContext *userCtx) -{ - userCtx->readProc=NULL; - userCtx->readProcUserPtr=NULL; - userCtx->skipSig = 0; - - userCtx->writeProc=NULL; - userCtx->writeProcUserPtr=NULL; - userCtx->compressionLevel=Z_DEFAULT_COMPRESSION; - - userCtx->allocProc=internalMalloc; - userCtx->allocProcUserPtr=NULL; - userCtx->freeProc=internalFree; - userCtx->freeProcUserPtr=NULL; - - userCtx->warnProc=internalPrintf; - userCtx->warnProcUserPtr=(void*)stderr; - - userCtx->overrideImage=NULL; -} \ No newline at end of file diff --git a/tests/regression/tex/lupng.h b/tests/regression/tex/lupng.h deleted file mode 100644 index 5c3f8465..00000000 --- a/tests/regression/tex/lupng.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Jan Solanti - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma once - -#if defined(_MSC_VER) && (_MSC_VER < 1600) -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -#else -#include -#include -#endif - -typedef struct { - int32_t width; - int32_t height; - uint8_t channels; - uint8_t depth; /* must be 8 or 16 */ - size_t dataSize; - uint8_t *data; -} LuImage; - -typedef size_t (*PngReadProc)(void *outPtr, size_t size, size_t count, void *userPtr); -typedef size_t (*PngWriteProc)(const void *inPtr, size_t size, size_t count, void *userPtr); -typedef void* (*PngAllocProc)(size_t size, void *userPtr); -typedef void (*PngFreeProc)(void *ptr, void *userPtr); -typedef void (*PngWarnProc)(void *userPtr, const char *fmt, ...); - -typedef struct { - /* loader */ - PngReadProc readProc; - void *readProcUserPtr; - int skipSig; - - /* writer */ - PngWriteProc writeProc; - void *writeProcUserPtr; - int compressionLevel; - - /* memory allocation */ - PngAllocProc allocProc; - void *allocProcUserPtr; - PngFreeProc freeProc; - void *freeProcUserPtr; - - /* warnings/error output */ - PngWarnProc warnProc; /* set to NULL to disable output altogether */ - void *warnProcUserPtr; - - /* special case: avoid allocating a LuImage when loading or creating - * an image, just use this one */ - LuImage *overrideImage; -} LuUserContext; - -/** - * Initializes a LuUserContext to use the defaul malloc implementation. - * - * @param userCtx the LuUserContext to initialize - */ -void luUserContextInitDefault(LuUserContext *userCtx); - -/** - * Creates a new Image object with the specified attributes. - * The data store of the Image is allocated but its contents are undefined. - * Only 8 and 16 bits deep images with 1-4 channels are supported. - * - * @param buffer pointer to an existing buffer (which may already contain the - * image data), or NULL to internally allocate a new buffer - * @param userCtx the user context (with the memory allocator function - * pointers to use), or NULL to use the default allocator - * (malloc). - */ -LuImage *luImageCreate(size_t width, size_t height, uint8_t channels, uint8_t depth, - uint8_t *buffer, const LuUserContext *usrCtx); - -/** - * Releases the memory associated with the given Image object. - * - * @param userCtx the user context (with the memory deallocator function - * pointers to use), or NULL to use the default deallocator - * (free). The deallocator should match the ones used for - * allocation. - */ -void luImageRelease(LuImage *img, const LuUserContext *usrCtx); - -/** - * Extracts the raw image buffer form a LuImage and releases the - * then-orphaned LuImage object. This can be used if you want to use - * the image data in your own structures. - * - * @param userCtx the user context (with the memory deallocator function - * pointers to use), or NULL to use the default deallocator - * (free). The deallocator should match the ones used for - * allocation. - */ -uint8_t *luImageExtractBufAndRelease(LuImage *img, const LuUserContext *userCtx); - -/** - * Decodes a PNG image from a file - * - * @param filename the file name (optionally with full path) to read from. - * @param userCtx the user context (with the memory allocator function - * pointers to use), or NULL to use the default allocator - * (malloc). - */ -LuImage *luPngReadFile(const char *filename, LuUserContext *userCtx); - -/** - * Decodes a PNG image with the provided read function into a LuImage struct - * - * @param readProc a function pointer to a user-defined function to use for - * reading the PNG data. - * @param userPtr an opaque pointer provided as an argument to readProc - * @param skipSig don't verify PNG signature - the bytes have already been - * removed from the input stream - */ -LuImage *luPngRead(PngReadProc readProc, void *userPtr, int skipSig); - -/** - * Decodes a PNG image with the provided user context into a LuImage struct - * - * @param userCtx the LuUserContext to use - */ -LuImage *luPngReadUC(const LuUserContext *userCtx); - -/** - * Encodes a LuImage struct to PNG and writes it out to a file. - * - * @param filename the file name (optionally with full path) to write to. - * Existing files will be overwritten! - * @param img the LuImage to encode - */ -int luPngWriteFile(const char *filename, const LuImage *img); - -/** - * Encodes a LuImage struct to PNG and writes it out using a user-defined write - * function. - * - * @param writeProc a function pointer to a user-defined function that will be - * used for writing the final PNG data. - * @param userPtr an opaque pointer provided as an argument to writeProc - * @param img the LuImage to encode - */ -int luPngWrite(PngWriteProc writeProc, void *userPtr, const LuImage *img); - -/** - * Encodes a LuImage struct to PNG and writes it out with the provided user - * context. - * - * @param userCtx the LuUserContext to use - * @param img the LuImage to encode - */ -int luPngWriteUC(const LuUserContext *userCtx, const LuImage *img); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/tests/regression/tex/main.cpp b/tests/regression/tex/main.cpp index ffdfb593..5ea47cc0 100644 --- a/tests/regression/tex/main.cpp +++ b/tests/regression/tex/main.cpp @@ -9,6 +9,8 @@ #include "common.h" #include "utils.h" +using namespace cocogfx; + #define RT_CHECK(_expr) \ do { \ int _ret = _expr; \ @@ -29,7 +31,6 @@ int filter = 0; // 0-> point, 1->bilinear, 2->trilinear float scale = 1.0f; int format = 0; bool use_sw = false; -float lod = 1.0f; // >= 1.0f ePixelFormat eformat = FORMAT_A8R8G8B8; vx_device_h device = nullptr; @@ -37,18 +38,18 @@ vx_buffer_h buffer = nullptr; static void show_usage() { std::cout << "Vortex Texture Test." << std::endl; - std::cout << "Usage: [-k: kernel] [-i image] [-o image] [-s scale] [-w wrap] [-f format] [-g filter] [-l lod] [-z no_hw] [-h: help]" << std::endl; + std::cout << "Usage: [-k: kernel] [-i image] [-o image] [-s scale] [-w wrap] [-f format] [-g filter] [-z no_hw] [-h: help]" << std::endl; } static void parse_args(int argc, char **argv) { int c; - while ((c = getopt(argc, argv, "zi:o:k:w:f:g:h?")) != -1) { + while ((c = getopt(argc, argv, "zi:o:k:w:f:g:s:h?")) != -1) { switch (c) { case 'i': - input_file = optarg; + input_file = optarg; break; case 'o': - output_file = optarg; + output_file = optarg; break; case 's': scale = std::stof(optarg, NULL); @@ -56,9 +57,6 @@ static void parse_args(int argc, char **argv) { case 'w': wrap = std::atoi(optarg); break; - case 'l': - lod = std::stof(optarg, NULL); - break; case 'z': use_sw = true; break; @@ -67,9 +65,11 @@ static void parse_args(int argc, char **argv) { switch (format) { case 0: eformat = FORMAT_A8R8G8B8; break; case 1: eformat = FORMAT_R5G6B5; break; - case 2: eformat = FORMAT_R4G4B4A4; break; - case 3: eformat = FORMAT_L8; break; - case 4: eformat = FORMAT_A8; break; + case 2: eformat = FORMAT_A1R5G5B5; break; + case 3: eformat = FORMAT_A4R4G4B4; break; + case 4: eformat = FORMAT_A8L8; break; + case 5: eformat = FORMAT_L8; break; + case 6: eformat = FORMAT_A8; break; default: std::cout << "Error: invalid format: " << format << std::endl; exit(1); @@ -105,7 +105,9 @@ void cleanup() { int run_test(const kernel_arg_t& kernel_arg, uint32_t buf_size, uint32_t width, - uint32_t height) { + uint32_t height, + uint32_t bpp) { + (void)bpp; auto time_start = std::chrono::high_resolution_clock::now(); // start device @@ -132,7 +134,7 @@ int run_test(const kernel_arg_t& kernel_arg, // save output image std::cout << "save output image" << std::endl; - //dump_image(dst_pixels, width, height, bpp); + //dump_image(dst_pixels, width, height, bpp); RT_CHECK(SaveImage(output_file, FORMAT_A8R8G8B8, dst_pixels, width, height)); return 0; @@ -151,11 +153,9 @@ int main(int argc, char *argv[]) { { std::vector staging; RT_CHECK(LoadImage(input_file, eformat, staging, &src_width, &src_height)); - - RT_CHECK(GenerateMipmaps(src_pixels, mip_offsets, staging, eformat, src_width, src_height)); - - //uint32_t src_bpp = Format::GetInfo(eformat).BytePerPixel; - //dump_image(src_pixels, src_pixels.size() / src_bpp, 1, src_bpp); + uint32_t src_bpp = GetInfo(eformat).BytePerPixel; + //dump_image(staging, src_width, src_height, src_bpp); + RT_CHECK(GenerateMipmaps(src_pixels, mip_offsets, staging, eformat, src_width, src_height, src_width * src_bpp)); } // check power of two support @@ -167,12 +167,6 @@ int main(int argc, char *argv[]) { uint32_t src_logwidth = log2ceil(src_width); uint32_t src_logheight = log2ceil(src_height); - uint32_t src_max_lod = std::max(src_logwidth, src_logheight); - if (lod > src_max_lod) { - std::cout << "Error: out-of-bound level-of-detail: lod=" << lod << ", source image=" << src_max_lod << std::endl; - return -1; - } - uint32_t src_bufsize = src_pixels.size(); uint32_t dst_width = (uint32_t)(src_width * scale); @@ -227,7 +221,6 @@ int main(int argc, char *argv[]) { kernel_arg.src_logwidth = src_logwidth; kernel_arg.src_logheight = src_logheight; kernel_arg.src_addr = src_addr; - kernel_arg.lod = lod; for (uint32_t i = 0; i < mip_offsets.size(); ++i) { assert(i < TEX_LOD_MAX); @@ -267,7 +260,7 @@ int main(int argc, char *argv[]) { // run tests std::cout << "run tests" << std::endl; - RT_CHECK(run_test(kernel_arg, dst_bufsize, dst_width, dst_height)); + RT_CHECK(run_test(kernel_arg, dst_bufsize, dst_width, dst_height, dst_bpp)); // cleanup std::cout << "cleanup" << std::endl; diff --git a/tests/regression/tex/surfacedesc.h b/tests/regression/tex/surfacedesc.h deleted file mode 100644 index cf303584..00000000 --- a/tests/regression/tex/surfacedesc.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright (c) Blaise Tine. All rights reserved. -// -// -// Use of this sample source code is subject to the terms of the Microsoft -// license agreement under which you licensed this sample source code. If -// you did not accept the terms of the license agreement, you are not -// authorized to use this sample source code. For the terms of the license, -// please see the license agreement between you and Microsoft or, if applicable, -// see the LICENSE.RTF on your install media or the root of your tools -// installation. -// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR -// INDEMNITIES. -// -#pragma once - -#include "format.h" - -struct SurfaceDesc { - ePixelFormat Format; - uint8_t *pBits; - uint32_t Width; - uint32_t Height; - uint32_t Pitch; -}; \ No newline at end of file diff --git a/tests/regression/tex/texsw.h b/tests/regression/tex/texsw.h index c9961ab8..2eecb079 100644 --- a/tests/regression/tex/texsw.h +++ b/tests/regression/tex/texsw.h @@ -4,14 +4,30 @@ #include #include "common.h" -inline uint32_t texel_read(uint8_t* address, uint32_t stride) { +using namespace cocogfx; + +inline void texel_read(uint32_t* texels, + uint8_t** addresses, + uint32_t count, + uint32_t stride) { switch (stride) { - case 1: return *(uint8_t*)address; - case 2: return *(uint16_t*)address; - case 4: return *(uint32_t*)address; + case 1: + for (uint32_t i = 0; i < count; ++i) { + texels[i] = *(uint8_t*)addresses[i]; + } + break; + case 2: + for (uint32_t i = 0; i < count; ++i) { + texels[i] = *(uint16_t*)addresses[i]; + } + break; + case 4: + for (uint32_t i = 0; i < count; ++i) { + texels[i] = *(uint32_t*)addresses[i]; + } + break; default: std::abort(); - return 0; } } @@ -34,32 +50,35 @@ inline uint32_t vx_tex_sw(kernel_arg_t* state, // addressing uint32_t offset00, offset01, offset10, offset11; uint32_t alpha, beta; + uint8_t* addr[4]; + uint32_t texel[4]; + TexAddressLinear(xu, xv, log_width, log_height, wrapu, wrapv, &offset00, &offset01, &offset10, &offset11, &alpha, &beta); - uint8_t* addr00 = base_addr + offset00 * stride; - uint8_t* addr01 = base_addr + offset01 * stride; - uint8_t* addr10 = base_addr + offset10 * stride; - uint8_t* addr11 = base_addr + offset11 * stride; + addr[0] = base_addr + offset00 * stride; + addr[1] = base_addr + offset01 * stride; + addr[2] = base_addr + offset10 * stride; + addr[3] = base_addr + offset11 * stride; - // memory lookup - uint32_t texel00 = texel_read(addr00, stride); - uint32_t texel01 = texel_read(addr01, stride); - uint32_t texel10 = texel_read(addr10, stride); - uint32_t texel11 = texel_read(addr11, stride); + // memory fetch + texel_read(texel, addr, 4, stride); // filtering color = TexFilterLinear( - format, texel00, texel01, texel10, texel11, alpha, beta); + format, texel[0], texel[1], texel[2], texel[3], alpha, beta); } else { // addressing uint32_t offset; + uint8_t* addr; + uint32_t texel; + TexAddressPoint(xu, xv, log_width, log_height, wrapu, wrapv, &offset); - uint8_t* addr = base_addr + offset * stride; + addr = base_addr + offset * stride; - // memory lookup - uint32_t texel = texel_read(addr, stride); + // memory fetch + texel_read(&texel, &addr, 1, stride); // filtering color = TexFilterPoint(format, texel); @@ -67,56 +86,40 @@ inline uint32_t vx_tex_sw(kernel_arg_t* state, return color; } -inline uint32_t tex_load_hw(kernel_arg_t* state, - Fixed xu, - Fixed xv, - Fixed<16> xlod) { +inline uint32_t tex_load(kernel_arg_t* state, + Fixed xu, + Fixed xv, + Fixed<16> xj) { uint32_t color; - int32_t ilod = std::max(xlod.data(), Fixed<16>::ONE); - uint32_t lod = std::min(log2floor(ilod) - 16, TEX_LOD_MAX); + uint32_t j = std::max(xj.data(), Fixed<16>::ONE); + uint32_t l = std::min(log2floor(j) - 16, TEX_LOD_MAX); if (state->filter == 2) { - uint32_t lod_n = std::min(lod + 1, TEX_LOD_MAX); - uint32_t frac = ilod >> (lod + 16 - 8); - uint32_t texel0 = vx_tex(0, xu.data(), xv.data(), lod); - uint32_t texel1 = vx_tex(0, xu.data(), xv.data(), lod_n); + uint32_t ln = std::min(l + 1, TEX_LOD_MAX); + uint32_t f = (j - (1 << (l + 16))) >> (l + 16 - 8); + uint32_t texel0, texel1; + if (state->use_sw) { + texel0 = vx_tex_sw(state, xu, xv, l); + texel1 = vx_tex_sw(state, xu, xv, ln); + } else { + texel0 = vx_tex(0, xu.data(), xv.data(), l); + texel1 = vx_tex(0, xu.data(), xv.data(), ln); + } uint32_t cl, ch; { - uint32_t c0l, c0h; - uint32_t c1l, c1h; - Unpack8888(TexFormat::R8G8B8A8, texel0, &c0l, &c0h); - Unpack8888(TexFormat::R8G8B8A8, texel1, &c1l, &c1h); - Lerp8888(c0l, c0h, c1l, c1h, frac, &cl, &ch); + uint32_t c0l, c0h, c1l, c1h; + Unpack8888(texel0, &c0l, &c0h); + Unpack8888(texel1, &c1l, &c1h); + cl = Lerp8888(c0l, c1l, f); + ch = Lerp8888(c0h, c1h, f); } - color = Pack8888(TexFormat::R8G8B8A8, cl, ch); + color = Pack8888(cl, ch); + //vx_printf("j=0x%x, l=%d, ln=%d, f=%d, texel0=0x%x, texel1=0x%x, color=0x%x\n", j, l, ln, f, texel0, texel1, color); } else { - color = vx_tex(0, xu.data(), xv.data(), lod); - } - return color; -} - -inline uint32_t tex_load_sw(kernel_arg_t* state, - Fixed xu, - Fixed xv, - Fixed<16> xlod) { - uint32_t color; - int32_t ilod = std::max(xlod.data(), Fixed<16>::ONE); - uint32_t lod = std::min(log2floor(ilod) - 16, TEX_LOD_MAX); - if (state->filter == 2) { - uint32_t lod_n = std::min(lod + 1, TEX_LOD_MAX); - uint32_t frac = ilod >> (lod + 16 - 8); - uint32_t texel0 = vx_tex_sw(state, xu, xv, lod); - uint32_t texel1 = vx_tex_sw(state, xu, xv, lod_n); - uint32_t cl, ch; - { - uint32_t c0l, c0h; - uint32_t c1l, c1h; - Unpack8888(TexFormat::R8G8B8A8, texel0, &c0l, &c0h); - Unpack8888(TexFormat::R8G8B8A8, texel1, &c1l, &c1h); - Lerp8888(c0l, c0h, c1l, c1h, frac, &cl, &ch); + if (state->use_sw) { + color = vx_tex_sw(state, xu, xv, l); + } else { + color = vx_tex(0, xu.data(), xv.data(), l); } - color = Pack8888(TexFormat::R8G8B8A8, cl, ch); - } else { - color = vx_tex_sw(state, xu, xv, lod); } return color; } \ No newline at end of file diff --git a/tests/regression/tex/tga.cpp b/tests/regression/tex/tga.cpp deleted file mode 100644 index 62641587..00000000 --- a/tests/regression/tex/tga.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "tga.h" -#include -#include -#include "format.h" - -struct __attribute__((__packed__)) tga_header_t { - int8_t idlength; - int8_t colormaptype; - int8_t imagetype; - int16_t colormaporigin; - int16_t colormaplength; - int8_t colormapdepth; - int16_t xoffset; - int16_t yoffset; - int16_t width; - int16_t height; - int8_t bitsperpixel; - int8_t imagedescriptor; -}; - -int LoadTGA(const char *filename, - std::vector &pixels, - uint32_t *width, - uint32_t *height, - uint32_t *bpp) { - std::ifstream ifs(filename, std::ios::in | std::ios::binary); - if (!ifs.is_open()) { - std::cerr << "couldn't open file: " << filename << "!" << std::endl; - return -1; - } - - tga_header_t header; - ifs.read(reinterpret_cast(&header), sizeof(tga_header_t)); - if (ifs.fail()) { - std::cerr << "invalid TGA file header!" << std::endl; - return -1; - } - - if (header.imagetype != 2) { - std::cerr << "unsupported TGA encoding format!" << std::endl; - return -1; - } - - ifs.seekg(header.idlength, std::ios::cur); // skip string - if (ifs.fail()) { - std::cerr << "invalid TGA file!" << std::endl; - return -1; - } - - switch (header.bitsperpixel) { - case 16: - case 24: - case 32: { - // Read pixels data - auto stride = header.bitsperpixel / 8; - pixels.resize(stride * header.width * header.height); - ifs.read((char*)pixels.data(), pixels.size()); - if (ifs.fail()) { - std::cerr << "invalid TGA file!" << std::endl; - return -1; - } - *bpp = stride; - break; - } - default: - std::cerr << "unsupported TGA bitsperpixel!" << std::endl; - return -1; - } - - *width = header.width; - *height = header.height; - - return 0; -} - -int SaveTGA(const char *filename, - const std::vector &pixels, - uint32_t width, - uint32_t height, - uint32_t bpp) { - std::ofstream ofs(filename, std::ios::out | std::ios::binary); - if (!ofs.is_open()) { - std::cerr << "couldn't create file: " << filename << "!" << std::endl; - return -1; - } - - if (bpp < 2 || bpp > 4) { - std::cerr << "unsupported pixel stride: " << bpp << "!" << std::endl; - return -1; - } - - tga_header_t header; - header.idlength = 0; - header.colormaptype = 0; // no palette - header.imagetype = 2; // color mapped data - header.colormaporigin = 0; - header.colormaplength = 0; - header.colormapdepth = 0; - header.xoffset = 0; - header.yoffset = 0; - header.width = width; - header.height = height; - header.bitsperpixel = bpp * 8; - header.imagedescriptor = 0; - - // write header - ofs.write(reinterpret_cast(&header), sizeof(tga_header_t)); - - // write pixel data - uint32_t pitch = bpp * width; - const uint8_t* pixel_bytes = pixels.data() + (height - 1) * pitch; - for (uint32_t y = 0; y < height; ++y) { - const uint8_t* pixel_row = pixel_bytes; - for (uint32_t x = 0; x < width; ++x) { - ofs.write((const char*)pixel_row, bpp); - pixel_row += bpp; - } - pixel_bytes -= pitch; - } - - return 0; -} \ No newline at end of file diff --git a/tests/regression/tex/tga.h b/tests/regression/tex/tga.h deleted file mode 100644 index 24b92a75..00000000 --- a/tests/regression/tex/tga.h +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include - -int LoadTGA(const char *filename, - std::vector &pixels, - uint32_t *width, - uint32_t *height, - uint32_t *bpp); - -int SaveTGA(const char *filename, - const std::vector &pixels, - uint32_t width, - uint32_t height, - uint32_t bpp); \ No newline at end of file diff --git a/tests/regression/tex/utils.cpp b/tests/regression/tex/utils.cpp index 81a47158..e76b72f9 100644 --- a/tests/regression/tex/utils.cpp +++ b/tests/regression/tex/utils.cpp @@ -1,10 +1,12 @@ #include "utils.h" #include -#include -#include "blitter.h" -#include "format.h" -#include "tga.h" -#include "lupng.h" +#include +#include +#include +#include +#include + +using namespace cocogfx; std::string getFileExt(const std::string& str) { auto i = str.rfind('.'); @@ -41,22 +43,9 @@ int LoadImage(const char *filename, return ret; } else if (iequals(ext, "png")) { - auto image = luPngReadFile(filename, NULL); - if (image == NULL) - return -1; - if (image->depth != 8 - || (image->channels != 3 - && image->channels != 4)) { - luImageRelease(image, NULL); - std::cerr << "invalid png file format!" << std::endl; - return -1; - } - pixels.resize(image->channels * image->width * image->height); - memcpy(pixels.data(), image->data, pixels.size()); - img_width = image->width; - img_height = image->height; - img_bpp = image->channels; - luImageRelease(image, NULL); + int ret = LoadPNG(filename, pixels, &img_width, &img_height, &img_bpp); + if (ret) + return ret; } else { std::cerr << "invalid file extension: " << ext << "!" << std::endl; return -1; @@ -83,7 +72,7 @@ int LoadImage(const char *filename, if (img_format != format) { // format conversion to RGBA std::vector staging; - int ret = ConvertImage(staging, pixels, img_width, img_height, img_format, format); + int ret = ConvertImage(staging, format, pixels, img_format, img_width, img_height, img_width * img_bpp); if (ret) return ret; pixels.swap(staging); @@ -100,19 +89,13 @@ int SaveImage(const char *filename, const std::vector &pixels, uint32_t width, uint32_t height) { - uint32_t bpp = Format::GetInfo(format).BytePerPixel; + uint32_t bpp = GetInfo(format).BytePerPixel; auto ext = getFileExt(filename); if (iequals(ext, "tga")) { return SaveTGA(filename, pixels, width, height, bpp); } else if (iequals(ext, "png")) { - LuImage image; - image.width = width; - image.height = height; - image.depth = 8; - image.channels = bpp; - image.data = (uint8_t*)pixels.data(); - return luPngWriteFile(filename, &image); + return SavePNG(filename, pixels, width, height, bpp); } else { std::cerr << "invalid file extension: " << ext << "!" << std::endl; return -1; @@ -132,171 +115,8 @@ void dump_image(const std::vector& pixels, uint32_t width, uint32_t hei pixel32 |= pixel8 << (b * 8); } if (x) std::cout << ", "; - std::cout << std::hex << pixel32; + std::cout << std::hex << std::setw(bpp * 2) << std::setfill('0') << pixel32; } std::cout << std::endl; } -} - -int CopyBuffers(SurfaceDesc &dstDesc, - int32_t dstOffsetX, - int32_t dstOffsetY, - uint32_t copyWidth, - uint32_t copyHeight, - const SurfaceDesc &srcDesc, - int32_t srcOffsetX, - int32_t srcOffsetY) { - - static const BlitTable s_blitTable; - - if ((srcOffsetX >= (int32_t)srcDesc.Width) || (srcOffsetY >= (int32_t)srcDesc.Height) || - (dstOffsetX >= (int32_t)dstDesc.Width) || (dstOffsetY >= (int32_t)dstDesc.Height)) { - return -1; - } - - if (copyWidth > dstDesc.Width) { - copyWidth = dstDesc.Width; - } - - if (copyWidth > srcDesc.Width) { - copyWidth = srcDesc.Width; - } - - if (copyHeight > dstDesc.Height) { - copyHeight = dstDesc.Height; - } - - if (copyHeight > srcDesc.Height) { - copyHeight = srcDesc.Height; - } - - return s_blitTable.get(srcDesc.Format, dstDesc.Format)( - dstDesc, dstOffsetX, dstOffsetY, copyWidth, copyHeight, srcDesc, - srcOffsetX, srcOffsetY); -} - -int ConvertImage(std::vector& dst_pixels, - const std::vector& src_pixels, - uint32_t width, - uint32_t height, - ePixelFormat src_format, - ePixelFormat dst_format) { - - uint32_t src_pitch = Format::GetInfo(src_format).BytePerPixel * width; - uint32_t dst_pitch = Format::GetInfo(dst_format).BytePerPixel * width; - - dst_pixels.resize(dst_pitch * height); - - SurfaceDesc srcDesc{src_format, (uint8_t*)src_pixels.data(), width, height, src_pitch}; - SurfaceDesc dstDesc{dst_format, dst_pixels.data(), width, height, dst_pitch}; - - return CopyBuffers(dstDesc, 0, 0, width, height, srcDesc, 0, 0); -} - - - -int GenerateMipmaps(std::vector& dst_pixels, - std::vector& mip_offsets, - const std::vector& src_pixels, - ePixelFormat format, - uint32_t src_width, - uint32_t src_height) { - std::vector src_staging, dst_staging; - const std::vector *pSrcPixels; - std::vector *pDstPixels; - - // convert source image if needed - bool need_conversion = (format != FORMAT_A8R8G8B8); - if (need_conversion) { - ConvertImage(src_staging, src_pixels, src_width, src_height, format, FORMAT_A8R8G8B8); - pSrcPixels = &src_staging; - pDstPixels = &dst_staging; - } else { - pSrcPixels = &src_pixels; - pDstPixels = &dst_pixels; - } - - uint32_t src_logwidth = log2ceil(src_width); - uint32_t src_logheight = log2ceil(src_height); - uint32_t max_lod = std::max(src_logwidth, src_logheight) + 1; - - mip_offsets.resize(max_lod); - - // Calculate mipmaps buffer size - uint32_t dst_height = 1; - uint32_t dst_width = 0; - for (uint32_t lod = 0, w = src_width, h = src_height; lod < max_lod; ++lod) { - assert((w > 0) || (w > 0)); - uint32_t pw = std::max(w, 1); - uint32_t ph = std::max(h, 1); - mip_offsets.at(lod) = dst_width; - dst_width += pw * ph; - w >>= 1; - h >>= 1; - } - - // allocate mipmap - pDstPixels->resize(dst_width * 4); - - // generate mipmaps - { - auto pSrc = reinterpret_cast(pSrcPixels->data()); - auto pDst = reinterpret_cast(pDstPixels->data()); - - // copy level 0 - memcpy(pDst, pSrc, pSrcPixels->size()); - assert(pSrcPixels->size() == 4 * src_width * src_height); - pSrc = pDst; - pDst += src_width * src_height; - - // copy lower levels - for (uint32_t lod = 1, w = (src_width/2), h = (src_height/2); lod < max_lod;) { - assert((w > 0) || (w > 0)); - uint32_t pw = std::max(w, 1); - uint32_t ph = std::max(h, 1); - for (uint32_t y = 0; y < pw; ++y) { - auto v0 = 2 * y; - auto v1 = 2 * y + ((ph > 1) ? 1 : 0); - auto pSrc0 = pSrc + v0 * (2 * pw); - auto pSrc1 = pSrc + v1 * (2 * pw); - - for (uint32_t x = 0; x 1) ? 1 : 0); - - auto c00 = Format::ConvertFrom(pSrc0 + u0); - auto c01 = Format::ConvertFrom(pSrc0 + u1); - auto c10 = Format::ConvertFrom(pSrc1 + u0); - auto c11 = Format::ConvertFrom(pSrc1 + u1); - - const ColorARGB color((c00.a + c01.a + c10.a + c11.a+2) >> 2, - (c00.r + c01.r + c10.r + c11.r+2) >> 2, - (c00.g + c01.g + c10.g + c11.g+2) >> 2, - (c00.b + c01.b + c10.b + c11.b+2) >> 2); - - uint32_t ncolor; - Format::ConvertTo(&ncolor, color); - pDst[x + y * pw] = ncolor; - } - } - ++lod; - pSrc = pDst; - pDst += pw * ph; - w >>= 1; - h >>= 1; - } - assert((pDst - reinterpret_cast(pDstPixels->data())) == dst_width); - } - - // convert destination image if needed - if (need_conversion) { - ConvertImage(dst_staging, dst_staging, dst_width, dst_height, FORMAT_A8R8G8B8, format); - } - - uint32_t bpp = Format::GetInfo(format).BytePerPixel; - for (auto& offset : mip_offsets) { - offset *= bpp; - } - - return 0; } \ No newline at end of file diff --git a/tests/regression/tex/utils.h b/tests/regression/tex/utils.h index 7ce58941..a3ffccae 100644 --- a/tests/regression/tex/utils.h +++ b/tests/regression/tex/utils.h @@ -1,44 +1,21 @@ #include #include -#include +#include +#include #include -#include "surfacedesc.h" int LoadImage(const char *filename, - ePixelFormat format, + cocogfx::ePixelFormat format, std::vector &pixels, uint32_t *width, uint32_t *height); int SaveImage(const char *filename, - ePixelFormat format, + cocogfx::ePixelFormat format, const std::vector &pixels, uint32_t width, uint32_t height); -int CopyBuffers(SurfaceDesc &dstDesc, - int32_t dstOffsetX, - int32_t dstOffsetY, - uint32_t copyWidth, - uint32_t copyHeight, - const SurfaceDesc &srcDesc, - int32_t srcOffsetX, - int32_t srcOffsetY); - -int ConvertImage(std::vector& dst_pixels, - const std::vector& src_pixels, - uint32_t width, - uint32_t height, - ePixelFormat src_format, - ePixelFormat dst_format); - -int GenerateMipmaps(std::vector& dst_pixels, - std::vector& mip_offsets, - const std::vector& src_pixels, - ePixelFormat format, - uint32_t src_width, - uint32_t src_height); - void dump_image(const std::vector& pixels, uint32_t width, uint32_t height, diff --git a/third_party/Makefile b/third_party/Makefile new file mode 100644 index 00000000..8a9ed890 --- /dev/null +++ b/third_party/Makefile @@ -0,0 +1,15 @@ +all: fpnew cocogfx softfloat + +fpnew: + +cocogfx: + $(MAKE) -C cocogfx + +softfloat: + SPECIALIZE_TYPE=RISCV SOFTFLOAT_OPTS="-fPIC -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 -DSOFTFLOAT_FAST_DIV64TO32" $(MAKE) -C softfloat/build/Linux-x86_64-GCC + +clean: + $(MAKE) clean -C cocogfx + $(MAKE) -C softfloat/build/Linux-x86_64-GCC clean + +.PHONY: all fpnew cocogfx softfloat \ No newline at end of file