Merge branch 'r300g-vbo'

This is an experimental HW TCL fastpath for r300g. It should run alright.

Thanks to osiris for making this possible.
This commit is contained in:
Corbin Simpson 2009-11-07 12:01:48 -08:00
commit b7322fd874
13 changed files with 447 additions and 114 deletions

View file

@ -17,6 +17,7 @@ C_SOURCES = \
r300_state.c \
r300_state_derived.c \
r300_state_invariant.c \
r300_vbo.c \
r300_vs.c \
r300_texture.c \
r300_tgsi_to_rc.c

View file

@ -104,6 +104,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct r300_winsys* r300_winsys)
{
struct r300_context* r300 = CALLOC_STRUCT(r300_context);
struct r300_screen* r300screen = r300_screen(screen);
if (!r300)
return NULL;
@ -119,9 +120,16 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.clear = r300_clear;
r300->context.draw_arrays = r300_draw_arrays;
r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
if (r300screen->caps->has_tcl)
{
r300->context.draw_arrays = r300_draw_arrays;
r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_draw_range_elements;
}
else
{
assert(0);
}
r300->context.is_texture_referenced = r300_is_texture_referenced;
r300->context.is_buffer_referenced = r300_is_buffer_referenced;

View file

@ -216,18 +216,19 @@ struct r300_texture {
struct r300_texture_state state;
};
struct r300_vertex_format {
struct r300_vertex_info {
/* Parent class */
struct vertex_info vinfo;
/* R300_VAP_PROG_STREAK_CNTL_[0-7] */
uint32_t vap_prog_stream_cntl[8];
/* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
uint32_t vap_prog_stream_cntl_ext[8];
/* Map of vertex attributes into PVS memory for HW TCL,
* or GA memory for SW TCL. */
int vs_tab[16];
/* Map of rasterizer attributes from GB through RS to US. */
int fs_tab[16];
/* R300_VAP_PROG_STREAK_CNTL_[0-7] */
uint32_t vap_prog_stream_cntl[8];
/* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
uint32_t vap_prog_stream_cntl_ext[8];
};
extern struct pipe_viewport_state r300_viewport_identity;
@ -256,7 +257,7 @@ struct r300_context {
* depends on the combination of both currently loaded shaders. */
struct util_hash_table* shader_hash_table;
/* Vertex formatting information. */
struct r300_vertex_format* vertex_info;
struct r300_vertex_info* vertex_info;
/* Various CSO state objects. */
/* Blend state. */
@ -285,12 +286,6 @@ struct r300_context {
/* Texture states. */
struct r300_texture* textures[8];
int texture_count;
/* Vertex buffers for Gallium. */
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
int vertex_buffer_count;
/* Vertex elements for Gallium. */
struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
int vertex_element_count;
/* Vertex shader. */
struct r300_vertex_shader* vs;
/* Viewport state. */
@ -298,6 +293,13 @@ struct r300_context {
/* ZTOP state. */
struct r300_ztop_state ztop_state;
/* Vertex buffers for Gallium. */
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
int vbuf_count;
/* Vertex elements for Gallium. */
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
int aos_count;
/* Bitmask of dirty state objects. */
uint32_t dirty_state;
/* Flag indicating whether or not the HW is dirty. */

View file

@ -34,8 +34,8 @@
#define MAX_CS_SIZE 64 * 1024 / 4
#define VERY_VERBOSE_CS 0
#define VERY_VERBOSE_REGISTERS 0
#define VERY_VERBOSE_CS 1
#define VERY_VERBOSE_REGISTERS 1
/* XXX stolen from radeon_drm.h */
#define RADEON_GEM_DOMAIN_CPU 0x1

View file

@ -582,7 +582,48 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
void r300_emit_vertex_buffer(struct r300_context* r300)
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element;
CS_LOCALS(r300);
int i;
unsigned packet_size = (r300->aos_count * 3 + 1) / 2;
BEGIN_CS(2 + packet_size + r300->aos_count * 2);
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(r300->aos_count);
for (i = 0; i < r300->aos_count - 1; i += 2) {
int buf_num1 = velem[i].vertex_buffer_index;
int buf_num2 = velem[i+1].vertex_buffer_index;
assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0);
OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) |
(pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22));
OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset +
offset * vbuf[buf_num1].stride);
OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset +
offset * vbuf[buf_num2].stride);
}
if (r300->aos_count & 1) {
int buf_num = velem[i].vertex_buffer_index;
assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6));
OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset +
offset * vbuf[buf_num].stride);
}
for (i = 0; i < r300->aos_count; i++) {
cs_winsys->write_cs_reloc(cs_winsys,
vbuf[velem[i].vertex_buffer_index].buffer,
RADEON_GEM_DOMAIN_GTT,
0,
0);
cs_count -= 2;
}
END_CS;
}
#if 0
void r300_emit_draw_packet(struct r300_context* r300)
{
CS_LOCALS(r300);
@ -605,6 +646,7 @@ void r300_emit_vertex_buffer(struct r300_context* r300)
OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS;
}
#endif
void r300_emit_vertex_format_state(struct r300_context* r300)
{
@ -771,8 +813,6 @@ void r300_emit_dirty_state(struct r300_context* r300)
return;
}
r300_update_derived_state(r300);
/* Clean out BOs. */
r300->winsys->reset_bos(r300->winsys);
@ -823,7 +863,7 @@ validate:
goto validate;
}
} else {
debug_printf("No VBO while emitting dirty state!\n");
// debug_printf("No VBO while emitting dirty state!\n");
}
if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
@ -951,7 +991,7 @@ validate:
*/
/* Finally, emit the VBO. */
r300_emit_vertex_buffer(r300);
//r300_emit_vertex_buffer(r300);
r300->dirty_hw++;
}

