OpenCores
URL https://opencores.org/ocsvn/orsoc_graphics_accelerator/orsoc_graphics_accelerator/trunk

Subversion Repositories orsoc_graphics_accelerator

[/] [orsoc_graphics_accelerator/] [trunk/] [rtl/] [verilog/] [gfx/] [gfx_blender.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 Orka
/*
2
ORSoC GFX accelerator core
3
Copyright 2012, ORSoC, Per Lenander, Anton Fosselius.
4
 
5
PER-PIXEL COLORING MODULE, alpha blending
6
 
7
 
8
 This file is part of orgfx.
9
 
10
 orgfx is free software: you can redistribute it and/or modify
11
 it under the terms of the GNU Lesser General Public License as published by
12
 the Free Software Foundation, either version 3 of the License, or
13
 (at your option) any later version.
14
 
15
 orgfx is distributed in the hope that it will be useful,
16
 but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 GNU Lesser General Public License for more details.
19
 
20
 You should have received a copy of the GNU Lesser General Public License
21
 along with orgfx.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
*/
24
 
25
/*
26
This module performs alpha blending by fetching the pixel from the target and mixing it with the texel based on the current alpha value.
27
 
28
The exact formula is:
29
alpha = global_alpha_i * alpha_i
30
color_out = color_in * alpha + color_target * (1-alpha)       , where alpha is defined from 0 to 1
31
 
32
alpha_i[7:0] is used, so the actual span is 0 (transparent) to 255 (opaque)
33
 
34
If alpha blending is disabled (blending_enable_i == 1'b0) the module just passes on the input pixel.
35
*/
36
module gfx_blender(clk_i, rst_i,
37
  blending_enable_i, target_base_i, target_size_x_i, target_size_y_i, color_depth_i,
38
  x_counter_i, y_counter_i, z_i, alpha_i, global_alpha_i, write_i, ack_o,                      // from fragment
39
  target_ack_i, target_addr_o, target_data_i, target_sel_o, target_request_o, wbm_busy_i, // from/to wbm reader
40
  pixel_x_o, pixel_y_o, pixel_z_o, pixel_color_i, pixel_color_o, write_o, ack_i                      // to render
41
  );
42
 
43
parameter point_width = 16;
44
 
45
input                   clk_i;
46
input                   rst_i;
47
 
48
input                   blending_enable_i;
49
input            [31:2] target_base_i;
50
input [point_width-1:0] target_size_x_i;
51
input [point_width-1:0] target_size_y_i;
52
input             [1:0] color_depth_i;
53
 
54
// from fragment
55
input [point_width-1:0] x_counter_i;
56
input [point_width-1:0] y_counter_i;
57
input signed [point_width-1:0] z_i;
58
input             [7:0] alpha_i;
59
input             [7:0] global_alpha_i;
60
input            [31:0] pixel_color_i;
61
input                   write_i;
62
output reg              ack_o;
63
 
64
// Interface against wishbone master (reader)
65
input             target_ack_i;
66
output     [31:2] target_addr_o;
67
input      [31:0] target_data_i;
68
output reg  [3:0] target_sel_o;
69
output reg        target_request_o;
70
input             wbm_busy_i;
71
 
72
//to render
73
output reg [point_width-1:0] pixel_x_o;
74
output reg [point_width-1:0] pixel_y_o;
75
output reg signed [point_width-1:0] pixel_z_o;
76
output reg            [31:0] pixel_color_o;
77
output reg                   write_o;
78
input                        ack_i;
79
 
80
// State machine
81
reg [1:0] state;
82
parameter wait_state = 2'b00,
83
          target_read_state = 2'b01,
84
          write_pixel_state = 2'b10;
85
 
86
// Calculate alpha
87
reg [15:0] combined_alpha_reg;
88
wire [7:0] alpha = combined_alpha_reg[15:8];
89
 
90
// Calculate address of target pixel
91
// Addr[31:2] = Base + (Y*width + X) * ppb
92
wire [31:0] pixel_offset;
93
assign pixel_offset = (color_depth_i == 2'b00) ? (target_size_x_i*y_counter_i + {16'h0, x_counter_i})      : // 8  bit
94
                      (color_depth_i == 2'b01) ? (target_size_x_i*y_counter_i + {16'h0, x_counter_i}) << 1 : // 16 bit
