Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 7 commits
  • 10 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jul 21, 2012
@gzorin Yet more glDraw* refactoring. 02c1989
Commits on Jul 22, 2012
@gzorin MORE refactoring... 844f05a
@gzorin Refactored glMultiDrawElements*() appear to work. 87a3b06
@gzorin New instanced draw functinos... however floating point textures, upon…
… which instanced rendering depends, appear to be broken.
b16904f
@gzorin Force the nvfx_screen to advertise floating-point textures. c179186
@gzorin Refactored instance rendering commands "work"...
...in the sense that they schedule the command stream properly. Instance rendering does not actually occur, however, probably because the GLSL compiler isn't emitting a vertex program texture command.
0ba609d
@gzorin Finished refactoring glDraw*() functions.
Attempting to make use of "policy-based design," per Alexandrescu.
75911e1
View
1,223 src/library/draw.cc
@@ -122,8 +122,8 @@ rsxgl_check_draw_elements(rsxgl_context_t * ctx,GLenum mode,GLenum type)
const uint32_t rsx_primitive_type = rsxgl_draw_mode(mode);
RSXGL_FORWARD_ERROR(std::make_pair(~0U, RSXGL_MAX_ELEMENT_TYPES));
- const uint32_t rsx_type = rsxgl_draw_elements_type(type);
- if(rsx_type == RSXGL_MAX_ELEMENT_TYPES) {
+ const uint32_t rsx_element_type = rsxgl_draw_elements_type(type);
+ if(rsx_element_type == RSXGL_MAX_ELEMENT_TYPES) {
RSXGL_ERROR(GL_INVALID_ENUM,std::make_pair(~0U,RSXGL_MAX_ELEMENT_TYPES));
}
@@ -137,36 +137,9 @@ rsxgl_check_draw_elements(rsxgl_context_t * ctx,GLenum mode,GLenum type)
rsxgl_check_unmapped_arrays(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].attribs_enabled);
RSXGL_FORWARD_ERROR(std::make_pair(~0U, RSXGL_MAX_ELEMENT_TYPES));
- return std::make_pair(rsx_primitive_type,rsx_type);
+ return std::make_pair(rsx_primitive_type,rsx_element_type);
}
-static inline uint32_t
-rsxgl_draw_init(rsxgl_context_t * ctx,GLenum mode,const uint32_t start,const uint32_t length,const uint32_t count)
-{
- const uint32_t timestamp = rsxgl_timestamp_create(ctx,count);
- const uint32_t last_timestamp = timestamp + count - 1;
-
- // validate everything:
- rsxgl_draw_framebuffer_validate(ctx,last_timestamp);
- rsxgl_state_validate(ctx);
- rsxgl_program_validate(ctx,last_timestamp);
- rsxgl_attribs_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].attribs_enabled,start,length,last_timestamp);
- rsxgl_uniforms_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM]);
- rsxgl_textures_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM],last_timestamp);
-
- return timestamp;
-}
-
-struct rsxgl_draw_elements_info_t {
- const bool client_indices;
- const void * migrate_buffer;
- const uint32_t migrate_buffer_size;
-
- rsxgl_draw_elements_info_t(const bool _client_indices,void const * _migrate_buffer,const uint32_t _migrate_buffer_size)
- : client_indices(_client_indices), migrate_buffer(_migrate_buffer), migrate_buffer_size(_migrate_buffer_size) {
- }
-};
-
#define NV30_3D_IDXBUF_FORMAT_TYPE_U8 2
static const uint8_t rsxgl_element_nv40_type[RSXGL_MAX_ELEMENT_TYPES] = {
@@ -183,62 +156,6 @@ static const uint8_t rsxgl_element_type_bytes[RSXGL_MAX_ELEMENT_TYPES] = {
sizeof(uint8_t)
};
-static inline void
-rsxgl_draw_elements_emit_index_buffer(gcmContextData * context,const uint32_t rsx_type,const uint32_t offset,const uint32_t location)
-{
- uint32_t * buffer = gcm_reserve(context,3);
-
- gcm_emit_method_at(buffer,0,NV30_3D_IDXBUF_OFFSET,2);
- gcm_emit_at(buffer,1,offset);
- gcm_emit_at(buffer,2,(uint32_t)rsxgl_element_nv40_type[rsx_type] | location);
-
- gcm_finish_n_commands(context,3);
-}
-
-static inline rsxgl_draw_elements_info_t
-rsxgl_draw_elements_init(rsxgl_context_t * ctx,const GLuint start,const GLuint end,const GLsizei count,const uint32_t rsx_type,const GLvoid * indices,const uint32_t timestamp)
-{
- gcmContextData * context = ctx -> gcm_context();
-
- const bool client_indices = ctx -> buffer_binding.names[RSXGL_ELEMENT_ARRAY_BUFFER] == 0;
- void * migrate_buffer = 0;
-
- uint32_t index_buffer_offset = 0, index_buffer_location = 0;
- const uint32_t index_buffer_size = (uint32_t)rsxgl_element_type_bytes[rsx_type] * count;
-
- if(client_indices) {
- migrate_buffer = rsxgl_vertex_migrate_memalign(context,16,index_buffer_size);
- memcpy(migrate_buffer,indices,index_buffer_size);
- int32_t s = gcmAddressToOffset(migrate_buffer,&index_buffer_offset);
- rsxgl_assert(s == 0);
-
- index_buffer_location = RSXGL_VERTEX_MIGRATE_BUFFER_LOCATION;
- }
- else {
- const uint32_t start = (uint32_t)((uint64_t)indices);
- rsxgl_buffer_validate(ctx,ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER],start,index_buffer_size,timestamp);
-
- const buffer_t & index_buffer = ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER];
- index_buffer_offset = index_buffer.memory.offset + start;
- index_buffer_location = index_buffer.memory.location;
- }
-
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer_offset,index_buffer_location);
-
- return rsxgl_draw_elements_info_t(client_indices,migrate_buffer,index_buffer_size);
-}
-
-static inline void
-rsxgl_draw_elements_exit(rsxgl_context_t * ctx,rsxgl_draw_elements_info_t const & info)
-{
- gcmContextData * context = ctx -> gcm_context();
-
- if(info.client_indices) {
- rsxgl_assert(info.migrate_buffer != 0);
- rsxgl_vertex_migrate_free(context,info.migrate_buffer,info.migrate_buffer_size);
- }
-}
-
// This function is designed to split an iteration into groups (RSX method invocations) & batches
// as required by the hardware. max_method_args is the total number of arguments accepted by a
// single "method" - this should pretty much be set to 2047. batch_size can vary depending upon
@@ -503,59 +420,6 @@ struct rsxgl_draw_array_operations {
}
};
-static inline uint32_t
-rsxgl_count_arrays(const uint32_t rsx_primitive_type,const uint32_t count)
-{
- if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
- return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
- return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
- return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
- return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
- return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > > (count);
- }
- else {
- return 0;
- }
-}
-
-static inline void
-rsxgl_draw_arrays(gcmContextData * context,const uint32_t rsx_primitive_type,const uint32_t first,const uint32_t count)
-{
- if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
- rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > op(first);
- rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
- rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_lines > op(first);
- rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
- rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > op(first);
- rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
- rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > op(first);
- rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
- rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > op(first);
- rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
-}
-
#define RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS 1
// Operations performed by rsxgl_process_batch (a local class passed as a template argument is a C++0x feature):
@@ -633,227 +497,392 @@ struct rsxgl_draw_array_elements_operations {
}
};
-static inline uint32_t
-rsxgl_count_array_elements(const uint32_t rsx_primitive_type,const uint32_t count)
-{
- if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
- return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
- return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
- return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
- return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > > (count);
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
- return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > > (count);
- }
- else {
- return 0;
- }
-}
+namespace {
+ template< typename ElementRangePolicy, typename IterationPolicy, typename DrawPolicy >
+ void rsxgl_draw(rsxgl_context_t * ctx,const ElementRangePolicy & elementRangePolicy,const IterationPolicy & iterationPolicy,const DrawPolicy & drawPolicy)
+ {
+#if 0
+ rsxgl_debug_printf("%s\n",__PRETTY_FUNCTION__);
+#endif
-static inline void
-rsxgl_draw_array_elements(gcmContextData * context,const uint32_t rsx_primitive_type,const uint32_t count)
-{
- if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
- rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > op;
- rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
- rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > op;
- rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
- rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > op;
- rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
- rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > op;
- rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
- else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
- rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > op;
- rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (context,count,op);
- context -> current = op.buffer;
- }
-}
+ // Compute the range of array elements used by this draw call:
+ const std::pair< uint32_t, uint32_t > index_range = elementRangePolicy.range();
-static inline void
-rsxgl_draw_array_elements_base(gcmContextData * context,const uint32_t base)
-{
- uint32_t * buffer = gcm_reserve(context,2);
- gcm_emit_method_at(buffer,0,0x173c,1);
- gcm_emit_at(buffer,1,base);
- gcm_finish_n_commands(context,2);
-}
+ // Iteration:
+ typename IterationPolicy::iterator it = iterationPolicy.begin(), it_end = iterationPolicy.end();
-// Tags for draw behavior:
-namespace {
- namespace draw_tags {
- // How many primitives?
- struct single {};
- struct multi {};
- struct instanced {};
-
- // Arrays or elements?
- struct arrays {};
- struct elements {};
-
- // How to obtain element range?
- struct no_range {};
- struct scan_range {};
- struct explicit_range {};
-
- // How to handle base vertex?
- struct no_base {};
- struct zero_base {};
- struct explicit_base {};
- };
-};
+ // Timestamps, determined by the number of iterations:
+ const size_t timestampCount = it_end - it;
+ uint32_t timestamp = rsxgl_timestamp_create(ctx,timestampCount);
+ const uint32_t lastTimestamp = timestamp + timestampCount - 1;
-namespace {
+ // Validate state:
+ rsxgl_draw_framebuffer_validate(ctx,lastTimestamp);
+ rsxgl_state_validate(ctx);
+ rsxgl_program_validate(ctx,lastTimestamp);
+ rsxgl_attribs_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].attribs_enabled,index_range.first,index_range.second,lastTimestamp);
+ rsxgl_uniforms_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM]);
+ rsxgl_textures_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM],lastTimestamp);
- template< typename SingleOrMulti, typename ArrayOrElements, typename Range, typename Base >
- struct draw_functions;
+ // Draw functions:
+ gcmContextData * gcm_context = ctx -> gcm_context();
- struct draw_functions_base {
- gcmContextData * const context;
- const uint32_t rsx_primitive_type;
+ drawPolicy.begin(gcm_context,timestamp);
+ for(;it != it_end;++it,++timestamp) {
+ drawPolicy.draw(gcm_context,timestamp,it);
+ rsxgl_timestamp_post(ctx,timestamp);
+ }
+ drawPolicy.end(gcm_context,timestamp);
+ }
- draw_functions_base(gcmContextData * _context,const uint32_t _rsx_primitive_type)
- : context(_context), rsx_primitive_type(_rsx_primitive_type) {
+ struct ignore_element_range_policy {
+ std::pair< uint32_t, uint32_t > range() const {
+ return std::pair< uint32_t, uint32_t >(0,0);
}
};
- template< >
- struct draw_functions< draw_tags::single, draw_tags::arrays, draw_tags::no_range, draw_tags::no_base > : public draw_functions_base {
- const GLint * const first;
- const GLsizei * const count;
-
- draw_functions(rsxgl_context_t * _ctx,
- const uint32_t _rsx_primitive_type,
- const GLsizei _primitive_count,const GLint * _first,const GLsizei * _count,
- const uint32_t _rsx_element_type,const GLint _element_base,const GLuint _min_element,const GLuint _max_element,const GLvoid ** _element_indices)
- : draw_functions_base(_ctx -> gcm_context(), _rsx_primitive_type),
- first(_first), count(_count) {
+ struct start_end_element_range_policy {
+ const GLuint start, end;
+
+ start_end_element_range_policy(GLuint _start,GLuint _end) : start(_start), end(_end) {}
+
+ std::pair< uint32_t, uint32_t > range() const {
+ return std::pair< uint32_t, uint32_t >(start,end - start);
}
+ };
- std::pair< uint32_t, uint32_t > index_range() {
- return std::make_pair(*first,*count);
+ struct single_iteration_policy {
+ typedef unsigned int iterator;
+
+ constexpr iterator begin() const {
+ return 0;
}
-
- size_t iteration_count() {
+
+ constexpr iterator end() const {
return 1;
}
+ };
- void start() {}
+ struct multi_iteration_policy {
+ typedef unsigned int iterator;
+
+ GLsizei primcount;
+
+ multi_iteration_policy(GLsizei _primcount) : primcount(_primcount) {}
+
+ iterator begin() const {
+ return 0;
+ }
+
+ iterator end() const {
+ return primcount;
+ }
+ };
- void iteration(const size_t) {
- rsxgl_draw_arrays(context,rsx_primitive_type,*first,*count);
+ struct array_draw_policy {
+ const uint32_t rsx_primitive_type;
+
+ array_draw_policy(uint32_t _rsx_primitive_type)
+ : rsx_primitive_type(_rsx_primitive_type) {}
+
+ protected:
+ void draw(gcmContextData * gcm_context,uint32_t first,uint32_t count) const {
+ if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
+ rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > op(first);
+ rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
+ rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_lines > op(first);
+ rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
+ rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > op(first);
+ rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
+ rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > op(first);
+ rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
+ rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > op(first);
+ rsxgl_process_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
}
- void finish() {}
+ uint32_t countDrawCommands(uint32_t count) const {
+ if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
+ return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
+ return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
+ return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
+ return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
+ return rsxgl_count_batch< RSXGL_VERTEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > > (count);
+ }
+ else {
+ return 0;
+ }
+ }
};
- template< >
- struct draw_functions< draw_tags::multi, draw_tags::arrays, draw_tags::no_range, draw_tags::no_base > : public draw_functions_base {
- const GLsizei primitive_count;
- const GLint * const first;
- const GLsizei * const count;
-
+ struct multi_draw_policy {
const rsxgl_query_object_index_type query_index;
-
- draw_functions(rsxgl_context_t * _ctx,
- const uint32_t _rsx_primitive_type,
- const GLsizei _primitive_count,const GLint * _first,const GLsizei * _count,
- const uint32_t _rsx_element_type,const GLint _element_base,const GLuint _min_element,const GLuint _max_element,const GLvoid ** _element_indices)
- : draw_functions_base(_ctx -> gcm_context(),_rsx_primitive_type),
- primitive_count(_primitive_count), first(_first), count(_count),
- query_index(_ctx -> any_samples_passed_query) {
+ const bool set_query_object;
+
+ multi_draw_policy(rsxgl_context_t * ctx)
+ : query_index(ctx -> any_samples_passed_query), set_query_object(query_index != RSXGL_MAX_QUERY_OBJECTS) {}
+
+ protected:
+
+ void draw(gcmContextData * gcm_context) const {
+ if(set_query_object) {
+ rsxgl_query_object_set(gcm_context,query_index);
+ }
}
+ };
+
+ struct element_draw_policy {
+ rsxgl_context_t * ctx;
+ const uint32_t rsx_primitive_type, rsx_element_type;
+
+ const bool client_indices;
+
+ element_draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type)
+ : ctx(_ctx), rsx_primitive_type(_rsx_primitive_type), rsx_element_type(_rsx_element_type),
+
+ client_indices(ctx -> buffer_binding.names[RSXGL_ELEMENT_ARRAY_BUFFER] == 0),
+ migrate_buffer(0), migrate_buffer_size(0) {}
+
+ protected:
+ mutable void * migrate_buffer;
+ mutable uint32_t migrate_buffer_size;
+ mutable uint32_t index_buffer_offset, index_buffer_location;
+
+ void begin(gcmContextData * context,uint32_t timestamp,const GLsizei * count,const GLvoid * const* indices,GLsizei primcount,uint32_t * offsets) const {
+ index_buffer_offset = 0;
+ index_buffer_location = 0;
+
+ // Migrate client-side index array to RSX:
+ if(client_indices) {
+ migrate_buffer_size = (uint32_t)rsxgl_element_type_bytes[rsx_element_type] * std::accumulate(count,count + primcount,0);
+ migrate_buffer = rsxgl_vertex_migrate_memalign(context,16,migrate_buffer_size);
- std::pair< uint32_t, uint32_t > index_range() {
- const GLint * min_first = std::min_element(first,first + primitive_count);
- const GLsizei * max_count = std::max_element(count,count + primitive_count);
- return std::make_pair(*min_first,*max_count);
+ uint8_t * pmigrate_buffer = (uint8_t *)migrate_buffer;
+ uint32_t offset = 0;
+ for(GLsizei i = 0;i < primcount;++i) {
+ const size_t size = (uint32_t)rsxgl_element_type_bytes[rsx_element_type] * *count;
+ memcpy(pmigrate_buffer,*indices,size);
+ *offsets = offset;
+ pmigrate_buffer += size;
+ offset += size;
+ ++count;
+ ++indices;
+ ++offsets;
+ }
+
+ int32_t s = gcmAddressToOffset(migrate_buffer,&index_buffer_offset);
+ rsxgl_assert(s == 0);
+
+ index_buffer_location = RSXGL_VERTEX_MIGRATE_BUFFER_LOCATION;
+ }
+ // Validate the RSX buffer:
+ else {
+ uint32_t start = std::numeric_limits< uint32_t >::max(), end = std::numeric_limits< uint32_t >::min();
+
+ for(GLsizei i = 0;i < primcount;++i) {
+ const uint32_t offset = (uint32_t)((uint64_t)*indices);
+ *offsets = offset;
+ start = std::min(start,offset);
+ const uint32_t size = (uint32_t)rsxgl_element_type_bytes[rsx_element_type] * *count;
+ end = std::max(end,offset + size);
+ ++count;
+ ++indices;
+ ++offsets;
+ }
+
+ rsxgl_buffer_validate(ctx,ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER],start,end - start,timestamp + primcount - 1);
+
+ const buffer_t & index_buffer = ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER];
+ index_buffer_offset = index_buffer.memory.offset;
+ index_buffer_location = index_buffer.memory.location;
+ }
}
- size_t iteration_count() {
- return primitive_count;
+ void emitIndexBufferCommands(gcmContextData * gcm_context,uint32_t offset) const {
+ // Emit the commands for this buffer:
+ uint32_t * buffer = gcm_reserve(gcm_context,3);
+
+ gcm_emit_method_at(buffer,0,NV30_3D_IDXBUF_OFFSET,2);
+ gcm_emit_at(buffer,1,index_buffer_offset + offset);
+ gcm_emit_at(buffer,2,(uint32_t)rsxgl_element_nv40_type[rsx_element_type] | index_buffer_location);
+
+ gcm_finish_n_commands(gcm_context,3);
}
- void start() {}
+ void emitDrawCommands(gcmContextData * gcm_context,uint32_t count) const {
+ if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
+ rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > op;
+ rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
+ rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > op;
+ rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
+ rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > op;
+ rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
+ rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > op;
+ rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
+ rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > op;
+ rsxgl_process_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS > (gcm_context,count,op);
+ gcm_context -> current = op.buffer;
+ }
+ }
- void iteration(const size_t i) {
- rsxgl_draw_arrays(context,rsx_primitive_type,first[i],count[i]);
- if(query_index != RSXGL_MAX_QUERY_OBJECTS) {
- rsxgl_query_object_set(context,query_index);
+ void end(gcmContextData * context) const {
+ if(client_indices) {
+ rsxgl_assert(migrate_buffer != 0);
+ rsxgl_vertex_migrate_free(context,migrate_buffer,migrate_buffer_size);
}
}
- void finish() {}
+ uint32_t countDrawCommands(uint32_t count) const {
+ if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_POINTS) {
+ return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_points > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINES) {
+ return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_LINE_STRIP) {
+ return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_line_strip > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLES) {
+ return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangles > > (count);
+ }
+ else if(rsx_primitive_type == NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP) {
+ return rsxgl_count_batch< RSXGL_INDEX_BATCH_MAX_FIFO_METHOD_ARGS, rsxgl_draw_array_elements_operations< RSXGL_MAX_DRAW_BATCH_SIZE, rsxgl_draw_triangle_strip > > (count);
+ }
+ else {
+ return 0;
+ }
+ }
};
-};
+ struct base_element_draw_policy {
+ protected:
+ void draw(gcmContextData * context,uint32_t base) const {
+ uint32_t * buffer = gcm_reserve(context,2);
+ gcm_emit_method_at(buffer,0,0x173c,1);
+ gcm_emit_at(buffer,1,base);
+ gcm_finish_n_commands(context,2);
+ }
-template< typename SingleOrMulti, typename ArrayOrElements, typename Range, typename Base >
-static inline void
-rsxgl_draw(rsxgl_context_t * ctx,
- const uint32_t rsx_primitive_type,
- const GLsizei primitive_count,const GLint * first,const GLsizei * count,
- const uint32_t rsx_element_type,const GLint element_base,const GLuint min_element,const GLuint max_element,const GLvoid ** element_indices)
-{
- rsxgl_debug_printf("%s\n",__PRETTY_FUNCTION__);
-
- typedef draw_functions< SingleOrMulti, ArrayOrElements, Range, Base > draw_functions_type;
- draw_functions_type functions(ctx,rsx_primitive_type,primitive_count,first,count,rsx_element_type,element_base,min_element,max_element,element_indices);
-
- // Compute the range of array elements used by this draw call:
- const std::pair< uint32_t, uint32_t > index_range = functions.index_range();
-
- // Number of iterations:
- const size_t iteration_count = functions.iteration_count();
-
- // - always compute timestamp(s):
- uint32_t timestamp = rsxgl_timestamp_create(ctx,iteration_count);
- const uint32_t last_timestamp = timestamp + iteration_count - 1;
-
- // validate everything:
- // - always validate state, attribs, etc.
- rsxgl_draw_framebuffer_validate(ctx,last_timestamp);
- rsxgl_state_validate(ctx);
- rsxgl_program_validate(ctx,last_timestamp);
- rsxgl_attribs_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].attribs_enabled,index_range.first,index_range.second,last_timestamp);
- rsxgl_uniforms_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM]);
- rsxgl_textures_validate(ctx,ctx -> program_binding[RSXGL_ACTIVE_PROGRAM],last_timestamp);
-
- // - maybe migrate client indices
- // - maybe set base vertex
- functions.start();
-
- // Iterate:
- // - for each iteration:
- // - on first, maybe cache as "display list"
- // - maybe set base vertex
- // - maybe update query object
- // - post timestamp
- for(size_t i = 0;i < iteration_count;++i,++timestamp) {
- functions.iteration(i);
- rsxgl_timestamp_post(ctx,timestamp);
- }
+ void end(gcmContextData * context) const {
+ uint32_t * buffer = gcm_reserve(context,2);
+ gcm_emit_method_at(buffer,0,0x173c,1);
+ gcm_emit_at(buffer,1,0);
+ gcm_finish_n_commands(context,2);
+ }
+ };
- // Exit:
- // - maybe free client indices
- // - maybe reset base vertex
- functions.finish();
+ struct instanced_draw_policy : public multi_draw_policy {
+ const uint32_t instanceid_index;
+
+ mutable uint32_t call_offset, call_cmd;
+
+ instanced_draw_policy(rsxgl_context_t * _ctx)
+ : multi_draw_policy(_ctx), instanceid_index(_ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index) {}
+
+ protected:
+
+ void beginInstance(gcmContextData * gcm_context,uint32_t nwords) const {
+ gcm_reserve(gcm_context,nwords + 2);
+
+ // call location - current position + 1
+ // jump location - current position + 1 word + nwords + 1 word
+ call_offset = 0;
+ uint32_t jump_offset = 0;
+ int32_t s = 0;
+
+ s = gcmAddressToOffset(gcm_context -> current + 1,&call_offset);
+ rsxgl_assert(s == 0);
+
+ s = gcmAddressToOffset(gcm_context -> current + nwords + 2,&jump_offset);
+ rsxgl_assert(s == 0);
+
+ gcm_emit_at(gcm_context -> current,0,gcm_jump_cmd(jump_offset)); ++gcm_context -> current;
+
+ call_cmd = gcm_call_cmd(call_offset);
+ }
+
+ void endInstance(gcmContextData * gcm_context) const {
+ gcm_emit_at(gcm_context -> current,0,gcm_return_cmd()); ++gcm_context -> current;
+ }
+
+ void draw(gcmContextData * gcm_context,unsigned int i) const {
+ uint32_t * buffer = gcm_reserve(gcm_context,4);
+
+ ieee32_t tmp;
+ tmp.f = (float)i;
+
+ gcm_emit_method_at(buffer,0,NV30_3D_VP_UPLOAD_CONST_ID,2);
+ gcm_emit_at(buffer,1,instanceid_index);
+ gcm_emit_at(buffer,2,tmp.u);
+ gcm_emit_at(buffer,3,call_cmd);
+
+ gcm_finish_n_commands(gcm_context,4);
+
+ multi_draw_policy::draw(gcm_context);
+ }
+ };
+}
+
+namespace {
+ struct arrays_element_range_policy {
+ const GLint first;
+ const GLsizei count;
+
+ arrays_element_range_policy(GLint _first,GLint _count) : first(_first), count(_count) {}
+
+ std::pair< uint32_t, uint32_t > range() const {
+ return std::pair< uint32_t, uint32_t >(first,count);
+ }
+ };
+
+ struct draw_arrays_policy : public array_draw_policy {
+ const GLint first;
+ const GLsizei count;
+
+ draw_arrays_policy(uint32_t _rsx_primitive_type,GLint _first,GLint _count)
+ : array_draw_policy(_rsx_primitive_type), first(_first), count(_count) {
+ }
+
+ void begin(gcmContextData * context,uint32_t) const {}
+ void end(gcmContextData * context,uint32_t) const {}
+
+ void draw(gcmContextData * gcm_context,uint32_t,unsigned int) const {
+ array_draw_policy::draw(gcm_context,first,count);
+ }
+ };
}
//
@@ -870,8 +899,8 @@ glDrawArrays (GLenum mode, GLint first, GLsizei count)
RSXGL_ERROR_(GL_INVALID_VALUE);
}
- if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- rsxgl_draw< draw_tags::single, draw_tags::arrays, draw_tags::no_range, draw_tags::no_base >(ctx,rsx_primitive_type,1,&first,&count,0,0,0,0,0);
+ if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
+ rsxgl_draw(ctx,arrays_element_range_policy(first,count),single_iteration_policy(),draw_arrays_policy(rsx_primitive_type,first,count));
}
RSXGL_NOERROR_();
@@ -891,10 +920,71 @@ glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, const
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- rsxgl_draw< draw_tags::multi, draw_tags::arrays, draw_tags::no_range, draw_tags::no_base >(ctx,rsx_primitive_type,primcount,first,count,0,0,0,0,0);
+ struct element_range_policy {
+ const GLint * first;
+ const GLsizei * count;
+ const GLsizei primcount;
+
+ element_range_policy(const GLint * _first,const GLint * _count,GLsizei _primcount) : first(_first), count(_count), primcount(_primcount) {}
+
+ std::pair< uint32_t, uint32_t > range() const {
+ GLint start = std::numeric_limits< GLint >::max();
+ GLsizei end = std::numeric_limits< GLsizei >::min();
+
+ for(GLsizei i = 0;i < primcount;++i) {
+ start = std::min(start,first[i]);
+ end = std::max(end,first[i] + count[i]);
+ }
+
+ return std::pair< uint32_t, uint32_t >(start,end - start);
+ }
+ };
+
+ struct draw_policy : public array_draw_policy, public multi_draw_policy {
+ const GLint * first;
+ const GLsizei * count;
+
+ draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,const GLint * _first,const GLint * _count)
+ : array_draw_policy(_rsx_primitive_type), multi_draw_policy(_ctx), first(_first), count(_count) {
+ }
+
+ void begin(gcmContextData * context,uint32_t) const {}
+ void end(gcmContextData * context,uint32_t) const {}
+
+ void draw(gcmContextData * gcm_context,uint32_t,unsigned int i) const {
+ array_draw_policy::draw(gcm_context,first[i],count[i]);
+ multi_draw_policy::draw(gcm_context);
+ }
+ };
+
+ rsxgl_draw(ctx,element_range_policy(first,count,primcount),multi_iteration_policy(primcount),draw_policy(ctx,rsx_primitive_type,first,count));
}
}
+namespace {
+ struct draw_elements_policy : public element_draw_policy {
+ const GLsizei count;
+ const GLvoid * indices;
+
+ mutable uint32_t offset;
+
+ draw_elements_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type,GLsizei _count,const GLvoid * _indices) : element_draw_policy(_ctx,_rsx_primitive_type,_rsx_element_type), count(_count), indices(_indices) {}
+
+ void begin(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::begin(gcm_context,timestamp,&count,&indices,1,&offset);
+ }
+
+ void draw(gcmContextData * gcm_context,uint32_t timestamp,unsigned int) const {
+ element_draw_policy::emitIndexBufferCommands(gcm_context,offset);
+ element_draw_policy::emitDrawCommands(gcm_context,count);
+ }
+
+ void end(gcmContextData * gcm_context,uint32_t) const {
+ element_draw_policy::end(gcm_context);
+ }
+ };
+}
+
//
GLAPI void APIENTRY
glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
@@ -902,8 +992,8 @@ glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)) {
@@ -919,91 +1009,88 @@ glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- // draw!
- gcmContextData * context = ctx -> gcm_context();
-
- //
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,1);
- const rsxgl_draw_elements_info_t info = rsxgl_draw_elements_init(ctx,0,0,count,rsx_type,indices,timestamp);
- if(ctx -> state.enable.transform_feedback_program && ctx -> state.enable.transform_feedback_mode) {
- const uint32_t list_offset = gcm_begin_list(context);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- gcm_finish_list(context,list_offset,true);
- }
- else {
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- }
- rsxgl_timestamp_post(ctx,timestamp);
- rsxgl_draw_elements_exit(ctx,info);
+ rsxgl_draw(ctx,ignore_element_range_policy(),single_iteration_policy(),draw_elements_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices));
}
RSXGL_NOERROR_();
}
GLAPI void APIENTRY
-glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)
+glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(count < 0) {
RSXGL_ERROR_(GL_INVALID_VALUE);
}
+ if(end < start) {
+ RSXGL_ERROR_(GL_INVALID_VALUE);
+ }
+
if(ctx -> buffer_binding.names[RSXGL_ELEMENT_ARRAY_BUFFER] != 0 && ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER].mapped) {
RSXGL_ERROR_(GL_INVALID_OPERATION);
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- gcmContextData * context = ctx -> gcm_context();
-
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,1);
- const rsxgl_draw_elements_info_t info = rsxgl_draw_elements_init(ctx,0,0,count,rsx_type,indices,timestamp);
- rsxgl_draw_array_elements_base(context,basevertex);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- rsxgl_timestamp_post(ctx,timestamp);
- rsxgl_draw_array_elements_base(context,0);
- rsxgl_draw_elements_exit(ctx,info);
+ rsxgl_draw(ctx,start_end_element_range_policy(start,end),single_iteration_policy(),draw_elements_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices));
}
RSXGL_NOERROR_();
}
+namespace {
+ struct draw_elements_base_policy : public element_draw_policy, public base_element_draw_policy {
+ const GLsizei count;
+ const GLvoid * indices;
+ const GLint basevertex;
+
+ mutable uint32_t offset;
+
+ draw_elements_base_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type,GLsizei _count,const GLvoid * _indices,GLint _basevertex) : element_draw_policy(_ctx,_rsx_primitive_type,_rsx_element_type), count(_count), indices(_indices), basevertex(_basevertex) {}
+
+ void begin(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::begin(gcm_context,timestamp,&count,&indices,1,&offset);
+ }
+
+ void draw(gcmContextData * gcm_context,uint32_t timestamp,unsigned int) const {
+ base_element_draw_policy::draw(gcm_context,basevertex);
+ element_draw_policy::emitIndexBufferCommands(gcm_context,offset);
+ element_draw_policy::emitDrawCommands(gcm_context,count);
+ }
+
+ void end(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::end(gcm_context);
+ base_element_draw_policy::end(gcm_context);
+ }
+ };
+}
+
GLAPI void APIENTRY
-glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
+glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)
{
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(count < 0) {
RSXGL_ERROR_(GL_INVALID_VALUE);
}
- if(end < start) {
- RSXGL_ERROR_(GL_INVALID_VALUE);
- }
-
if(ctx -> buffer_binding.names[RSXGL_ELEMENT_ARRAY_BUFFER] != 0 && ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER].mapped) {
RSXGL_ERROR_(GL_INVALID_OPERATION);
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- // draw!
- gcmContextData * context = ctx -> gcm_context();
-
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,start,end - start,1);
- const rsxgl_draw_elements_info_t info = rsxgl_draw_elements_init(ctx,start,end,count,rsx_type,indices,timestamp);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- rsxgl_timestamp_post(ctx,timestamp);
- rsxgl_draw_elements_exit(ctx,info);
+ rsxgl_draw(ctx,ignore_element_range_policy(),single_iteration_policy(),draw_elements_base_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices,basevertex));
}
RSXGL_NOERROR_();
@@ -1015,8 +1102,8 @@ glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei co
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(count < 0) {
@@ -1032,15 +1119,7 @@ glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei co
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- gcmContextData * context = ctx -> gcm_context();
-
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,start,end - start,1);
- const rsxgl_draw_elements_info_t info = rsxgl_draw_elements_init(ctx,start,end,count,rsx_type,indices,timestamp);
- rsxgl_draw_array_elements_base(context,basevertex);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- rsxgl_timestamp_post(ctx,timestamp);
- rsxgl_draw_array_elements_base(context,0);
- rsxgl_draw_elements_exit(ctx,info);
+ rsxgl_draw(ctx,start_end_element_range_policy(start,end),single_iteration_policy(),draw_elements_base_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices,basevertex));
}
RSXGL_NOERROR_();
@@ -1052,8 +1131,8 @@ glMultiDrawElements (const GLenum mode, const GLsizei *count, GLenum type, const
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(primcount < 0) {
@@ -1065,73 +1144,32 @@ glMultiDrawElements (const GLenum mode, const GLsizei *count, GLenum type, const
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- gcmContextData * context = ctx -> gcm_context();
-
- uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,primcount);
-
- const rsxgl_query_object_index_type query_index = ctx -> any_samples_passed_query;
-
- const bool client_indices = ctx -> buffer_binding.names[RSXGL_ELEMENT_ARRAY_BUFFER] == 0;
-
- if(client_indices) {
- void * migrate_buffers[primcount];
- uint32_t index_buffer_sizes[primcount];
- uint32_t index_buffer_offsets[primcount];
- for(GLsizei i = 0;i < primcount;++i) {
- index_buffer_sizes[i] = (uint32_t)rsxgl_element_type_bytes[rsx_type] * count[i];
- migrate_buffers[i] = rsxgl_vertex_migrate_memalign(context,16,index_buffer_sizes[i]);
- memcpy(migrate_buffers[i],indices,index_buffer_sizes[i]);
- int32_t s = gcmAddressToOffset(migrate_buffers[i],index_buffer_offsets + i);
- rsxgl_assert(s == 0);
- }
+ struct draw_policy : public element_draw_policy, public multi_draw_policy {
+ const GLsizei * count;
+ const GLvoid * const * indices;
+ const GLsizei primcount;
- if(query_index == RSXGL_MAX_QUERY_OBJECTS) {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer_offsets[i],RSXGL_VERTEX_MIGRATE_BUFFER_LOCATION);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- }
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
- }
- else {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer_offsets[i],RSXGL_VERTEX_MIGRATE_BUFFER_LOCATION);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- rsxgl_query_object_set(context,query_index);
- rsxgl_timestamp_post(ctx,timestamp++);
- }
- }
+ std::unique_ptr< uint32_t > offsets;
+
+ draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type,const GLsizei * _count,const GLvoid * const * _indices,GLsizei _primcount) : element_draw_policy(_ctx,_rsx_primitive_type,_rsx_element_type), multi_draw_policy(_ctx), count(_count), indices(_indices), primcount(_primcount), offsets(new uint32_t[primcount]) {}
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_vertex_migrate_free(context,migrate_buffers[i],index_buffer_sizes[i]);
- }
- }
- else {
- uint32_t min_start = std::numeric_limits< uint32_t >::max(), max_length = std::numeric_limits< uint32_t >::min();
- for(GLsizei i = 0;i < primcount;++i) {
- min_start = std::min(min_start,(uint32_t)((uint64_t)indices[i]));
- max_length = std::max(max_length,(uint32_t)count[i]);
+ void begin(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::begin(gcm_context,timestamp,count,indices,primcount,offsets.get());
}
- rsxgl_buffer_validate(ctx,ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER],min_start,max_length,timestamp + primcount - 1);
-
- const buffer_t & index_buffer = ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER];
- const uint32_t
- location = index_buffer.memory.location;
- if(query_index == RSXGL_MAX_QUERY_OBJECTS) {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer.memory.offset + (uint32_t)((uint64_t)indices[i]),location);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- }
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
+ void draw(gcmContextData * gcm_context,uint32_t timestamp,unsigned int i) const {
+ element_draw_policy::emitIndexBufferCommands(gcm_context,offsets.get()[i]);
+ element_draw_policy::emitDrawCommands(gcm_context,count[i]);
+
+ multi_draw_policy::draw(gcm_context);
}
- else {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer.memory.offset + (uint32_t)((uint64_t)indices[i]),location);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- rsxgl_timestamp_post(ctx,timestamp++);
- }
+
+ void end(gcmContextData * gcm_context,uint32_t) const {
+ element_draw_policy::end(gcm_context);
}
- }
+ };
+
+ rsxgl_draw(ctx,ignore_element_range_policy(),multi_iteration_policy(primcount),draw_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices,primcount));
}
RSXGL_NOERROR_();
@@ -1143,8 +1181,8 @@ glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, c
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(primcount < 0) {
@@ -1156,159 +1194,37 @@ glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, c
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- gcmContextData * context = ctx -> gcm_context();
-
- const rsxgl_query_object_index_type query_index = ctx -> any_samples_passed_query;
- const bool client_indices = ctx -> buffer_binding.names[RSXGL_ELEMENT_ARRAY_BUFFER] == 0;
+ struct draw_policy : public element_draw_policy, public base_element_draw_policy, public multi_draw_policy {
+ const GLsizei * count;
+ const GLvoid * const * indices;
+ const GLsizei primcount;
+ const GLint * basevertex;
+
+ std::unique_ptr< uint32_t > offsets;
- uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,primcount);
-
- if(client_indices) {
- void * migrate_buffers[primcount];
- uint32_t index_buffer_sizes[primcount];
- uint32_t index_buffer_offsets[primcount];
- for(GLsizei i = 0;i < primcount;++i) {
- index_buffer_sizes[i] = (uint32_t)rsxgl_element_type_bytes[rsx_type] * count[i];
- migrate_buffers[i] = rsxgl_vertex_migrate_memalign(context,16,index_buffer_sizes[i]);
- memcpy(migrate_buffers[i],indices,index_buffer_sizes[i]);
- int32_t s = gcmAddressToOffset(migrate_buffers[i],index_buffer_offsets + i);
- rsxgl_assert(s == 0);
- }
+ draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type,const GLsizei * _count,const GLvoid * const * _indices,GLsizei _primcount,const GLint * _basevertex) : element_draw_policy(_ctx,_rsx_primitive_type,_rsx_element_type), multi_draw_policy(_ctx), count(_count), indices(_indices), primcount(_primcount), basevertex(_basevertex), offsets(new uint32_t[primcount]) {}
- if(query_index == RSXGL_MAX_QUERY_OBJECTS) {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer_offsets[i],RSXGL_VERTEX_MIGRATE_BUFFER_LOCATION);
- rsxgl_draw_array_elements_base(context,basevertex[i]);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- }
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
- }
- else {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer_offsets[i],RSXGL_VERTEX_MIGRATE_BUFFER_LOCATION);
- rsxgl_draw_array_elements_base(context,basevertex[i]);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- rsxgl_query_object_set(context,query_index);
- rsxgl_timestamp_post(ctx,timestamp++);
- }
+ void begin(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::begin(gcm_context,timestamp,count,indices,primcount,offsets.get());
}
- rsxgl_draw_array_elements_base(context,0);
-
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_vertex_migrate_free(context,migrate_buffers[i],index_buffer_sizes[i]);
+ void draw(gcmContextData * gcm_context,uint32_t timestamp,unsigned int i) const {
+ base_element_draw_policy::draw(gcm_context,basevertex[i]);
+ element_draw_policy::emitIndexBufferCommands(gcm_context,offsets.get()[i]);
+ element_draw_policy::emitDrawCommands(gcm_context,count[i]);
+ multi_draw_policy::draw(gcm_context);
}
- }
- else {
- uint32_t min_start = std::numeric_limits< uint32_t >::max(), max_length = std::numeric_limits< uint32_t >::min();
- for(GLsizei i = 0;i < primcount;++i) {
- min_start = std::min(min_start,(uint32_t)((uint64_t)indices[i]));
- max_length = std::max(max_length,(uint32_t)count[i]);
- }
- rsxgl_buffer_validate(ctx,ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER],min_start,max_length,timestamp + primcount - 1);
-
- const buffer_t & index_buffer = ctx -> buffer_binding[RSXGL_ELEMENT_ARRAY_BUFFER];
- const uint32_t
- location = index_buffer.memory.location;
- if(query_index == RSXGL_MAX_QUERY_OBJECTS) {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer.memory.offset + (uint32_t)((uint64_t)indices[i]),location);
- rsxgl_draw_array_elements_base(context,basevertex[i]);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
- }
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
+ void end(gcmContextData * gcm_context,uint32_t) const {
+ element_draw_policy::end(gcm_context);
+ base_element_draw_policy::end(gcm_context);
}
- else {
- for(GLsizei i = 0;i < primcount;++i) {
- rsxgl_draw_elements_emit_index_buffer(context,rsx_type,index_buffer.memory.offset + (uint32_t)((uint64_t)indices[i]),location);
- rsxgl_draw_array_elements_base(context,basevertex[i]);
- rsxgl_draw_array_elements(context,rsx_primitive_type,count[i]);
-
- rsxgl_timestamp_post(ctx,timestamp++);
- }
- }
-
- rsxgl_draw_array_elements_base(context,0);
- }
- }
-
- RSXGL_NOERROR_();
-}
-
-struct rsxgl_instance_info_t {
- uint32_t call_offset, jump_offset;
-
- rsxgl_instance_info_t(const uint32_t _call_offset,const uint32_t _jump_offset)
- : call_offset(_call_offset), jump_offset(_jump_offset) {
- }
-};
-
-static inline rsxgl_instance_info_t
-rsxgl_instance_draw_init(gcmContextData * context,const uint32_t nwords)
-{
- gcm_reserve(context,nwords + 2);
-
- // call location - current position + 1
- // jump location - current position + 1 word + nwords + 1 word
- uint32_t call_offset = 0, jump_offset = 0;
- int32_t s = 0;
-
- s = gcmAddressToOffset(context -> current + 1,&call_offset);
- rsxgl_assert(s == 0);
-
- s = gcmAddressToOffset(context -> current + nwords + 2,&jump_offset);
- rsxgl_assert(s == 0);
-
- return rsxgl_instance_info_t(call_offset,jump_offset);
-}
-
-// returns call_offset
-static inline uint32_t
-rsxgl_draw_arrays_instanced(gcmContextData * context,const uint32_t rsx_primitive_type,const uint32_t first,const uint32_t count)
-{
- const rsxgl_instance_info_t info = rsxgl_instance_draw_init(context,rsxgl_count_arrays(rsx_primitive_type,count));
+ };
- gcm_emit_at(context -> current,0,gcm_jump_cmd(info.jump_offset)); ++context -> current;
- rsxgl_draw_arrays(context,rsx_primitive_type,first,count);
- gcm_emit_at(context -> current,0,gcm_return_cmd()); ++context -> current;
-
- return info.call_offset;
-}
-
-static inline uint32_t
-rsxgl_draw_array_elements_instanced(gcmContextData * context,const uint32_t rsx_primitive_type,const uint32_t count)
-{
- const rsxgl_instance_info_t info = rsxgl_instance_draw_init(context,rsxgl_count_array_elements(rsx_primitive_type,count));
-
- gcm_emit_at(context -> current,0,gcm_jump_cmd(info.jump_offset)); ++context -> current;
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- gcm_emit_at(context -> current,0,gcm_return_cmd()); ++context -> current;
-
- return info.call_offset;
-}
-
-static inline uint32_t
-rsxgl_draw_instances(gcmContextData * context,const uint32_t primcount,const uint32_t instanceid_index,const uint32_t call_offset)
-{
- // TODO: Break instances into smaller batches based upon the size of the command buffer.
-
- const uint32_t call_cmd = gcm_call_cmd(call_offset);
-
- const uint32_t n = primcount * 4;
- uint32_t * buffer = gcm_reserve(context,n);
-
- for(uint32_t i = 0;i < primcount;++i,buffer += 4) {
- ieee32_t tmp;
- tmp.f = (float)i;
-
- gcm_emit_method_at(buffer,0,NV30_3D_VP_UPLOAD_CONST_ID,2);
- gcm_emit_at(buffer,1,instanceid_index);
- gcm_emit_at(buffer,2,tmp.u);
- gcm_emit_at(buffer,3,call_cmd);
+ rsxgl_draw(ctx,ignore_element_range_policy(),multi_iteration_policy(primcount),draw_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices,primcount,basevertex));
}
- gcm_finish_n_commands(context,n);
+ RSXGL_NOERROR_();
}
GLAPI void APIENTRY
@@ -1330,19 +1246,32 @@ glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcoun
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,primcount);
-
- const rsxgl_query_object_index_type query_index = ctx -> any_samples_passed_query;
+ struct draw_policy : public array_draw_policy, public instanced_draw_policy {
+ const GLint first;
+ const GLsizei count;
+
+ draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,const GLsizei _first,const GLsizei _count)
+ : array_draw_policy(_rsx_primitive_type), instanced_draw_policy(_ctx), first(_first), count(_count) {}
+
+ void begin(gcmContextData * gcm_context,uint32_t) const {
+ instanced_draw_policy::beginInstance(gcm_context,array_draw_policy::countDrawCommands(count));
+ array_draw_policy::draw(gcm_context,first,count);
+ instanced_draw_policy::endInstance(gcm_context);
+ }
+
+ void draw(gcmContextData * gcm_context,uint32_t,unsigned int i) const {
+ instanced_draw_policy::draw(gcm_context,i);
+ }
+
+ void end(gcmContextData * gcm_context,uint32_t) const {}
+ };
- const uint32_t instanceid_index = ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index;
- if(instanceid_index != ~0 && primcount > 1) {
- rsxgl_draw_instances(context,primcount,instanceid_index,rsxgl_draw_arrays_instanced(context,rsx_primitive_type,first,count));
+ if(ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index != ~0 && primcount > 1) {
+ rsxgl_draw(ctx,ignore_element_range_policy(),multi_iteration_policy(primcount),draw_policy(ctx,rsx_primitive_type,first,count));
}
else {
- rsxgl_draw_arrays_instanced(context,rsx_primitive_type,first,count);
+ rsxgl_draw(ctx,arrays_element_range_policy(first,count),single_iteration_policy(),draw_arrays_policy(rsx_primitive_type,first,count));
}
-
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
}
RSXGL_NOERROR_();
@@ -1354,8 +1283,8 @@ glDrawElementsInstanced (const GLenum mode, const GLsizei count, const GLenum ty
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(count < 0) {
@@ -1367,21 +1296,39 @@ glDrawElementsInstanced (const GLenum mode, const GLsizei count, const GLenum ty
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- gcmContextData * context = ctx -> gcm_context();
-
- const rsxgl_query_object_index_type query_index = ctx -> any_samples_passed_query;
- const uint32_t instanceid_index = ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index;
+ struct draw_policy : public element_draw_policy, public instanced_draw_policy {
+ const GLsizei count;
+ const GLvoid * indices;
+
+ mutable uint32_t offset;
+
+ draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type,const GLsizei _count,const GLvoid * _indices)
+ : element_draw_policy(_ctx,_rsx_primitive_type,_rsx_element_type), instanced_draw_policy(_ctx), count(_count), indices(_indices) {}
+
+ void begin(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::begin(gcm_context,timestamp,&count,&indices,1,&offset);
+ element_draw_policy::emitIndexBufferCommands(gcm_context,offset);
+
+ instanced_draw_policy::beginInstance(gcm_context,element_draw_policy::countDrawCommands(count));
+ element_draw_policy::emitDrawCommands(gcm_context,count);
+ instanced_draw_policy::endInstance(gcm_context);
+ }
+
+ void draw(gcmContextData * gcm_context,uint32_t,unsigned int i) const {
+ instanced_draw_policy::draw(gcm_context,i);
+ }
+
+ void end(gcmContextData * gcm_context,uint32_t) const {
+ element_draw_policy::end(gcm_context);
+ }
+ };
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,primcount);
- const rsxgl_draw_elements_info_t info = rsxgl_draw_elements_init(ctx,0,0,count,rsx_type,indices,timestamp);
- if(instanceid_index != ~0 && primcount > 1) {
- rsxgl_draw_instances(context,primcount,instanceid_index,rsxgl_draw_array_elements_instanced(context,rsx_primitive_type,count));
+ if(ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index != ~0 && primcount > 1) {
+ rsxgl_draw(ctx,ignore_element_range_policy(),multi_iteration_policy(primcount),draw_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices));
}
else {
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
- }
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
- rsxgl_draw_elements_exit(ctx,info);
+ rsxgl_draw(ctx,ignore_element_range_policy(),single_iteration_policy(),draw_elements_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices));
+ }
}
RSXGL_NOERROR_();
@@ -1393,8 +1340,8 @@ glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, cons
rsxgl_context_t * ctx = current_ctx();
RSXGL_FORWARD_ERROR_BEGIN();
- uint32_t rsx_primitive_type = 0, rsx_type = 0;
- std::tie(rsx_primitive_type,rsx_type) = rsxgl_check_draw_elements(ctx,mode,type);
+ uint32_t rsx_primitive_type = 0, rsx_element_type = 0;
+ std::tie(rsx_primitive_type,rsx_element_type) = rsxgl_check_draw_elements(ctx,mode,type);
RSXGL_FORWARD_ERROR_END();
if(count < 0) {
@@ -1406,23 +1353,41 @@ glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, cons
}
if(ctx -> state.enable.conditional_render_status != RSXGL_CONDITIONAL_RENDER_ACTIVE_WAIT_FAIL) {
- gcmContextData * context = ctx -> gcm_context();
+ struct draw_policy : public element_draw_policy, public base_element_draw_policy, public instanced_draw_policy {
+ const GLsizei count;
+ const GLvoid * indices;
+ const GLint basevertex;
- const rsxgl_query_object_index_type query_index = ctx -> any_samples_passed_query;
- const uint32_t instanceid_index = ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index;
-
- const uint32_t timestamp = rsxgl_draw_init(ctx,mode,0,0,primcount);
- const rsxgl_draw_elements_info_t info = rsxgl_draw_elements_init(ctx,0,0,count,rsx_type,indices,timestamp);
- rsxgl_draw_array_elements_base(context,basevertex);
- if(instanceid_index != ~0 && primcount > 1) {
- rsxgl_draw_instances(context,primcount,instanceid_index,rsxgl_draw_array_elements_instanced(context,rsx_primitive_type,count));
+ mutable uint32_t offset;
+
+ draw_policy(rsxgl_context_t * _ctx,uint32_t _rsx_primitive_type,uint32_t _rsx_element_type,GLsizei _count,const GLvoid * _indices,GLint _basevertex)
+ : element_draw_policy(_ctx,_rsx_primitive_type,_rsx_element_type), instanced_draw_policy(_ctx), count(_count), indices(_indices), basevertex(_basevertex) {}
+
+ void begin(gcmContextData * gcm_context,uint32_t timestamp) const {
+ element_draw_policy::begin(gcm_context,timestamp,&count,&indices,1,&offset);
+ base_element_draw_policy::draw(gcm_context,basevertex);
+ element_draw_policy::emitIndexBufferCommands(gcm_context,offset);
+
+ instanced_draw_policy::beginInstance(gcm_context,element_draw_policy::countDrawCommands(count));
+ element_draw_policy::emitDrawCommands(gcm_context,count);
+ instanced_draw_policy::endInstance(gcm_context);
+ }
+
+ void draw(gcmContextData * gcm_context,uint32_t,unsigned int i) const {
+ instanced_draw_policy::draw(gcm_context,i);
+ }
+
+ void end(gcmContextData * gcm_context,uint32_t) const {
+ element_draw_policy::end(gcm_context);
+ }
+ };
+
+ if(ctx -> program_binding[RSXGL_ACTIVE_PROGRAM].instanceid_index != ~0 && primcount > 1) {
+ rsxgl_draw(ctx,ignore_element_range_policy(),multi_iteration_policy(primcount),draw_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices,basevertex));
}
else {
- rsxgl_draw_array_elements(context,rsx_primitive_type,count);
+ rsxgl_draw(ctx,ignore_element_range_policy(),single_iteration_policy(),draw_elements_base_policy(ctx,rsx_primitive_type,rsx_element_type,count,indices,basevertex));
}
- rsxgl_draw_array_elements_base(context,0);
- rsxgl_timestamp_post(ctx,timestamp + primcount - 1);
- rsxgl_draw_elements_exit(ctx,info);
}
RSXGL_NOERROR_();
View
15 src/library/program.cc
@@ -1158,8 +1158,19 @@ glLinkProgram (GLuint program_name)
}
}
- // TODO: deal with these:
- program.instanceid_index = ~0;
+ {
+ program_t::uniform_table_type::type table = program.uniform_table();
+
+ const std::pair< bool, program_t::uniform_size_type > tmp = table.find(program.names(),"rsxgl_InstanceID");
+ if(tmp.first) {
+ program.instanceid_index = table[tmp.second].second.vp_index;
+ }
+ else {
+ program.instanceid_index = ~0;
+ }
+ }
+
+ // TODO: deal with this:
program.point_sprite_control = 0;
#if 0
View
8 src/library/program.h
@@ -154,6 +154,10 @@ struct program_t {
bool operator()(const value_type & lhs,const char * rhs) const {
return strcmp(names.values + lhs.first,rhs) < 0;
}
+
+ bool operator()(const char * rhs,const value_type & lhs) const {
+ return strcmp(names.values + lhs.first,rhs) < 0;
+ }
};
struct find_eq {
@@ -164,6 +168,10 @@ struct program_t {
bool operator()(const value_type & lhs,const char * rhs) const {
return strcmp(names.values + lhs.first,rhs) == 0;
}
+
+ bool operator()(const char * rhs,const value_type & lhs) const {
+ return strcmp(names.values + lhs.first,rhs) == 0;
+ }
};
struct type : public array_type::type {
View
20 src/library/textures.cc
@@ -1222,7 +1222,6 @@ rsxgl_texture_validate_storage(rsxgl_context_t * ctx,texture_t & texture)
const uint32_t fmt = pfmt -> fmt[4] | NV40_3D_TEX_FORMAT_LINEAR | (texture.rect ? NV40_3D_TEX_FORMAT_RECT : 0) | 0x8000;
-#if 0
rsxgl_debug_printf("%s: dims:%u pformat:%u size:%ux%ux%u pitch:%u levels:%u bytes:%u fmt:%x\n",__PRETTY_FUNCTION__,
(unsigned int)texture.dims,
(unsigned int)texture.pformat,
@@ -1231,7 +1230,6 @@ rsxgl_texture_validate_storage(rsxgl_context_t * ctx,texture_t & texture)
(unsigned int)texture.num_levels,
(unsigned int)nbytes,(unsigned int)fmt);
rsxgl_debug_printf("\toffset:%u\n",texture.memory.offset);
-#endif
texture.format =
((texture.memory.location == 0) ? NV30_3D_TEX_FORMAT_DMA0 : NV30_3D_TEX_FORMAT_DMA1) |
@@ -2124,19 +2122,35 @@ rsxgl_textures_validate(rsxgl_context_t * ctx,program_t & program,const uint32_t
// TODO: Set LOD min, max, bias:
}
if(invalid_it.test() || invalid_textures.test(api_index)) {
+#if 0
+ rsxgl_debug_printf("trying to activate vertex sampler: %u\n",index);
+#endif
+
texture_t & texture = ctx -> texture_binding[api_index];
rsxgl_texture_validate(ctx,texture,timestamp);
if(texture.memory) {
+#if 0
+ rsxgl_debug_printf("\tit has memory\n");
+#endif
+
const uint32_t format = texture.format & (0x3 | NV30_3D_TEX_FORMAT_DIMS__MASK | NV30_3D_TEX_FORMAT_FORMAT__MASK | NV40_3D_TEX_FORMAT_MIPMAP_COUNT__MASK);
const uint32_t format_format = (format & NV30_3D_TEX_FORMAT_FORMAT__MASK);
+#if 0
+ rsxgl_debug_printf("\ttexture.format: %x format: %x format_format: %x\n",texture.format,format,format_format);
+#endif
+
static const uint32_t
RGBA32F_format = NV40_3D_TEX_FORMAT_FORMAT_RGBA32F | NV40_3D_TEX_FORMAT_LINEAR | 0x9000,
- R32F_format = 0x1b00 | NV40_3D_TEX_FORMAT_LINEAR | 0x9000;
+ R32F_format = 0x1c00 | NV40_3D_TEX_FORMAT_LINEAR | 0x9000;
if(format_format == RGBA32F_format || format_format == R32F_format) {
+#if 0
+ rsxgl_debug_printf("\tactivating vertex sampler: %u\n",index);
+#endif
+
// activate the texture:
uint32_t * buffer = gcm_reserve(context,9);
View
5 src/nvfx/nvfx_screen.c
@@ -573,12 +573,17 @@ nvfx_screen_create(struct nouveau_device *dev)
screen->inline_cost_per_hardware_cost = atof(debug_get_option("NVFX_INLINE_COST_PER_HARDWARE_COST", "1.0"));
screen->static_reuse_threshold = atof(debug_get_option("NVFX_STATIC_REUSE_THRESHOLD", "2.0"));
+#if !defined(__RSXGL__)
/* We don't advertise these by default because filtering and blending doesn't work as
* it should, due to several restrictions.
* The only exception is fp16 on nv40.
*/
screen->advertise_fp16 = debug_get_bool_option("NVFX_FP16", !!screen->use_nv4x);
screen->advertise_fp32 = debug_get_bool_option("NVFX_FP32", 0);
+#else
+ screen->advertise_fp16 = TRUE;
+ screen->advertise_fp32 = TRUE;
+#endif
screen->vertex_buffer_reloc_flags = nvfx_screen_get_vertex_buffer_flags(screen);
View
8 src/samples/rsxgltest/Makefile.am
@@ -16,7 +16,8 @@ BUILT_SOURCES = textures_vpo.h textures_fpo.h \
occlusion_vpo.h occlusion_fpo.h \
gradient_png.h \
texcube_vert.h texcube_frag.h \
- points_vert.h points_frag.h
+ points_vert.h points_frag.h \
+ cube_vert.h cube_frag.h
CLEANFILES = draw_vpo.h draw_fpo.h draw_vpo.o draw_fpo.o \
textures_vpo.h textures_fpo.h textures_vpo.o textures_fpo.o \
manypoints_vpo.h manypoints_fpo.h manypoints_vpo.o manypoints_fpo.o \
@@ -31,7 +32,8 @@ CLEANFILES = draw_vpo.h draw_fpo.h draw_vpo.o draw_fpo.o \
face_png.o face_png.h \
gradient_png.o gradient_png.h \
texcube_vert.h texcube_frag.h \
- points_vert.h points_frag.h
+ points_vert.h points_frag.h \
+ cube_vert.h cube_frag.h
# clear.c viewport_scissor.c buffer.c program.c draw.c uniforms.c textures.c cube.cc
clear_objects =
@@ -46,7 +48,7 @@ textures_sources = textures.c texture.c textures.vert textures.frag dice.bin
manypoints_objects = face_png.o
manypoints_sources = manypoints.cc texture.c points.vert points.frag face.png
-manycubes_objects = cube_vpo.o cube_fpo.o
+manycubes_objects =
manycubes_sources = manycubes.cc cube.vert cube.frag
texcube_objects = nagel_bin.o gradient_png.o face_png.o
View
1  src/samples/rsxgltest/cube.frag
@@ -1,3 +1,4 @@
+#version 130
varying vec3 c;
void
View
4 src/samples/rsxgltest/cube.vert
@@ -1,3 +1,4 @@
+#version 130
attribute vec3 position;
attribute vec3 color;
@@ -25,7 +26,8 @@ main(void)
texture1D(texture,i + _delta2),
texture1D(texture,i + _delta3));
- gl_Position = ProjMatrix * (TransMatrix * m * vec4(position,1));
+ //gl_Position = ProjMatrix * (TransMatrix * m * vec4(position,1));
+ gl_Position = ProjMatrix * (TransMatrix * vec4(position,1));
c = vec3(0.5,0.5,0.5);
}
View
35 src/samples/rsxgltest/manycubes.cc
@@ -11,8 +11,8 @@
#include "sine_wave.h"
#include <stddef.h>
-#include "cube_vpo.h"
-#include "cube_fpo.h"
+#include "cube_vert.h"
+#include "cube_frag.h"
#include <io/pad.h>
@@ -82,7 +82,7 @@ Eigen::Affine3f ViewMatrixInv =
)
).inverse();
-const GLuint ncubes = 100;
+const GLuint ncubes = 10;
extern "C"
void
@@ -115,8 +115,33 @@ rsxgltest_init(int argc,const char ** argv)
glAttachShader(program,shaders[1]);
// Supply shader binaries:
- glShaderBinary(1,shaders,0,cube_vpo,cube_vpo_size);
- glShaderBinary(1,shaders + 1,0,cube_fpo,cube_fpo_size);
+ //glShaderBinary(1,shaders,0,cube_vpo,cube_vpo_size);
+ //glShaderBinary(1,shaders + 1,0,cube_fpo,cube_fpo_size);
+
+ // Supply shader SOURCES!
+ char szInfo[2048];
+
+ const GLchar * shader_srcs[] = { (const GLchar *)cube_vert, (const GLchar *)cube_frag };
+ GLint shader_srcs_lengths[] = { cube_vert_len, cube_frag_len };
+ GLint compiled = 0;
+
+ glShaderSource(shaders[0],1,shader_srcs,shader_srcs_lengths);
+ glCompileShader(shaders[0]);
+
+ glGetShaderiv(shaders[0],GL_COMPILE_STATUS,&compiled);
+ tcp_printf("shader compile status: %i\n",compiled);
+
+ glGetShaderInfoLog(shaders[0],2048,0,szInfo);
+ tcp_printf("%s\n",szInfo);
+
+ glShaderSource(shaders[1],1,shader_srcs + 1,shader_srcs_lengths + 1);
+ glCompileShader(shaders[1]);
+
+ glGetShaderiv(shaders[1],GL_COMPILE_STATUS,&compiled);
+ tcp_printf("shader compile status: %i\n",compiled);
+
+ glGetShaderInfoLog(shaders[1],2048,0,szInfo);
+ tcp_printf("%s\n",szInfo);
// Link the program for real:
glLinkProgram(program);
View
52 src/samples/rsxgltest/manypoints.cc
@@ -72,6 +72,11 @@ const GLuint nbatch = (npoints / batchsize) + ((npoints % batchsize) ? 1 : 0);
GLint batchfirst[nbatch];
GLsizei batchcount[nbatch];
+GLvoid const * batchoffsets[nbatch];
+
+GLuint * client_elements = 0;
+GLvoid const * client_batchindices[nbatch];
+GLuint elements = 0;
#define DTOR(X) ((X)*0.01745329f)
#define RTOD(d) ((d)*57.295788f)
@@ -194,14 +199,37 @@ rsxgltest_init(int argc,const char ** argv)
geometry[5] = 1.0;
}
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ client_elements = (GLuint *)malloc(sizeof(GLuint) * npoints);
+ for(size_t i = 0;i < npoints;++i) {
+ client_elements[i] = i;
+ }
+
GLint first = 0;
for(size_t i = 0;i < nbatch;++i) {
batchfirst[i] = first;
batchcount[i] = (i == (nbatch - 1)) ? (npoints % batchsize) : (batchsize);
+ batchoffsets[i] = (GLvoid const*)((uint64_t)first * sizeof(GLuint));
+ client_batchindices[i] = client_elements + first;
first += batchsize;
}
- glUnmapBuffer(GL_ARRAY_BUFFER);
+ glGenBuffers(1,&elements);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elements);
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLuint) * npoints,0,GL_STATIC_DRAW);
+
+ GLuint * pelements = (GLuint *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER,GL_WRITE_ONLY);
+
+ for(size_t i = 0;i < npoints;++i) {
+ pelements[i] = i;
+ }
+
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glEnableVertexAttribArray(vertex_location);
//glEnableVertexAttribArray(color_location);
@@ -255,12 +283,30 @@ rsxgltest_draw()
Eigen::Affine3f modelview = ViewMatrixInv * (Eigen::Affine3f::Identity() * Eigen::Translation3f(0,0,0) * rotmat);
glUniformMatrix4fv(TransMatrix_location,1,GL_FALSE,modelview.data());
- if(frame % 2) {
+ int which = frame % 6;
+
+ if(which == 0) {
glDrawArrays(GL_POINTS,0,npoints);
}
- else {
+ else if(which == 1) {
glMultiDrawArrays(GL_POINTS,batchfirst,batchcount,nbatch);
}
+ else if(which == 2) {
+ glDrawElements(GL_POINTS,npoints,GL_UNSIGNED_INT,client_elements);
+ }
+ else if(which == 3) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elements);
+ glDrawElements(GL_POINTS,npoints,GL_UNSIGNED_INT,0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+ }
+ else if(which == 4) {
+ glMultiDrawElements(GL_POINTS,batchcount,GL_UNSIGNED_INT,client_batchindices,nbatch);
+ }
+ else if(which == 5) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elements);
+ glMultiDrawElements(GL_POINTS,batchcount,GL_UNSIGNED_INT,batchoffsets,nbatch);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+ }
}
++frame;

No commit comments for this range

Something went wrong with that request. Please try again.