View file

@ -29,6 +29,8 @@
struct rX00_fragment_program_code;
struct r300_vertex_program_code;
void r300_emit_aos(struct r300_context* r300, unsigned offset);
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend);

View file

@ -20,6 +20,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* r300_render: Vertex and index buffer primitive emission. Contains both
* HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
@ -34,11 +37,12 @@
#include "r300_reg.h"
#include "r300_render.h"
#include "r300_state_derived.h"
#include "r300_vbo.h"
/* r300_render: Vertex and index buffer primitive emission. */
#define R300_MAX_VBO_SIZE (1024 * 1024)
static uint32_t r300_translate_primitive(unsigned prim)
uint32_t r300_translate_primitive(unsigned prim)
{
switch (prim) {
case PIPE_PRIM_POINTS:
@ -66,6 +70,94 @@ static uint32_t r300_translate_primitive(unsigned prim)
}
}
static void r300_emit_draw_arrays(struct r300_context *r300,
unsigned mode,
unsigned count)
{
CS_LOCALS(r300);
BEGIN_CS(4);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300_translate_primitive(mode));
END_CS;
}
static void r300_emit_draw_elements(struct r300_context *r300,
struct pipe_buffer* indexBuffer,
unsigned indexSize,
unsigned minIndex,
unsigned maxIndex,
unsigned mode,
unsigned start,
unsigned count)
{
uint32_t count_dwords;
uint32_t offset_dwords = indexSize * start / sizeof(uint32_t);
CS_LOCALS(r300);
/* XXX most of these are stupid */
assert(indexSize == 4 || indexSize == 2);
assert((start * indexSize) % 4 == 0);
assert(offset_dwords == 0);
BEGIN_CS(10);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) {
count_dwords = count + start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
r300_translate_primitive(mode));
} else {
count_dwords = (count + start + 1) / 2;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300_translate_primitive(mode));
}
/* INDX_BUFFER is a truly special packet3.
* Unlike most other packet3, where the offset is after the count,
* the order is reversed, so the relocation ends up carrying the
* size of the indexbuf instead of the offset.
*
* XXX Fix offset
*/
OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
OUT_CS(offset_dwords);
OUT_CS_RELOC(indexBuffer, count_dwords,
RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS;
}
static boolean r300_setup_vertex_buffers(struct r300_context *r300)
{
unsigned vbuf_count = r300->aos_count;
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element;
validate:
for (int i = 0; i < vbuf_count; i++) {
if (!r300->winsys->add_buffer(r300->winsys,
vbuf[velem[i].vertex_buffer_index].buffer,
RADEON_GEM_DOMAIN_GTT, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
return r300->winsys->validate(r300->winsys);
}
return TRUE;
}
/* This is the fast-path drawing & emission for HW TCL. */
boolean r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
@ -77,87 +169,31 @@ boolean r300_draw_range_elements(struct pipe_context* pipe,
unsigned count)
{
struct r300_context* r300 = r300_context(pipe);
uint32_t prim = r300_translate_primitive(mode);
struct pipe_vertex_buffer* aos = r300->vertex_buffers;
unsigned aos_count = r300->vertex_buffer_count;
short* indices;
unsigned packet_size;
unsigned i;
bool invalid = FALSE;
CS_LOCALS(r300);
if (!u_trim_pipe_prim(mode, &count)) {
return FALSE;
}
validate:
for (i = 0; i < aos_count; i++) {
if (!r300->winsys->add_buffer(r300->winsys, aos[i].buffer,
RADEON_GEM_DOMAIN_GTT, 0)) {
pipe->flush(pipe, 0, NULL);
goto validate;
}
if (count > 65535) {
return FALSE;
}
if (!r300->winsys->validate(r300->winsys)) {
pipe->flush(pipe, 0, NULL);
if (invalid) {
/* Well, hell. */
debug_printf("r300: Stuck in validation loop, gonna quit now.");
exit(1);
}
invalid = TRUE;
goto validate;
r300_update_derived_state(r300);
if (!r300_setup_vertex_buffers(r300)) {
return FALSE;
}
setup_vertex_attributes(r300);
setup_index_buffer(r300, indexBuffer, indexSize);
r300_emit_dirty_state(r300);
packet_size = (aos_count >> 1) * 3 + (aos_count & 1) * 2;
r300_emit_aos(r300, 0);
BEGIN_CS(3 + packet_size + (aos_count * 2));
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(aos_count);
for (i = 0; i < aos_count - 1; i += 2) {
OUT_CS(aos[i].stride |
(aos[i].stride << 8) |
(aos[i + 1].stride << 16) |
(aos[i + 1].stride << 24));
OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride);
OUT_CS(aos[i + 1].buffer_offset + start * 4 * aos[i + 1].stride);
}
if (aos_count & 1) {
OUT_CS(aos[i].stride | (aos[i].stride << 8));
OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride);
}
for (i = 0; i < aos_count; i++) {
OUT_CS_RELOC(aos[i].buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
}
END_CS;
if (indexBuffer) {
indices = (short*)pipe_buffer_map(pipe->screen, indexBuffer,
PIPE_BUFFER_USAGE_CPU_READ);
/* Set the starting point. */
indices += start;
BEGIN_CS(2 + (count+1)/2);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count + 1)/2);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | prim);
for (i = 0; i < count - 1; i += 2) {
OUT_CS(indices[i + 1] << 16 | indices[i]);
}
if (count % 2) {
OUT_CS(indices[count - 1]);
}
END_CS;
} else {
BEGIN_CS(2);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
prim);
END_CS;
}
r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex,
mode, start, count);
return TRUE;
}
@ -175,7 +211,31 @@ boolean r300_draw_elements(struct pipe_context* pipe,
boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
unsigned start, unsigned count)
{
return pipe->draw_elements(pipe, NULL, 0, mode, start, count);
struct r300_context* r300 = r300_context(pipe);
if (!u_trim_pipe_prim(mode, &count)) {
return FALSE;
}
if (count > 65535) {
return FALSE;
}
r300_update_derived_state(r300);
if (!r300_setup_vertex_buffers(r300)) {
return FALSE;
}
setup_vertex_attributes(r300);
r300_emit_dirty_state(r300);
r300_emit_aos(r300, start);
r300_emit_draw_arrays(r300, mode, count);
return TRUE;
}
/****************************************************************************
@ -183,7 +243,8 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
* keep these functions separated so that they are easier to locate. ~C. *
***************************************************************************/
/* Draw-based drawing for SW TCL chipsets. */
/* Draw-based drawing for SW TCL chipsets.
* XXX currently broken as fucking hell. */
boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
unsigned indexSize,
@ -193,6 +254,8 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
unsigned start,
unsigned count)
{
assert(0);
#if 0
struct r300_context* r300 = r300_context(pipe);
int i;
@ -233,7 +296,7 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
draw_set_mapped_element_buffer_range(r300->draw, 0, start,
start + count - 1, NULL);
}
#endif
return TRUE;
}

