Commit 72128962 authored by Jerome Glisse's avatar Jerome Glisse Committed by Jerome Glisse
Browse files

r600g: Initial import

parent 3d41dd79
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = r600
LIBRARY_INCLUDES = \
$(shell pkg-config libdrm --cflags-only-I)
C_SOURCES = \
r600_buffer.c \
r600_context.c \
r600_draw.c \
r600_blit.c \
r600_helper.c \
r600_query.c \
r600_screen.c \
r600_state.c \
r600_texture.c \
r600_shader.c \
r600_compiler.c \
r600_compiler_tgsi.c \
r600_compiler_dump.c \
r600_compiler_r600.c \
r600_compiler_r700.c
include ../../Makefile.template
Import('*')
env = env.Clone()
env.Append(CPPPATH = [
'#/include',
'#/src/mesa',
])
r600 = env.ConvenienceLibrary(
target = 'r600',
source = [
'r600_buffer.c',
'r600_context.c',
'r600_draw.c',
'r600_query.c',
'r600_screen.c',
'r600_state.c',
'r600_texture.c',
])
Export('r600')
/*
* Copyright 2009 Marek Olšák <maraeo@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.
*
* Authors:
* Jerome Glisse
* Marek Olšák
*/
#include <pipe/p_screen.h>
#include <util/u_blitter.h>
#include <util/u_inlines.h>
#include <util/u_memory.h>
#include "r600_screen.h"
#include "r600_texture.h"
#include "r600_context.h"
static void r600_blitter_save_states(struct pipe_context *ctx)
{
struct r600_context *rctx = (struct r600_context*)ctx;
util_blitter_save_blend(rctx->blitter,
rctx->draw->state[R600_BLEND]);
util_blitter_save_depth_stencil_alpha(rctx->blitter,
rctx->draw->state[R600_DSA]);
util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
util_blitter_save_rasterizer(rctx->blitter,
rctx->draw->state[R600_RASTERIZER]);
util_blitter_save_fragment_shader(rctx->blitter,
rctx->ps_shader);
util_blitter_save_vertex_shader(rctx->blitter,
rctx->vs_shader);
}
void r600_clear(struct pipe_context *ctx, unsigned buffers,
const float *rgba, double depth, unsigned stencil)
{
struct r600_context *rctx = (struct r600_context*)ctx;
struct pipe_framebuffer_state *fb = &rctx->fb_state;
#if 0
r600_blitter_save_states(ctx);
util_blitter_clear(rctx->blitter, fb->width, fb->height,
fb->nr_cbufs, buffers, rgba, depth,
stencil);
#endif
}
void r600_surface_copy(struct pipe_context *ctx,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
struct pipe_surface *src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
}
void r600_surface_fill(struct pipe_context *ctx,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height,
unsigned value)
{
}
/*
* Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
*
* 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.
*
* Authors:
* Jerome Glisse
* Corbin Simpson <MostAwesomeDude@gmail.com>
*/
#include <pipe/p_screen.h>
#include <util/u_format.h>
#include <util/u_math.h>
#include <util/u_inlines.h>
#include <util/u_memory.h>
#include "r600_screen.h"
#include "r600_texture.h"
#include "r600_context.h"
static u32 r600_domain_from_usage(unsigned usage)
{
u32 domain = RADEON_GEM_DOMAIN_GTT;
if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
domain |= RADEON_GEM_DOMAIN_VRAM;
}
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
domain |= RADEON_GEM_DOMAIN_VRAM;
}
if (usage & PIPE_BUFFER_USAGE_VERTEX) {
domain |= RADEON_GEM_DOMAIN_GTT;
}
if (usage & PIPE_BUFFER_USAGE_INDEX) {
domain |= RADEON_GEM_DOMAIN_GTT;
}
return domain;
}
static struct pipe_buffer *r600_buffer_create(struct pipe_screen *screen,
unsigned alignment,
unsigned usage,
unsigned size)
{
struct r600_screen *rscreen = r600_screen(screen);
struct r600_pipe_buffer *rbuffer;
struct radeon_bo *bo;
struct pb_desc desc;
rbuffer = CALLOC_STRUCT(r600_pipe_buffer);
if (rbuffer == NULL)
return NULL;
pipe_reference_init(&rbuffer->base.reference, 1);
rbuffer->base.screen = screen;
rbuffer->base.alignment = alignment;
rbuffer->base.usage = usage;
rbuffer->base.size = size;
if (usage & PIPE_BUFFER_USAGE_CONSTANT) {
desc.alignment = alignment;
desc.usage = usage;
rbuffer->pb = pb_malloc_buffer_create(size, &desc);
if (rbuffer->pb == NULL) {
free(rbuffer);
return NULL;
}
return &rbuffer->base;
}
rbuffer->domain = r600_domain_from_usage(usage);
bo = radeon_bo(rscreen->rw, 0, size, alignment, NULL);
if (bo == NULL) {
FREE(rbuffer);
return NULL;
}
rbuffer->bo = bo;
return &rbuffer->base;
}
static struct pipe_buffer *r600_user_buffer_create(struct pipe_screen *screen,
void *ptr, unsigned bytes)
{
struct r600_pipe_buffer *rbuffer;
struct r600_screen *rscreen = r600_screen(screen);
rbuffer = (struct r600_pipe_buffer*)r600_buffer_create(screen, 0, 0, bytes);
if (rbuffer == NULL) {
return NULL;
}
radeon_bo_map(rscreen->rw, rbuffer->bo);
memcpy(rbuffer->bo->data, ptr, bytes);
radeon_bo_unmap(rscreen->rw, rbuffer->bo);
return &rbuffer->base;
}
static void r600_buffer_destroy(struct pipe_buffer *buffer)
{
struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer;
struct r600_screen *rscreen = r600_screen(buffer->screen);
if (rbuffer->pb) {
pipe_reference_init(&rbuffer->pb->base.reference, 0);
pb_destroy(rbuffer->pb);
rbuffer->pb = NULL;
}
if (rbuffer->bo) {
radeon_bo_decref(rscreen->rw, rbuffer->bo);
}
FREE(rbuffer);
}
static void *r600_buffer_map_range(struct pipe_screen *screen,
struct pipe_buffer *buffer,
unsigned offset, unsigned length,
unsigned usage)
{
struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer;
struct r600_screen *rscreen = r600_screen(buffer->screen);
int write = 0;
if (rbuffer->pb) {
return pb_map(rbuffer->pb, usage);
}
if (usage & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* FIXME */
}
if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
write = 1;
}
if (radeon_bo_map(rscreen->rw, rbuffer->bo)) {
return NULL;
}
return rbuffer->bo->data;
}
static void r600_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *buffer)
{
struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer;
struct r600_screen *rscreen = r600_screen(buffer->screen);
if (rbuffer->pb) {
pb_unmap(rbuffer->pb);
} else {
radeon_bo_unmap(rscreen->rw, rbuffer->bo);
}
}
static void r600_buffer_flush_mapped_range(struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned offset, unsigned length)
{
}
void r600_screen_init_buffer_functions(struct pipe_screen *screen)
{
screen->buffer_create = r600_buffer_create;
screen->user_buffer_create = r600_user_buffer_create;
screen->buffer_map_range = r600_buffer_map_range;
screen->buffer_flush_mapped_range = r600_buffer_flush_mapped_range;
screen->buffer_unmap = r600_buffer_unmap;
screen->buffer_destroy = r600_buffer_destroy;
}
/*
* Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
*
* 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.
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include "r600_compiler.h"
struct c_vector *c_vector_new(void)
{
struct c_vector *v = calloc(1, sizeof(struct c_vector));
if (v == NULL) {
return NULL;
}
c_list_init(v);
return v;
}
static unsigned c_opcode_is_alu(unsigned opcode)
{
switch (opcode) {
case C_OPCODE_MOV:
case C_OPCODE_MUL:
case C_OPCODE_MAD:
case C_OPCODE_ARL:
case C_OPCODE_LIT:
case C_OPCODE_RCP:
case C_OPCODE_RSQ:
case C_OPCODE_EXP:
case C_OPCODE_LOG:
case C_OPCODE_ADD:
case C_OPCODE_DP3:
case C_OPCODE_DP4:
case C_OPCODE_DST:
case C_OPCODE_MIN:
case C_OPCODE_MAX:
case C_OPCODE_SLT:
case C_OPCODE_SGE:
case C_OPCODE_SUB:
case C_OPCODE_LRP:
case C_OPCODE_CND:
case C_OPCODE_DP2A:
case C_OPCODE_FRC:
case C_OPCODE_CLAMP:
case C_OPCODE_FLR:
case C_OPCODE_ROUND:
case C_OPCODE_EX2:
case C_OPCODE_LG2:
case C_OPCODE_POW:
case C_OPCODE_XPD:
case C_OPCODE_ABS:
case C_OPCODE_RCC:
case C_OPCODE_DPH:
case C_OPCODE_COS:
case C_OPCODE_DDX:
case C_OPCODE_DDY:
case C_OPCODE_PK2H:
case C_OPCODE_PK2US:
case C_OPCODE_PK4B:
case C_OPCODE_PK4UB:
case C_OPCODE_RFL:
case C_OPCODE_SEQ:
case C_OPCODE_SFL:
case C_OPCODE_SGT:
case C_OPCODE_SIN:
case C_OPCODE_SLE:
case C_OPCODE_SNE:
case C_OPCODE_STR:
case C_OPCODE_UP2H:
case C_OPCODE_UP2US:
case C_OPCODE_UP4B:
case C_OPCODE_UP4UB:
case C_OPCODE_X2D:
case C_OPCODE_ARA:
case C_OPCODE_ARR:
case C_OPCODE_BRA:
case C_OPCODE_SSG:
case C_OPCODE_CMP:
case C_OPCODE_SCS:
case C_OPCODE_NRM:
case C_OPCODE_DIV:
case C_OPCODE_DP2:
case C_OPCODE_CEIL:
case C_OPCODE_I2F:
case C_OPCODE_NOT:
case C_OPCODE_TRUNC:
case C_OPCODE_SHL:
case C_OPCODE_AND:
case C_OPCODE_OR:
case C_OPCODE_MOD:
case C_OPCODE_XOR:
case C_OPCODE_SAD:
case C_OPCODE_NRM4:
case C_OPCODE_F2I:
case C_OPCODE_IDIV:
case C_OPCODE_IMAX:
case C_OPCODE_IMIN:
case C_OPCODE_INEG:
case C_OPCODE_ISGE:
case C_OPCODE_ISHR:
case C_OPCODE_ISLT:
case C_OPCODE_F2U:
case C_OPCODE_U2F:
case C_OPCODE_UADD:
case C_OPCODE_UDIV:
case C_OPCODE_UMAD:
case C_OPCODE_UMAX:
case C_OPCODE_UMIN:
case C_OPCODE_UMOD:
case C_OPCODE_UMUL:
case C_OPCODE_USEQ:
case C_OPCODE_USGE:
case C_OPCODE_USHR:
case C_OPCODE_USLT:
case C_OPCODE_USNE:
return 1;
case C_OPCODE_END:
case C_OPCODE_VFETCH:
case C_OPCODE_KILP:
case C_OPCODE_CAL:
case C_OPCODE_RET:
case C_OPCODE_TXB:
case C_OPCODE_TXL:
case C_OPCODE_BRK:
case C_OPCODE_IF:
case C_OPCODE_BGNFOR:
case C_OPCODE_REP:
case C_OPCODE_ELSE:
case C_OPCODE_ENDIF:
case C_OPCODE_ENDFOR:
case C_OPCODE_ENDREP:
case C_OPCODE_PUSHA:
case C_OPCODE_POPA:
case C_OPCODE_TXF:
case C_OPCODE_TXQ:
case C_OPCODE_CONT:
case C_OPCODE_EMIT:
case C_OPCODE_ENDPRIM:
case C_OPCODE_BGNLOOP:
case C_OPCODE_BGNSUB:
case C_OPCODE_ENDLOOP:
case C_OPCODE_ENDSUB:
case C_OPCODE_NOP:
case C_OPCODE_CALLNZ:
case C_OPCODE_IFC:
case C_OPCODE_BREAKC:
case C_OPCODE_KIL:
case C_OPCODE_TEX:
case C_OPCODE_TXD:
case C_OPCODE_TXP:
case C_OPCODE_SWITCH:
case C_OPCODE_CASE:
case C_OPCODE_DEFAULT:
case C_OPCODE_ENDSWITCH:
default:
return 0;
}
}
/* NEW */
void c_node_init(struct c_node *node)
{
memset(node, 0, sizeof(struct c_node));
c_list_init(&node->predecessors);
c_list_init(&node->successors);
c_list_init(&node->childs);
c_list_init(&node->insts);
node->parent = NULL;
}
static struct c_node_link *c_node_link_new(struct c_node *node)
{
struct c_node_link *link;
link = calloc(1, sizeof(struct c_node_link));
if (link == NULL)
return NULL;
c_list_init(link);
link->node = node;
return link;
}
int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor)
{
struct c_node_link *pedge, *sedge;
pedge = c_node_link_new(successor);
sedge = c_node_link_new(predecessor);
if (sedge == NULL || pedge == NULL) {
free(sedge);
free(pedge);
return -ENOMEM;
}
c_list_add_tail(pedge, &predecessor->successors);
c_list_add_tail(sedge, &successor->predecessors);
return 0;
}
int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction)
{
struct c_instruction *inst = calloc(1, sizeof(struct c_instruction));
if (inst == NULL)
return -ENOMEM;
memcpy(inst, instruction, sizeof(struct c_instruction));
c_list_add(inst, &node->insts);
return 0;
}
int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction)
{
struct c_instruction *inst = calloc(1, sizeof(struct c_instruction));
if (inst == NULL)
return -ENOMEM;
memcpy(inst, instruction, sizeof(struct c_instruction));
c_list_add_tail(inst, &node->insts);
return 0;
}
struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor)
{
struct c_node *node = calloc(1, sizeof(struct c_node));
if (node == NULL)
return NULL;
c_node_init(node);
if (c_node_cfg_link(predecessor, node)) {
free(node);
return NULL;
}
c_list_add_tail(node, &shader->nodes);
return node;
}
int c_shader_init(struct c_shader *shader, unsigned type)
{
unsigned i;
int r;
shader->type = type;
for (i = 0; i < C_FILE_COUNT; i++) {
shader->files[i].nvectors = 0;
c_list_init(&shader->files[i].vectors);
}
c_list_init(&shader->nodes);
c_node_init(&shader->entry);
c_node_init(&shader->end);
shader->entry.opcode = C_OPCODE_ENTRY;
shader->end.opcode = C_OPCODE_END;
r = c_node_cfg_link(&shader->entry, &shader->end);
if (r)
return r;
return 0;
}
struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid)
{
struct c_vector *v = calloc(1, sizeof(struct c_vector));
int i;
if (v == NULL) {
return NULL;
}
for (i = 0; i < 4; i++) {
v->channel[i] = calloc(1, sizeof(struct c_channel));
if (v->channel[i] == NULL)
goto out_err;
v->channel[i]->vindex = i;
v->channel[i]->vector = v;
}
v->file = file;
v->name = name;
v->sid = sid;
shader->files[v->file].nvectors++;
v->id = shader->nvectors++;
c_list_add_tail(v, &shader->files[v->file].vectors);
return v;
out_err:
for (i = 0; i < 4; i++) {
free(v->channel[i]);
}