95
                      (target_size_x_i*y_counter_i + {16'h0, x_counter_i})                            << 2 ; // 32 bit
96
 
97
assign target_addr_o = target_base_i + pixel_offset[31:2];
98
 
99
// Split colors for alpha blending (render color)
100
wire [7:0] blend_color_r = (color_depth_i == 2'b00) ? pixel_color_i[7:0] :
101
                           (color_depth_i == 2'b01) ? pixel_color_i[15:11] :
102
                           pixel_color_i[23:16];
103
wire [7:0] blend_color_g = (color_depth_i == 2'b00) ? pixel_color_i[7:0] :
104
                           (color_depth_i == 2'b01) ? pixel_color_i[10:5] :
105
                           pixel_color_i[15:8];
106
wire [7:0] blend_color_b = (color_depth_i == 2'b00) ? pixel_color_i[7:0] :
107
                           (color_depth_i == 2'b01) ? pixel_color_i[4:0] :
108
                           pixel_color_i[7:0];
109
 
110
// Split colors for alpha blending (from target surface)
111
wire [7:0] target_color_r = (color_depth_i == 2'b00) ? dest_color[7:0] :
112
                            (color_depth_i == 2'b01) ? dest_color[15:11] :
113
                            target_data_i[23:16];
114
wire [7:0] target_color_g = (color_depth_i == 2'b00) ? dest_color[7:0] :
115
                            (color_depth_i == 2'b01) ? dest_color[10:5] :
116
                            target_data_i[15:8];
117
wire [7:0] target_color_b = (color_depth_i == 2'b00) ? dest_color[7:0] :
118
                            (color_depth_i == 2'b01) ? dest_color[4:0] :
119
                            target_data_i[7:0];
120
 
121
// Alpha blending (per color channel):
122
// rgb = (alpha1)(rgb1) + (1-alpha1)(rgb2)
123
wire [15:0] alpha_color_r = blend_color_r * alpha + target_color_r * (8'hff - alpha);
124
wire [15:0] alpha_color_g = blend_color_g * alpha + target_color_g * (8'hff - alpha);
125
wire [15:0] alpha_color_b = blend_color_b * alpha + target_color_b * (8'hff - alpha);
126
 
127
wire [31:0] dest_color;
128
// Memory to color converter
129
memory_to_color memory_proc(
130
.color_depth_i (color_depth_i),
131
.mem_i (target_data_i),
132
.mem_lsb_i (x_counter_i[1:0]),
133
.color_o (dest_color),
134
.sel_o ()
135
);
136
 
137
// Acknowledge when a command has completed
138
always @(posedge clk_i or posedge rst_i)
139
begin
140
  // reset, init component
141
  if(rst_i)
142
  begin
143
    ack_o            <= 1'b0;
144
    write_o          <= 1'b0;
145
    pixel_x_o        <= 1'b0;
146
    pixel_y_o        <= 1'b0;
147
    pixel_z_o        <= 1'b0;
148
    pixel_color_o    <= 1'b0;
149
    target_request_o <= 1'b0;
150
    target_sel_o     <= 4'b1111;
151
  end
152
  // Else, set outputs for next cycle
153
  else
154
  begin
155
    case (state)
156
 
157
      wait_state:
158
      begin
159
        ack_o <= 1'b0;
160
 
161
        if(write_i)
162
        begin
163
          if(!blending_enable_i)
164
          begin
165
            pixel_x_o     <= x_counter_i;
166
            pixel_y_o     <= y_counter_i;
167
            pixel_z_o     <= z_i;
168
            pixel_color_o <= pixel_color_i;
169
            write_o       <= 1'b1;
170
          end
171
          else
172
          begin
173
            target_request_o   <= !wbm_busy_i;
174
            combined_alpha_reg <= alpha_i * global_alpha_i;
175
          end
176
        end
177
      end
178
 
179
      // Read pixel color at target (request is sent through the wbm reader arbiter).
180
      target_read_state:
181
        if(target_ack_i)
182
        begin
183
          // When we receive an ack from memory, calculate the combined color and send the pixel forward in the pipeline (go to write state)
184
          write_o          <= 1'b1;
185
          pixel_x_o        <= x_counter_i;
186
          pixel_y_o        <= y_counter_i;
187
          pixel_z_o        <= z_i;
188
          target_request_o <= 1'b0;
189
 
190
          // Recombine colors
191
          pixel_color_o    <= (color_depth_i == 2'b00) ? {alpha_color_r[15:8]} : // 8 bit grayscale
192
                              (color_depth_i == 2'b01) ? {alpha_color_r[12:8], alpha_color_g[13:8], alpha_color_b[12:8]} : // 16 bit
193
                              {alpha_color_r[15:8], alpha_color_g[15:8], alpha_color_b[15:8]}; // 32 bit
194
        end
195
        else
196
          target_request_o <= !wbm_busy_i | target_request_o;
197
 
198
      // Ack and return to wait state
199
      write_pixel_state:
200
      begin
201
        write_o <= 1'b0;
202
        if(ack_i)
203
          ack_o <= 1'b1;
204
      end
205
 
206
    endcase
207
  end
208
end
209
 
210
// State machine
211
always @(posedge clk_i or posedge rst_i)
212
begin
213
  // reset, init component
214
  if(rst_i)
215
    state <= wait_state;
216
  // Move in statemachine
217
  else
218
    case (state)
219
 
220
      wait_state:
221
        if(write_i & blending_enable_i)
222
          state <= target_read_state;
223
        else if(write_i)
224
          state <= write_pixel_state;
225
 
226
      target_read_state:
227
        if(target_ack_i)
228
          state <= write_pixel_state;
229
 
230
      write_pixel_state:
231
        if(ack_i)
232
          state <= wait_state;
233
 
234
    endcase
235
end
236
 
237
endmodule
238
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.