View file

@ -23,6 +23,8 @@
#ifndef R300_RENDER_H
#define R300_RENDER_H
uint32_t r300_translate_primitive(unsigned prim);
boolean r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
unsigned indexSize,

View file

@ -577,6 +577,8 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
if (count > 8) {
return;
}
r300->context.flush(&r300->context, 0, NULL);
for (i = 0; i < count; i++) {
if (r300->textures[i] != (struct r300_texture*)texture[i]) {
@ -664,10 +666,9 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
memcpy(r300->vertex_buffers, buffers,
memcpy(r300->vertex_buffer, buffers,
sizeof(struct pipe_vertex_buffer) * count);
r300->vertex_buffer_count = count;
r300->vbuf_count = count;
if (r300->draw) {
draw_flush(r300->draw);
@ -681,10 +682,10 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
memcpy(r300->vertex_elements, elements,
sizeof(struct pipe_vertex_element) * count);
r300->vertex_element_count = count;
memcpy(r300->vertex_element,
elements,
sizeof(struct pipe_vertex_element) * count);
r300->aos_count = count;
if (r300->draw) {
draw_flush(r300->draw);

View file

@ -63,7 +63,7 @@ int r300_shader_key_compare(void* key1, void* key2) {
/* Set up the vs_tab and routes. */
static void r300_vs_tab_routes(struct r300_context* r300,
struct r300_vertex_format* vformat)
struct r300_vertex_info* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct vertex_info* vinfo = &vformat->vinfo;
@ -219,7 +219,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,
/* Update the PSC tables. */
static void r300_vertex_psc(struct r300_context* r300,
struct r300_vertex_format* vformat)
struct r300_vertex_info* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct vertex_info* vinfo = &vformat->vinfo;
@ -282,7 +282,7 @@ static void r300_vertex_psc(struct r300_context* r300,
/* Set up the mappings from GB to US, for RS block. */
static void r300_update_fs_tab(struct r300_context* r300,
struct r300_vertex_format* vformat)
struct r300_vertex_info* vformat)
{
struct tgsi_shader_info* info = &r300->fs->info;
int i, cols = 0, texs = 0, cols_emitted = 0;
@ -455,13 +455,13 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Update the vertex format. */
static void r300_update_derived_shader_state(struct r300_context* r300)
{
struct r300_shader_key* key;
struct r300_vertex_format* vformat;
struct r300_vertex_info* vformat;
struct r300_rs_block* rs_block;
struct r300_shader_derived_value* value;
int i;
/*
struct r300_shader_key* key;
struct r300_shader_derived_value* value;
key = CALLOC_STRUCT(r300_shader_key);
key->vs = r300->vs;
key->fs = r300->fs;
@ -486,7 +486,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
} */
/* XXX This will be refactored ASAP. */
vformat = CALLOC_STRUCT(r300_vertex_format);
vformat = CALLOC_STRUCT(r300_vertex_info);
rs_block = CALLOC_STRUCT(r300_rs_block);
for (i = 0; i < 16; i++) {

View file

@ -434,8 +434,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {
unsigned components = pf_component_count(format);
if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
debug_printf("r300: Bad format %s in %s\n", pf_name(format),
__FUNCTION__);
debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format),
__FUNCTION__, __LINE__);
return 0;
}
@ -447,6 +447,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {
result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
break;
default:
debug_printf("r300: Bad format %s in %s:%d\n",
pf_name(format), __FUNCTION__, __LINE__);
assert(0);
}
break;
@ -470,10 +472,16 @@ r300_translate_vertex_data_type(enum pipe_format format) {
}
break;
default:
debug_printf("r300: Bad format %s in %s:%d\n",
pf_name(format), __FUNCTION__, __LINE__);
debug_printf("r300: pf_size_x(format) == %d\n",
pf_size_x(format));
assert(0);
}
break;
default:
debug_printf("r300: Bad format %s in %s:%d\n",
pf_name(format), __FUNCTION__, __LINE__);
assert(0);
}
@ -492,8 +500,8 @@ static INLINE uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format) {
if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
debug_printf("r300: Bad format %s in %s\n", pf_name(format),
__FUNCTION__);
debug_printf("r300: Bad format %s in %s:%d\n",
pf_name(format), __FUNCTION__, __LINE__);
return 0;
}

View file

@ -0,0 +1,170 @@
/*
* Copyright 2009 Maciej Cencora <m.cencora@gmail.com>
*
* 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
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, 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 (including the next
* paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
*/
/* r300_vbo: Various helpers for emitting vertex buffers. Needs cleanup,
* refactoring, etc. */
#include "r300_vbo.h"
#include "pipe/p_format.h"
#include "r300_cs.h"
#include "r300_context.h"
#include "r300_state_inlines.h"
#include "r300_reg.h"
#include "r300_winsys.h"
static INLINE void setup_vertex_attribute(struct r300_vertex_info *vinfo,
struct pipe_vertex_element *vert_elem,
unsigned attr_num)
{
uint16_t hw_fmt1, hw_fmt2;
hw_fmt1 = r300_translate_vertex_data_type(vert_elem->src_format) |
(attr_num << R300_DST_VEC_LOC_SHIFT);
hw_fmt2 = r300_translate_vertex_data_swizzle(vert_elem->src_format);
if (attr_num % 2 == 0)
{
vinfo->vap_prog_stream_cntl[attr_num >> 1] = hw_fmt1;
vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] = hw_fmt2;
}
else
{
vinfo->vap_prog_stream_cntl[attr_num >> 1] |= hw_fmt1 << 16;
vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] |= hw_fmt2 << 16;
}
}
static void finish_vertex_attribs_setup(struct r300_vertex_info *vinfo,
unsigned attribs_num)
{
uint32_t last_vec_bit = (attribs_num % 2 == 0) ?
(R300_LAST_VEC << 16) : R300_LAST_VEC;
assert(attribs_num > 0 && attribs_num <= 16);
vinfo->vap_prog_stream_cntl[(attribs_num - 1) >> 1] |= last_vec_bit;
}
void setup_vertex_attributes(struct r300_context *r300)
{
struct pipe_vertex_element *vert_elem;
int i;
for (i = 0; i < r300->aos_count; i++) {
vert_elem = &r300->vertex_element[i];
setup_vertex_attribute(r300->vertex_info, vert_elem, i);
}
finish_vertex_attribs_setup(r300->vertex_info, r300->aos_count);
}
/* XXX WTF are these doing? */
static void setup_vertex_array(struct r300_context *r300, struct pipe_vertex_element *element)
{
}
static void finish_vertex_arrays_setup(struct r300_context *r300)
{
}
/* XXX move/integrate this with the checks in r300_state_inlines */
static boolean format_is_supported(enum pipe_format format, int nr_components)
{
if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS)
return FALSE;
if ((pf_size_x(format) != pf_size_y(format)) ||
(pf_size_x(format) != pf_size_z(format)) ||
(pf_size_x(format) != pf_size_w(format)))
return FALSE;
/* Following should be supported as long as stride is 4 bytes aligned */
if (pf_size_x(format) != 1 && nr_components != 4)
return FALSE;
if (pf_size_x(format) != 2 && !(nr_components == 2 || nr_components == 4))
return FALSE;
if (pf_size_x(format) == 3 || pf_size_x(format) > 4)
return FALSE;
return TRUE;
}
static INLINE int get_buffer_offset(struct r300_context *r300,
unsigned int buf_nr,
unsigned int elem_offset)
{
return r300->vertex_buffer[buf_nr].buffer_offset + elem_offset;
}
/**
*/
static void setup_vertex_buffers(struct r300_context *r300)
{
struct pipe_vertex_element *vert_elem;
int i;
for (i = 0; i < r300->aos_count; i++)
{
vert_elem = &r300->vertex_element[i];
if (!format_is_supported(vert_elem->src_format,
vert_elem->nr_components)) {
/* XXX use translate module to convert the data */
assert(0);
/*
struct pipe_buffer *buf;
const unsigned int max_index = r300->vertex_buffers[vert_elem->vertex_buffer_index].max_index;
buf = pipe_buffer_create(r300->context.screen, 4, usage, vert_elem->nr_components * max_index * sizeof(float));
*/
}
if (get_buffer_offset(r300,
vert_elem->vertex_buffer_index,
vert_elem->src_offset) % 4) {
/* XXX need to align buffer */
assert(0);
}
setup_vertex_array(r300, vert_elem);
}
finish_vertex_arrays_setup(r300);
}
void setup_index_buffer(struct r300_context *r300,
struct pipe_buffer* indexBuffer,
unsigned indexSize)
{
/* XXX I call BS; why is this different from the assert in r300_render? */
assert(indexSize = 2);
if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
RADEON_GEM_DOMAIN_GTT, 0)) {
assert(0);
}
if (!r300->winsys->validate(r300->winsys)) {
assert(0);
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright 2009 Maciej Cencora <m.cencora@gmail.com>
*
* 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
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, 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 (including the next
* paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
*/
#ifndef R300_VBO_H
#define R300_VBO_H
struct r300_context;
struct pipe_buffer;
void setup_vertex_attributes(struct r300_context *r300);
void setup_index_buffer(struct r300_context *r300,
struct pipe_buffer* indexBuffer,
unsigned indexSize);
#endif