Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Copyright © 2014 Intel Corporation
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
 
24
/**
25
 * \file lower_vertex_id.cpp
26
 *
27
 * There exists hardware, such as i965, that does not implement the OpenGL
28
 * semantic for gl_VertexID.  Instead, that hardware does not include the
29
 * value of basevertex in the gl_VertexID value.  To implement the OpenGL
30
 * semantic, we'll have to convert gl_Vertex_ID to
31
 * gl_VertexIDMESA+gl_BaseVertexMESA.
32
 */
33
 
34
#include "glsl_symbol_table.h"
35
#include "ir_hierarchical_visitor.h"
36
#include "ir.h"
37
#include "ir_builder.h"
38
#include "linker.h"
39
#include "program/prog_statevars.h"
40
 
41
namespace {
42
 
43
class lower_vertex_id_visitor : public ir_hierarchical_visitor {
44
public:
45
   explicit lower_vertex_id_visitor(ir_function_signature *main_sig,
46
                                    exec_list *ir_list)
47
      : progress(false), VertexID(NULL), gl_VertexID(NULL),
48
        gl_BaseVertex(NULL), main_sig(main_sig), ir_list(ir_list)
49
   {
50
      foreach_in_list(ir_instruction, ir, ir_list) {
51
         ir_variable *const var = ir->as_variable();
52
 
53
         if (var != NULL && var->data.mode == ir_var_system_value &&
54
             var->data.location == SYSTEM_VALUE_BASE_VERTEX) {
55
            gl_BaseVertex = var;
56
            break;
57
         }
58
      }
59
   }
60
 
61
   virtual ir_visitor_status visit(ir_dereference_variable *);
62
 
63
   bool progress;
64
 
65
private:
66
   ir_variable *VertexID;
67
   ir_variable *gl_VertexID;
68
   ir_variable *gl_BaseVertex;
69
 
70
   ir_function_signature *main_sig;
71
   exec_list *ir_list;
72
};
73
 
74
} /* anonymous namespace */
75
 
76
ir_visitor_status
77
lower_vertex_id_visitor::visit(ir_dereference_variable *ir)
78
{
79
   if (ir->var->data.mode != ir_var_system_value ||
80
       ir->var->data.location != SYSTEM_VALUE_VERTEX_ID)
81
      return visit_continue;
82
 
83
   if (VertexID == NULL) {
84
      const glsl_type *const int_t = glsl_type::int_type;
85
      void *const mem_ctx = ralloc_parent(ir);
86
 
87
      VertexID = new(mem_ctx) ir_variable(int_t, "__VertexID",
88
                                          ir_var_temporary);
89
      ir_list->push_head(VertexID);
90
 
91
      gl_VertexID = new(mem_ctx) ir_variable(int_t, "gl_VertexIDMESA",
92
                                             ir_var_system_value);
93
      gl_VertexID->data.how_declared = ir_var_declared_implicitly;
94
      gl_VertexID->data.read_only = true;
95
      gl_VertexID->data.location = SYSTEM_VALUE_VERTEX_ID_ZERO_BASE;
96
      gl_VertexID->data.explicit_location = true;
97
      gl_VertexID->data.explicit_index = 0;
98
      ir_list->push_head(gl_VertexID);
99
 
100
      if (gl_BaseVertex == NULL) {
101
         gl_BaseVertex = new(mem_ctx) ir_variable(int_t, "gl_BaseVertex",
102
                                                  ir_var_system_value);
103
         gl_BaseVertex->data.how_declared = ir_var_declared_implicitly;
104
         gl_BaseVertex->data.read_only = true;
105
         gl_BaseVertex->data.location = SYSTEM_VALUE_BASE_VERTEX;
106
         gl_BaseVertex->data.explicit_location = true;
107
         gl_BaseVertex->data.explicit_index = 0;
108
         ir_list->push_head(gl_BaseVertex);
109
      }
110
 
111
      ir_instruction *const inst =
112
         ir_builder::assign(VertexID,
113
                            ir_builder::add(gl_VertexID, gl_BaseVertex));
114
 
115
      main_sig->body.push_head(inst);
116
   }
117
 
118
   ir->var = VertexID;
119
   progress = true;
120
 
121
   return visit_continue;
122
}
123
 
124
bool
125
lower_vertex_id(gl_shader *shader)
126
{
127
   /* gl_VertexID only exists in the vertex shader.
128
    */
129
   if (shader->Stage != MESA_SHADER_VERTEX)
130
      return false;
131
 
132
   ir_function_signature *const main_sig =
133
      link_get_main_function_signature(shader);
134
   if (main_sig == NULL) {
135
      assert(main_sig != NULL);
136
      return false;
137
   }
138
 
139
   lower_vertex_id_visitor v(main_sig, shader->ir);
140
 
141
   v.run(shader->ir);
142
 
143
   return v.progress;
144
}