parent
852d0aff79
commit
03e3116a75
@ -0,0 +1,26 @@ |
||||
#ifndef U_DUAL_BLEND_H |
||||
#define U_DUAL_BLEND_H |
||||
|
||||
#include "pipe/p_state.h" |
||||
|
||||
static INLINE boolean util_blend_factor_is_dual_src(int factor) |
||||
{ |
||||
return (factor == PIPE_BLENDFACTOR_SRC1_COLOR) || |
||||
(factor == PIPE_BLENDFACTOR_SRC1_ALPHA) || |
||||
(factor == PIPE_BLENDFACTOR_INV_SRC1_COLOR) || |
||||
(factor == PIPE_BLENDFACTOR_INV_SRC1_ALPHA); |
||||
} |
||||
|
||||
static INLINE boolean util_blend_state_is_dual(const struct pipe_blend_state *blend,
|
||||
int index) |
||||
{ |
||||
if (util_blend_factor_is_dual_src(blend->rt[index].rgb_src_factor) || |
||||
util_blend_factor_is_dual_src(blend->rt[index].alpha_src_factor) || |
||||
util_blend_factor_is_dual_src(blend->rt[index].rgb_dst_factor) || |
||||
util_blend_factor_is_dual_src(blend->rt[index].alpha_dst_factor)) |
||||
return true; |
||||
return false; |
||||
} |
||||
|
||||
|
||||
#endif |
@ -0,0 +1,57 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* 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 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 VMWARE AND/OR ITS 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 U_TEXTURE_H |
||||
#define U_TEXTURE_H |
||||
|
||||
#include "pipe/p_compiler.h" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* Convert 2D texture coordinates of 4 vertices into cubemap coordinates |
||||
* in the given face. |
||||
* Coordinates must be in the range [0,1]. |
||||
* |
||||
* \param face Cubemap face. |
||||
* \param in_st 4 pairs of 2D texture coordinates to convert. |
||||
* \param in_stride Stride of in_st in floats. |
||||
* \param out_str STR cubemap texture coordinates to compute. |
||||
* \param out_stride Stride of out_str in floats. |
||||
*/ |
||||
void util_map_texcoords2d_onto_cubemap(unsigned face, |
||||
const float *in_st, unsigned in_stride, |
||||
float *out_str, unsigned out_stride, |
||||
boolean allow_scale); |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif |
@ -1,162 +0,0 @@ |
||||
#include <epoxy/gl.h> |
||||
#include <stdio.h> |
||||
#include "graw_renderer.h" |
||||
#include "vrend_object.h" |
||||
#include "graw_cursor.h" |
||||
|
||||
static const GLchar *cursor_vs_shader =
|
||||
"attribute vec2 position;\n" |
||||
"attribute vec2 textureCoords;\n" |
||||
"varying vec2 texCoords;\n" |
||||
"void main()\n" |
||||
"{\n" |
||||
" texCoords = textureCoords;\n" |
||||
" gl_Position = vec4(position, 0.0, 1.0);\n" |
||||
"}\n"; |
||||
|
||||
static const GLchar *cursor_fs_shader = |
||||
"uniform sampler2D texSampler;\n" |
||||
"varying vec2 texCoords;\n" |
||||
"void main()\n" |
||||
"{\n" |
||||
" gl_FragColor = texture2D(texSampler, texCoords);\n" |
||||
"}\n"; |
||||
|
||||
void graw_cursor_init(struct graw_cursor_info *cursor) |
||||
{ |
||||
GLuint curs_vs_id, curs_fs_id; |
||||
|
||||
cursor->prog_id = glCreateProgram(); |
||||
curs_vs_id = glCreateShader(GL_VERTEX_SHADER); |
||||
glShaderSource(curs_vs_id, 1, &cursor_vs_shader, NULL); |
||||
glCompileShader(curs_vs_id); |
||||
|
||||
curs_fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||
glShaderSource(curs_fs_id, 1, &cursor_fs_shader, NULL); |
||||
glCompileShader(curs_fs_id); |
||||
|
||||
glAttachShader(cursor->prog_id, curs_vs_id); |
||||
glAttachShader(cursor->prog_id, curs_fs_id); |
||||
glLinkProgram(cursor->prog_id); |
||||
|
||||
glGenBuffersARB(1, &cursor->vbo_id); |
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cursor->vbo_id); |
||||
glBufferData(GL_ARRAY_BUFFER_ARB, 4 * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW); |
||||
|
||||
cursor->attrib_locs[0] = glGetAttribLocation(cursor->prog_id, "position"); |
||||
cursor->attrib_locs[1] = glGetAttribLocation(cursor->prog_id, "textureCoords"); |
||||
cursor->samp_loc = glGetUniformLocation(cursor->prog_id, "texSampler"); |
||||
|
||||
glGenVertexArrays(1, &cursor->vaoid); |
||||
|
||||
grend_bind_va(cursor->vaoid); |
||||
|
||||
glVertexAttribPointer(cursor->attrib_locs[0], 2, GL_FLOAT, GL_FALSE, 16, 0); |
||||
glVertexAttribDivisorARB(cursor->attrib_locs[0], 0); |
||||
glVertexAttribPointer(cursor->attrib_locs[1], 2, GL_FLOAT, GL_FALSE, 16, (GLvoid *)8); |
||||
glVertexAttribDivisorARB(cursor->attrib_locs[1], 0); |
||||
|
||||
glEnableVertexAttribArray(cursor->attrib_locs[0]); |
||||
glEnableVertexAttribArray(cursor->attrib_locs[1]); |
||||
|
||||
} |
||||
|
||||
int graw_renderer_remove_cursor(struct graw_cursor_info *cursor, |
||||
struct grend_resource *dst_res) |
||||
{ |
||||
struct pipe_box box; |
||||
box.x = cursor->last_x; |
||||
box.y = cursor->last_y; |
||||
box.z = 0; |
||||
box.width = 64; |
||||
box.height = 64; |
||||
box.depth = 1; |
||||
|
||||
graw_renderer_flush_buffer_res(dst_res, &box); |
||||
return 0; |
||||
} |
||||
|
||||
int graw_renderer_paint_cursor(struct graw_cursor_info *cursor, |
||||
struct grend_resource *dst_res) |
||||
{ |
||||
GLuint fb_id; |
||||
struct grend_resource *cursor_res; |
||||
struct vertex { |
||||
GLfloat x, y, s, t; |
||||
}; |
||||
struct vertex verts[4]; |
||||
GLuint locs[2]; |
||||
GLfloat x0, y0, x1, y1; |
||||
int s_w, s_h; |
||||
if (!cursor->res_handle) |
||||
return 0; |
||||
|
||||
cursor_res = vrend_resource_lookup(cursor->res_handle, 0); |
||||
if (!cursor_res) |
||||
return 0; |
||||
|
||||
s_w = dst_res->base.width0; |
||||
s_h = dst_res->base.height0; |
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); |
||||
glDrawBuffer(GL_BACK); |
||||
|
||||
grend_use_program(cursor->prog_id); |
||||
|
||||
glUniform1i(cursor->samp_loc, 0); |
||||
|
||||
grend_blend_enable(GL_TRUE); |
||||
grend_depth_test_enable(GL_FALSE); |
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
||||
glBlendEquation(GL_FUNC_ADD); |
||||
|
||||
glActiveTexture(GL_TEXTURE0); |
||||
glBindTexture(cursor_res->target, cursor_res->id); |
||||
|
||||
glTexParameteri(cursor_res->target, GL_TEXTURE_BASE_LEVEL, 0); |
||||
glTexParameteri(cursor_res->target, GL_TEXTURE_MAX_LEVEL, 0); |
||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MIN_LOD, 0); |
||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MAX_LOD, 0); |
||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
||||
|
||||
grend_bind_va(cursor->vaoid); |
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cursor->vbo_id); |
||||
|
||||
cursor->last_x = cursor->x; |
||||
cursor->last_y = cursor->y; |
||||
|
||||
x0 = ((float)cursor->x / (s_w / 2)) - 1.0; |
||||
y0 = ((float)(s_h - cursor->y - cursor_res->base.width0) / (s_h / 2)) - 1.0; |
||||
x1 = (((float)cursor->x + cursor_res->base.height0) / (s_w / 2)) - 1.0; |
||||
y1 = (((float)(s_h - cursor->y)) / (s_h / 2)) - 1.0; |
||||
|
||||
verts[0].x = x0; |
||||
verts[0].y = y0; |
||||
|
||||
verts[1].x = x1; |
||||
verts[1].y = y0; |
||||
|
||||
verts[2].x = x1; |
||||
verts[2].y = y1; |
||||
|
||||
verts[3].x = x0; |
||||
verts[3].y = y1; |
||||
|
||||
verts[0].s = 0.0; |
||||
verts[0].t = 1.0; |
||||
verts[1].s = 1.0; |
||||
verts[1].t = 1.0; |
||||
verts[2].s = 1.0; |
||||
verts[2].t = 0.0; |
||||
verts[3].s = 0.0; |
||||
verts[3].t = 0.0; |
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); |
||||
|
||||
glDrawArrays(GL_QUADS, 0, 4); |
||||
return 0; |
||||
} |
@ -1,24 +0,0 @@ |
||||
#ifndef GRAW_CURSOR_H |
||||
#define GRAW_CURSOR_H |
||||
|
||||
/* cursor drawing state */ |
||||
|
||||
struct graw_cursor_info { |
||||
GLuint prog_id; |
||||
GLuint vaoid; |
||||
GLuint vbo_id; |
||||
uint32_t res_handle; |
||||
int x, y; |
||||
GLuint attrib_locs[2]; |
||||
GLuint samp_loc; |
||||
|
||||
int last_x, last_y; |
||||
}; |
||||
|
||||
void graw_cursor_init(struct graw_cursor_info *cursor); |
||||
|
||||
int graw_renderer_paint_cursor(struct graw_cursor_info *cursor, |
||||
struct grend_resource *dst_res); |
||||
int graw_renderer_remove_cursor(struct graw_cursor_info *cursor, |
||||
struct grend_resource *dst_res); |
||||
#endif |
@ -1,911 +0,0 @@ |
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
#include <stdio.h> |
||||
#include <epoxy/gl.h> |
||||
|
||||
#include "util/u_memory.h" |
||||
#include "pipe/p_state.h" |
||||
#include "pipe/p_shader_tokens.h" |
||||
#include "graw_decode.h" |
||||
#include "graw_renderer.h" |
||||
#include "vrend_object.h" |
||||
#include "tgsi/tgsi_text.h" |
||||
|
||||
/* decode side */ |
||||
#define DECODE_MAX_TOKENS 8000 |
||||
|
||||
struct grend_decode_ctx { |
||||
struct graw_decoder_state ids, *ds; |
||||
struct grend_context *grctx; |
||||
}; |
||||
|
||||
#define GRAW_MAX_CTX 16 |
||||
static struct grend_decode_ctx *dec_ctx[GRAW_MAX_CTX]; |
||||
|
||||
static int graw_decode_create_shader(struct grend_decode_ctx *ctx, uint32_t type, |
||||
uint32_t handle, |
||||
uint16_t length) |
||||
{ |
||||
struct pipe_shader_state *state = CALLOC_STRUCT(pipe_shader_state); |
||||
struct tgsi_token *tokens; |
||||
int i; |
||||
uint32_t shader_offset; |
||||
unsigned num_tokens; |
||||
if (!state) |
||||
return NULL; |
||||
|
||||
num_tokens = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
|
||||
if (num_tokens == 0) |
||||
num_tokens = 300; |
||||
|
||||
tokens = calloc(num_tokens + 10, sizeof(struct tgsi_token)); |
||||
if (!tokens) { |
||||
free(state); |
||||
return -1; |
||||
} |
||||
|
||||
state->stream_output.num_outputs = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
if (state->stream_output.num_outputs) { |
||||
for (i = 0; i < 4; i++) |
||||
state->stream_output.stride[i] = ctx->ds->buf[ctx->ds->buf_offset + 4 + i]; |
||||
for (i = 0; i < state->stream_output.num_outputs; i++) { |
||||
uint32_t tmp = ctx->ds->buf[ctx->ds->buf_offset + 8 + i]; |
||||
|
||||
state->stream_output.output[i].register_index = tmp & 0xff; |
||||
state->stream_output.output[i].start_component = (tmp >> 8) & 0x3; |
||||
state->stream_output.output[i].num_components = (tmp >> 10) & 0x7; |
||||
state->stream_output.output[i].output_buffer = (tmp >> 13) & 0x7; |
||||
state->stream_output.output[i].dst_offset = (tmp >> 16) & 0xffff;
|
||||
} |
||||
shader_offset = 8 + state->stream_output.num_outputs; |
||||
} else |
||||
shader_offset = 4; |
||||
if (vrend_dump_shaders) |
||||
fprintf(stderr,"shader\n%s\n", &ctx->ds->buf[ctx->ds->buf_offset + shader_offset]); |
||||
if (!tgsi_text_translate(&ctx->ds->buf[ctx->ds->buf_offset + shader_offset], tokens, num_tokens + 10)) { |
||||
fprintf(stderr,"failed to translate\n %s\n",&ctx->ds->buf[ctx->ds->buf_offset + shader_offset]); |
||||
free(tokens); |
||||
free(state); |
||||
return -1; |
||||
} |
||||
|
||||
state->tokens = tokens; |
||||
|
||||
if (type == VIRGL_OBJECT_FS) |
||||
grend_create_fs(ctx->grctx, handle, state); |
||||
else |
||||
grend_create_vs(ctx->grctx, handle, state); |
||||
|
||||
free(tokens); |
||||
free(state); |
||||
return 0; |
||||
} |
||||
|
||||
static int graw_decode_create_stream_output_target(struct grend_decode_ctx *ctx, uint32_t handle) |
||||
{ |
||||
uint32_t res_handle, buffer_size, buffer_offset; |
||||
|
||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
buffer_offset = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
buffer_size = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
|
||||
grend_create_so_target(ctx->grctx, handle, res_handle, buffer_offset, |
||||
buffer_size); |
||||
} |
||||
|
||||
static void graw_decode_set_framebuffer_state(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t nr_cbufs = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
uint32_t zsurf_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
uint32_t surf_handle[8]; |
||||
int i; |
||||
|
||||
for (i = 0; i < nr_cbufs; i++) |
||||
surf_handle[i] = ctx->ds->buf[ctx->ds->buf_offset + 3 + i]; |
||||
grend_set_framebuffer_state(ctx->grctx, nr_cbufs, surf_handle, zsurf_handle); |
||||
} |
||||
|
||||
static void graw_decode_clear(struct grend_decode_ctx *ctx) |
||||
{ |
||||
union pipe_color_union color; |
||||
double depth; |
||||
unsigned stencil, buffers; |
||||
int i; |
||||
int index = ctx->ds->buf_offset + 1; |
||||
|
||||
buffers = ctx->ds->buf[index++]; |
||||
for (i = 0; i < 4; i++) |
||||
color.ui[i] = ctx->ds->buf[index++]; |
||||
depth = *(double *)(uint64_t *)(&ctx->ds->buf[index]); |
||||
index += 2; |
||||
stencil = ctx->ds->buf[index++]; |
||||
|
||||
grend_clear(ctx->grctx, buffers, &color, depth, stencil); |
||||
} |
||||
|
||||
static float uif(unsigned int ui) |
||||
{ |
||||
union { float f; unsigned int ui; } myuif; |
||||
myuif.ui = ui; |
||||
return myuif.f; |
||||
} |
||||
|
||||
static void graw_decode_set_viewport_state(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_viewport_state vps; |
||||
int i; |
||||
|
||||
for (i = 0; i < 4; i++) |
||||
vps.scale[i] = uif(ctx->ds->buf[ctx->ds->buf_offset + 1 + i]); |
||||
for (i = 0; i < 4; i++) |
||||
vps.translate[i] = uif(ctx->ds->buf[ctx->ds->buf_offset + 5 + i]); |
||||
|
||||
grend_set_viewport_state(ctx->grctx, &vps); |
||||
} |
||||
|
||||
static void graw_decode_set_index_buffer(struct grend_decode_ctx *ctx) |
||||
{ |
||||
int offset = ctx->ds->buf_offset; |
||||
grend_set_index_buffer(ctx->grctx, ctx->ds->buf[offset + 1], |
||||
ctx->ds->buf[offset + 2], |
||||
ctx->ds->buf[offset + 3]); |
||||
} |
||||
|
||||
static void graw_decode_set_constant_buffer(struct grend_decode_ctx *ctx, uint16_t length) |
||||
{ |
||||
int offset = ctx->ds->buf_offset; |
||||
uint32_t shader = ctx->ds->buf[offset + 1]; |
||||
uint32_t index = ctx->ds->buf[offset + 2]; |
||||
int nc = (length - 2); |
||||
grend_set_constants(ctx->grctx, shader, index, nc, &ctx->ds->buf[offset + 3]); |
||||
} |
||||
|
||||
static void graw_decode_set_vertex_buffers(struct grend_decode_ctx *ctx, uint16_t length) |
||||
{ |
||||
int num_vbo; |
||||
int i; |
||||
num_vbo = (length / 3); |
||||
|
||||
for (i = 0; i < num_vbo; i++) { |
||||
int element_offset = ctx->ds->buf_offset + 1 + (i * 3); |
||||
grend_set_single_vbo(ctx->grctx, i, |
||||
ctx->ds->buf[element_offset], |
||||
ctx->ds->buf[element_offset + 1], |
||||
ctx->ds->buf[element_offset + 2]); |
||||
} |
||||
grend_set_num_vbo(ctx->grctx, num_vbo); |
||||
} |
||||
|
||||
static void graw_decode_set_sampler_views(struct grend_decode_ctx *ctx, uint16_t length) |
||||
{ |
||||
int num_samps; |
||||
int i; |
||||
uint32_t shader_type, start_slot; |
||||
num_samps = length - 2; |
||||
shader_type = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
start_slot = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
for (i = 0; i < num_samps; i++) { |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 3 + i]; |
||||
grend_set_single_sampler_view(ctx->grctx, shader_type, i + start_slot, handle); |
||||
} |
||||
grend_set_num_sampler_views(ctx->grctx, shader_type, start_slot, num_samps); |
||||
} |
||||
|
||||
static void graw_decode_resource_inline_write(struct grend_decode_ctx *ctx, uint16_t length) |
||||
{ |
||||
struct pipe_box box; |
||||
uint32_t res_handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
uint32_t level, usage, stride, layer_stride; |
||||
void *data; |
||||
|
||||
level = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
usage = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
stride = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
layer_stride = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
box.x = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
||||
box.y = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
||||
box.z = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
||||
box.width = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
||||
box.height = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
||||
box.depth = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
||||
|
||||
data = &ctx->ds->buf[ctx->ds->buf_offset + 12]; |
||||
grend_transfer_inline_write(ctx->grctx, res_handle, level, |
||||
usage, &box, data, stride, layer_stride); |
||||
|
||||
} |
||||
|
||||
static void graw_decode_draw_vbo(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_draw_info info; |
||||
|
||||
memset(&info, 0, sizeof(struct pipe_draw_info)); |
||||
|
||||
info.start = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
info.count = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
info.mode = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
info.indexed = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
info.instance_count = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
info.index_bias = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
||||
info.start_instance = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
||||
info.primitive_restart = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
||||
info.restart_index = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
||||
info.min_index = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
||||
info.max_index = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
||||
grend_draw_vbo(ctx->grctx, &info); |
||||
} |
||||
|
||||
static void graw_decode_create_blend(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
||||
{ |
||||
struct pipe_blend_state *blend_state = CALLOC_STRUCT(pipe_blend_state); |
||||
uint32_t tmp; |
||||
int i; |
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
blend_state->independent_blend_enable = (tmp & 1); |
||||
blend_state->logicop_enable = (tmp >> 1) & 0x1; |
||||
blend_state->dither = (tmp >> 2) & 0x1; |
||||
blend_state->alpha_to_coverage = (tmp >> 3) & 0x1; |
||||
blend_state->alpha_to_one = (tmp >> 4) & 0x1; |
||||
|
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
blend_state->logicop_func = tmp & 0xf; |
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 4 + i]; |
||||
blend_state->rt[i].blend_enable = tmp & 0x1; |
||||
blend_state->rt[i].rgb_func = (tmp >> 1) & 0x7; |
||||
blend_state->rt[i].rgb_src_factor = (tmp >> 4) & 0x1f; |
||||
blend_state->rt[i].rgb_dst_factor = (tmp >> 9) & 0x1f; |
||||
blend_state->rt[i].alpha_func = (tmp >> 14) & 0x7; |
||||
blend_state->rt[i].alpha_src_factor = (tmp >> 17) & 0x1f; |
||||
blend_state->rt[i].alpha_dst_factor = (tmp >> 22) & 0x1f; |
||||
blend_state->rt[i].colormask = (tmp >> 27) & 0xf; |
||||
} |
||||
|
||||
graw_renderer_object_insert(ctx->grctx, blend_state, sizeof(struct pipe_blend_state), handle, |
||||
VIRGL_OBJECT_BLEND); |
||||
} |
||||
|
||||
static void graw_decode_create_dsa(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
||||
{ |
||||
int i; |
||||
struct pipe_depth_stencil_alpha_state *dsa_state = CALLOC_STRUCT(pipe_depth_stencil_alpha_state); |
||||
uint32_t tmp; |
||||
|
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
dsa_state->depth.enabled = tmp & 0x1; |
||||
dsa_state->depth.writemask = (tmp >> 1) & 0x1; |
||||
dsa_state->depth.func = (tmp >> 2) & 0x7; |
||||
|
||||
dsa_state->alpha.enabled = (tmp >> 8) & 0x1; |
||||
dsa_state->alpha.func = (tmp >> 9) & 0x7; |
||||
|
||||
for (i = 0; i < 2; i++) { |
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 3 + i]; |
||||
dsa_state->stencil[i].enabled = tmp & 0x1; |
||||
dsa_state->stencil[i].func = (tmp >> 1) & 0x7; |
||||
dsa_state->stencil[i].fail_op = (tmp >> 4) & 0x7; |
||||
dsa_state->stencil[i].zpass_op = (tmp >> 7) & 0x7; |
||||
dsa_state->stencil[i].zfail_op = (tmp >> 10) & 0x7; |
||||
dsa_state->stencil[i].valuemask = (tmp >> 13) & 0xff; |
||||
dsa_state->stencil[i].writemask = (tmp >> 21) & 0xff; |
||||
} |
||||
|
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
dsa_state->alpha.ref_value = uif(tmp); |
||||
|
||||
graw_renderer_object_insert(ctx->grctx, dsa_state, sizeof(struct pipe_depth_stencil_alpha_state), handle, |
||||
VIRGL_OBJECT_DSA); |
||||
} |
||||
|
||||
static void graw_decode_create_rasterizer(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
||||
{ |
||||
struct pipe_rasterizer_state *rs_state = CALLOC_STRUCT(pipe_rasterizer_state); |
||||
uint32_t tmp; |
||||
|
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
#define ebit(name, bit) rs_state->name = (tmp >> bit) & 0x1 |
||||
#define emask(name, bit, mask) rs_state->name = (tmp >> bit) & mask |
||||
|
||||
ebit(flatshade, 0); |
||||
ebit(depth_clip, 1); |
||||
ebit(clip_halfz, 2); |
||||
ebit(rasterizer_discard, 3); |
||||
ebit(flatshade_first, 4); |
||||
ebit(light_twoside, 5); |
||||
ebit(sprite_coord_mode, 6); |
||||
ebit(point_quad_rasterization, 7); |
||||
emask(cull_face, 8, 0x3); |
||||
emask(fill_front, 10, 0x3); |
||||
emask(fill_back, 12, 0x3); |
||||
ebit(scissor, 14); |
||||
ebit(front_ccw, 15); |
||||
ebit(clamp_vertex_color, 16); |
||||
ebit(clamp_fragment_color, 17); |
||||
ebit(offset_line, 18); |
||||
ebit(offset_point, 19); |
||||
ebit(offset_tri, 20); |
||||
ebit(poly_smooth, 21); |
||||
ebit(poly_stipple_enable, 22); |
||||
ebit(point_smooth, 23); |
||||
ebit(point_size_per_vertex, 24); |
||||
ebit(multisample, 25); |
||||
ebit(line_smooth, 26); |
||||
ebit(line_stipple_enable, 27); |
||||
ebit(line_last_pixel, 28); |
||||
ebit(half_pixel_center, 29); |
||||
ebit(bottom_edge_rule, 30); |
||||
rs_state->point_size = uif(ctx->ds->buf[ctx->ds->buf_offset + 3]); |
||||
rs_state->sprite_coord_enable = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
emask(line_stipple_pattern, 0, 0xffff); |
||||
emask(line_stipple_factor, 16, 0xff); |
||||
emask(clip_plane_enable, 24, 0xff); |
||||
|
||||
rs_state->line_width = uif(ctx->ds->buf[ctx->ds->buf_offset + 6]); |
||||
rs_state->offset_units = uif(ctx->ds->buf[ctx->ds->buf_offset + 7]); |
||||
rs_state->offset_scale = uif(ctx->ds->buf[ctx->ds->buf_offset + 8]); |
||||
rs_state->offset_clamp = uif(ctx->ds->buf[ctx->ds->buf_offset + 9]); |
||||
|
||||
|
||||
graw_renderer_object_insert(ctx->grctx, rs_state, sizeof(struct pipe_rasterizer_state), handle, |
||||
VIRGL_OBJECT_RASTERIZER); |
||||
} |
||||
|
||||
static void graw_decode_create_surface(struct grend_decode_ctx *ctx, uint32_t handle) |
||||
{ |
||||
uint32_t res_handle, format, val0, val1; |
||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
format = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
val0 = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
val1 = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
grend_create_surface(ctx->grctx, handle, res_handle, format, val0, val1); |
||||
} |
||||
|
||||
static void graw_decode_create_sampler_view(struct grend_decode_ctx *ctx, uint32_t handle) |
||||
{ |
||||
uint32_t res_handle, format, val0, val1, swizzle_packed; |
||||
|
||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
format = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
val0 = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
val1 = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
swizzle_packed = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
||||
grend_create_sampler_view(ctx->grctx, handle, res_handle, format, val0, val1,swizzle_packed); |
||||
} |
||||
|
||||
static void graw_decode_create_sampler_state(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
||||
{ |
||||
struct pipe_sampler_state *state = CALLOC_STRUCT(pipe_sampler_state); |
||||
int i; |
||||
uint32_t tmp; |
||||
|
||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
state->wrap_s = tmp & 0x7; |
||||
state->wrap_t = (tmp >> 3) & 0x7; |
||||
state->wrap_r = (tmp >> 6) & 0x7; |
||||
state->min_img_filter = (tmp >> 9) & 0x3; |
||||
state->min_mip_filter = (tmp >> 11) & 0x3; |
||||
state->mag_img_filter = (tmp >> 13) & 0x3; |
||||
state->compare_mode = (tmp >> 15) & 0x1; |
||||
state->compare_func = (tmp >> 16) & 0x7; |
||||
|
||||
state->lod_bias = uif(ctx->ds->buf[ctx->ds->buf_offset + 3]); |
||||
state->min_lod = uif(ctx->ds->buf[ctx->ds->buf_offset + 4]); |
||||
state->max_lod = uif(ctx->ds->buf[ctx->ds->buf_offset + 5]); |
||||
|
||||
for (i = 0; i < 4; i++) |
||||
state->border_color.ui[i] = ctx->ds->buf[ctx->ds->buf_offset + 6 + i]; |
||||
graw_renderer_object_insert(ctx->grctx, state, sizeof(struct pipe_sampler_state), handle, |
||||
VIRGL_OBJECT_SAMPLER_STATE); |
||||
} |
||||
|
||||
static void graw_decode_create_ve(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
||||
{ |
||||
struct pipe_vertex_element *ve; |
||||
int num_elements; |
||||
int i; |
||||
|
||||
num_elements = (length - 1) / 4; |
||||
ve = calloc(num_elements, sizeof(struct pipe_vertex_element)); |
||||
if (!ve) |
||||
return; |
||||
|
||||
for (i = 0; i < num_elements; i++) { |
||||
uint32_t element_offset = ctx->ds->buf_offset + 2 + (i * 4); |
||||
ve[i].src_offset = ctx->ds->buf[element_offset]; |
||||
ve[i].instance_divisor = ctx->ds->buf[element_offset + 1]; |
||||
ve[i].vertex_buffer_index = ctx->ds->buf[element_offset + 2]; |
||||
ve[i].src_format = ctx->ds->buf[element_offset + 3]; |
||||
} |
||||
|
||||
grend_create_vertex_elements_state(ctx->grctx, handle, num_elements, |
||||
ve); |
||||
} |
||||
|
||||
static void graw_decode_create_query(struct grend_decode_ctx *ctx, uint32_t handle) |
||||
{ |
||||
uint32_t query_type; |
||||
uint32_t res_handle; |
||||
uint32_t offset; |
||||
query_type = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
offset = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
|
||||
grend_create_query(ctx->grctx, handle, query_type, res_handle, offset); |
||||
} |
||||
|
||||
static void graw_decode_create_object(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t header = ctx->ds->buf[ctx->ds->buf_offset]; |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset+1]; |
||||
uint16_t length; |
||||
uint8_t obj_type = (header >> 8) & 0xff; |
||||
|
||||
length = header >> 16; |
||||
|
||||
switch (obj_type){ |
||||
case VIRGL_OBJECT_BLEND: |
||||
graw_decode_create_blend(ctx, handle, length); |
||||
break; |
||||
case VIRGL_OBJECT_DSA: |
||||
graw_decode_create_dsa(ctx, handle, length); |
||||
break; |
||||
case VIRGL_OBJECT_RASTERIZER: |
||||
graw_decode_create_rasterizer(ctx, handle, length); |
||||
break; |
||||
case VIRGL_OBJECT_VS: |
||||
case VIRGL_OBJECT_FS: |
||||
graw_decode_create_shader(ctx, obj_type, handle, length); |
||||
break; |
||||
case VIRGL_OBJECT_VERTEX_ELEMENTS: |
||||
graw_decode_create_ve(ctx, handle, length); |
||||
break; |
||||
case VIRGL_OBJECT_SURFACE: |
||||
graw_decode_create_surface(ctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_SAMPLER_VIEW: |
||||
graw_decode_create_sampler_view(ctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_SAMPLER_STATE: |
||||
graw_decode_create_sampler_state(ctx, handle, length); |
||||
break; |
||||
case VIRGL_OBJECT_QUERY: |
||||
graw_decode_create_query(ctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_STREAMOUT_TARGET: |
||||
graw_decode_create_stream_output_target(ctx, handle); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static void graw_decode_bind_object(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t header = ctx->ds->buf[ctx->ds->buf_offset]; |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset+1]; |
||||
uint16_t length; |
||||
uint8_t obj_type = (header >> 8) & 0xff; |
||||
|
||||
length = header >> 16; |
||||
|
||||
switch (obj_type) { |
||||
case VIRGL_OBJECT_BLEND: |
||||
grend_object_bind_blend(ctx->grctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_DSA: |
||||
grend_object_bind_dsa(ctx->grctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_RASTERIZER: |
||||
grend_object_bind_rasterizer(ctx->grctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_VS: |
||||
grend_bind_vs(ctx->grctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_FS: |
||||
grend_bind_fs(ctx->grctx, handle); |
||||
break; |
||||
case VIRGL_OBJECT_VERTEX_ELEMENTS: |
||||
grend_bind_vertex_elements_state(ctx->grctx, handle); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static void graw_decode_destroy_object(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset+1]; |
||||
graw_renderer_object_destroy(ctx->grctx, handle); |
||||
} |
||||
|
||||
void graw_reset_decode(void) |
||||
{ |
||||
// free(gdctx->grctx);
|
||||
// gdctx->grctx = NULL;
|
||||
//gdctx->ds = NULL;
|
||||
} |
||||
|
||||
static void graw_decode_set_stencil_ref(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_stencil_ref ref; |
||||
uint32_t val = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
ref.ref_value[0] = val & 0xff; |
||||
ref.ref_value[1] = (val >> 8) & 0xff; |
||||
grend_set_stencil_ref(ctx->grctx, &ref); |
||||
} |
||||
|
||||
static void graw_decode_set_blend_color(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_blend_color color; |
||||
int i; |
||||
|
||||
for (i = 0; i < 4; i++) |
||||
color.color[i] = uif(ctx->ds->buf[ctx->ds->buf_offset + 1 + i]); |
||||
|
||||
grend_set_blend_color(ctx->grctx, &color); |
||||
} |
||||
|
||||
static void graw_decode_set_scissor_state(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_scissor_state ss; |
||||
uint32_t temp; |
||||
|
||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
ss.minx = temp & 0xffff; |
||||
ss.miny = (temp >> 16) & 0xffff; |
||||
|
||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
ss.maxx = temp & 0xffff; |
||||
ss.maxy = (temp >> 16) & 0xffff; |
||||
|
||||
grend_set_scissor_state(ctx->grctx, &ss); |
||||
} |
||||
|
||||
static void graw_decode_set_polygon_stipple(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_poly_stipple ps; |
||||
int i; |
||||
|
||||
for (i = 0; i < 32; i++) |
||||
ps.stipple[i] = ctx->ds->buf[ctx->ds->buf_offset + 1 + i]; |
||||
|
||||
grend_set_polygon_stipple(ctx->grctx, &ps); |
||||
} |
||||
|
||||
static void graw_decode_set_clip_state(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_clip_state clip; |
||||
int i, j; |
||||
|
||||
for (i = 0; i < 8; i++) |
||||
for (j = 0; j < 4; j++) |
||||
clip.ucp[i][j] = uif(ctx->ds->buf[ctx->ds->buf_offset + 1 + (i * 4) + j]); |
||||
grend_set_clip_state(ctx->grctx, &clip); |
||||
} |
||||
|
||||
static void graw_decode_set_sample_mask(struct grend_decode_ctx *ctx) |
||||
{ |
||||
unsigned mask; |
||||
|
||||
mask = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
grend_set_sample_mask(ctx->grctx, mask); |
||||
} |
||||
|
||||
static void graw_decode_resource_copy_region(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_box box; |
||||
uint32_t dst_handle, src_handle; |
||||
uint32_t dst_level, dstx, dsty, dstz; |
||||
uint32_t src_level; |
||||
|
||||
dst_handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
dst_level = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
dstx = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
dsty = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
dstz = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
src_handle = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
||||
src_level = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
||||
box.x = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
||||
box.y = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
||||
box.z = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
||||
box.width = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
||||
box.height = ctx->ds->buf[ctx->ds->buf_offset + 12]; |
||||
box.depth = ctx->ds->buf[ctx->ds->buf_offset + 13]; |
||||
|
||||
graw_renderer_resource_copy_region(ctx->grctx, dst_handle, |
||||
dst_level, dstx, dsty, dstz, |
||||
src_handle, src_level, |
||||
&box); |
||||
} |
||||
|
||||
|
||||
static void graw_decode_blit(struct grend_decode_ctx *ctx) |
||||
{ |
||||
struct pipe_blit_info info; |
||||
uint32_t dst_handle, src_handle, temp; |
||||
|
||||
info.mask = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
info.filter = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
info.scissor_enable = ctx->ds->buf[ctx->ds->buf_offset + 3] & 1; |
||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
||||
info.scissor.minx = temp & 0xffff; |
||||
info.scissor.miny = (temp >> 16) & 0xffff; |
||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
||||
info.scissor.maxx = temp & 0xffff; |
||||
info.scissor.maxy = (temp >> 16) & 0xffff; |
||||
dst_handle = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
||||
info.dst.level = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
||||
info.dst.format = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
||||
info.dst.box.x = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
||||
info.dst.box.y = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
||||
info.dst.box.z = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
||||
info.dst.box.width = ctx->ds->buf[ctx->ds->buf_offset + 12]; |
||||
info.dst.box.height = ctx->ds->buf[ctx->ds->buf_offset + 13]; |
||||
info.dst.box.depth = ctx->ds->buf[ctx->ds->buf_offset + 14]; |
||||
|
||||
src_handle = ctx->ds->buf[ctx->ds->buf_offset + 15]; |
||||
info.src.level = ctx->ds->buf[ctx->ds->buf_offset + 16]; |
||||
info.src.format = ctx->ds->buf[ctx->ds->buf_offset + 17]; |
||||
info.src.box.x = ctx->ds->buf[ctx->ds->buf_offset + 18]; |
||||
info.src.box.y = ctx->ds->buf[ctx->ds->buf_offset + 19]; |
||||
info.src.box.z = ctx->ds->buf[ctx->ds->buf_offset + 20]; |
||||
info.src.box.width = ctx->ds->buf[ctx->ds->buf_offset + 21]; |
||||
info.src.box.height = ctx->ds->buf[ctx->ds->buf_offset + 22]; |
||||
info.src.box.depth = ctx->ds->buf[ctx->ds->buf_offset + 23];
|
||||
|
||||
graw_renderer_blit(ctx->grctx, dst_handle, src_handle, &info); |
||||
} |
||||
|
||||
static void graw_decode_bind_sampler_states(struct grend_decode_ctx *ctx, int length) |
||||
{ |
||||
uint32_t shader_type = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
uint32_t start_slot = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
uint32_t num_states = length - 1; |
||||
|
||||
grend_bind_sampler_states(ctx->grctx, shader_type, start_slot, num_states, |
||||
&ctx->ds->buf[ctx->ds->buf_offset + 3]); |
||||
} |
||||
|
||||
static void graw_decode_begin_query(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
|
||||
grend_begin_query(ctx->grctx, handle); |
||||
} |
||||
|
||||
static void graw_decode_end_query(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
|
||||
grend_end_query(ctx->grctx, handle); |
||||
} |
||||
|
||||
static void graw_decode_get_query_result(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
uint32_t wait = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
||||
grend_get_query_result(ctx->grctx, handle, wait); |
||||
} |
||||
|
||||
static void graw_decode_set_render_condition(struct grend_decode_ctx *ctx) |
||||
{ |
||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
boolean condition = ctx->ds->buf[ctx->ds->buf_offset + 2] & 1; |
||||
uint mode = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
||||
grend_render_condition(ctx->grctx, handle, condition, mode); |
||||
} |
||||
|
||||
static void graw_decode_set_streamout_targets(struct grend_decode_ctx *ctx, |
||||
uint16_t length) |
||||
{ |
||||
uint32_t handles[16]; |
||||
uint32_t num_handles = length - 1; |
||||
uint32_t append_bitmask; |
||||
int i; |
||||
|
||||
append_bitmask = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
||||
for (i = 0; i < num_handles; i++) |
||||
handles[i] = ctx->ds->buf[ctx->ds->buf_offset + 2 + i]; |
||||
grend_set_streamout_targets(ctx->grctx, append_bitmask, num_handles, handles); |
||||
} |
||||
|
||||
static void graw_decode_set_query_state(struct grend_decode_ctx *ctx) |
||||
{ |
||||
boolean enabled; |
||||
|
||||
enabled = ctx->ds->buf[ctx->ds->buf_offset + 1] & 0x1; |
||||
grend_set_query_state(ctx->grctx, enabled); |
||||
} |
||||
|
||||
void graw_renderer_context_create_internal(uint32_t handle, uint32_t nlen, |
||||
const char *debug_name) |
||||
{ |
||||
struct grend_decode_ctx *dctx; |
||||
|
||||
if (handle > GRAW_MAX_CTX) |
||||
return; |
||||
|
||||
dctx = malloc(sizeof(struct grend_decode_ctx)); |
||||
if (!dctx) |
||||
return; |
||||
|
||||
dctx->grctx = grend_create_context(handle, nlen, debug_name); |
||||
if (!dctx->grctx) { |
||||
free(dctx); |
||||
return; |
||||
} |
||||
|
||||
dctx->ds = &dctx->ids; |
||||
|
||||
dec_ctx[handle] = dctx; |
||||
} |
||||
|
||||
void graw_renderer_context_create(uint32_t handle, uint32_t nlen, const char *debug_name) |
||||
{ |
||||
if (handle > GRAW_MAX_CTX) |
||||
return; |
||||
/* context 0 is always available with no guarantees */ |
||||
if (handle == 0) |
||||
return; |
||||
|
||||
graw_renderer_context_create_internal(handle, nlen, debug_name); |
||||
} |
||||
|
||||
void graw_renderer_context_destroy(uint32_t handle) |
||||
{ |
||||
struct grend_decode_ctx *ctx; |
||||
bool ret; |
||||
if (handle > GRAW_MAX_CTX) |
||||
return; |
||||
|
||||
ctx = dec_ctx[handle]; |
||||
dec_ctx[handle] = NULL; |
||||
ret = grend_destroy_context(ctx->grctx); |
||||
free(ctx); |
||||
/* switch to ctx 0 */ |
||||
if (ret) |
||||
grend_hw_switch_context(dec_ctx[0]->grctx, TRUE); |
||||
} |
||||
|
||||
struct grend_context *vrend_lookup_renderer_ctx(uint32_t ctx_id) |
||||
{ |
||||
if (ctx_id > GRAW_MAX_CTX) |
||||
return NULL; |
||||
|
||||
if (dec_ctx[ctx_id] == NULL) |
||||
return NULL; |
||||
|
||||
return dec_ctx[ctx_id]->grctx; |
||||
} |
||||
|
||||
static void graw_decode_block(uint32_t ctx_id, uint32_t *block, int ndw) |
||||
{ |
||||
int i = 0; |
||||
struct grend_decode_ctx *gdctx; |
||||
boolean ret; |
||||
if (ctx_id > GRAW_MAX_CTX) |
||||
return; |
||||
|
||||
if (dec_ctx[ctx_id] == NULL) |
||||
return; |
||||
|
||||
gdctx = dec_ctx[ctx_id]; |
||||
|
||||
ret = grend_hw_switch_context(gdctx->grctx, TRUE); |
||||
if (ret == FALSE) |
||||
return; |
||||
|
||||
gdctx->ds->buf = block; |
||||
gdctx->ds->buf_total = ndw; |
||||
gdctx->ds->buf_offset = 0; |
||||
|
||||
while (gdctx->ds->buf_offset < gdctx->ds->buf_total) { |
||||
uint32_t header = gdctx->ds->buf[gdctx->ds->buf_offset]; |
||||
|
||||
// fprintf(stderr,"[%d] cmd is %d (obj %d) len %d\n", gdctx->ds->buf_offset, header & 0xff, (header >> 8 & 0xff), (header >> 16));
|
||||
|
||||
switch (header & 0xff) { |
||||
case VIRGL_CCMD_CREATE_OBJECT: |
||||
graw_decode_create_object(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_BIND_OBJECT: |
||||
graw_decode_bind_object(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_DESTROY_OBJECT: |
||||
graw_decode_destroy_object(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_CLEAR: |
||||
graw_decode_clear(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_DRAW_VBO: |
||||
graw_decode_draw_vbo(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_FRAMEBUFFER_STATE: |
||||
graw_decode_set_framebuffer_state(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_VERTEX_BUFFERS: |
||||
graw_decode_set_vertex_buffers(gdctx, header >> 16); |
||||
break; |
||||
case VIRGL_CCMD_RESOURCE_INLINE_WRITE: |
||||
graw_decode_resource_inline_write(gdctx, header >> 16); |
||||
break; |
||||
case VIRGL_CCMD_SET_VIEWPORT_STATE: |
||||
graw_decode_set_viewport_state(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_SAMPLER_VIEWS: |
||||
graw_decode_set_sampler_views(gdctx, header >> 16); |
||||
break; |
||||
case VIRGL_CCMD_SET_INDEX_BUFFER: |
||||
graw_decode_set_index_buffer(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_CONSTANT_BUFFER: |
||||
graw_decode_set_constant_buffer(gdctx, header >> 16); |
||||
break; |
||||
case VIRGL_CCMD_SET_STENCIL_REF: |
||||
graw_decode_set_stencil_ref(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_BLEND_COLOR: |
||||
graw_decode_set_blend_color(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_SCISSOR_STATE: |
||||
graw_decode_set_scissor_state(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_BLIT: |
||||
graw_decode_blit(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_RESOURCE_COPY_REGION: |
||||
graw_decode_resource_copy_region(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_BIND_SAMPLER_STATES: |
||||
graw_decode_bind_sampler_states(gdctx, header >> 16); |
||||
break; |
||||
case VIRGL_CCMD_BEGIN_QUERY: |
||||
graw_decode_begin_query(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_END_QUERY: |
||||
graw_decode_end_query(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_GET_QUERY_RESULT: |
||||
graw_decode_get_query_result(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_POLYGON_STIPPLE: |
||||
graw_decode_set_polygon_stipple(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_CLIP_STATE: |
||||
graw_decode_set_clip_state(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_SAMPLE_MASK: |
||||
graw_decode_set_sample_mask(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_STREAMOUT_TARGETS: |
||||
graw_decode_set_streamout_targets(gdctx, header >> 16); |
||||
break; |
||||
case VIRGL_CCMD_SET_QUERY_STATE: |
||||
graw_decode_set_query_state(gdctx); |
||||
break; |
||||
case VIRGL_CCMD_SET_RENDER_CONDITION: |
||||
graw_decode_set_render_condition(gdctx); |
||||
break; |
||||
} |
||||
gdctx->ds->buf_offset += (header >> 16) + 1; |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
void graw_decode_block_iov(struct virgl_iovec *iov, unsigned int niovs, |
||||
uint32_t ctx_id, uint64_t offset, int ndw) |
||||
{ |
||||
uint32_t *block = (uint32_t *)(iov[0].iov_base + offset); |
||||
void *data; |
||||
if (niovs > 1) { |
||||
data = malloc(ndw * 4); |
||||
graw_iov_to_buf(iov, niovs, offset, data, ndw * 4); |
||||
} |
||||
else |
||||
data = (uint32_t *)(iov[0].iov_base + offset); |
||||
graw_decode_block(ctx_id, data, ndw); |
||||
if (niovs > 1) |
||||
free(data); |
||||
|
||||
} |
||||
|
@ -1,13 +0,0 @@ |
||||
#ifndef GRAW_DECODE_H |
||||
#define GRAW_DECODE_H |
||||
|
||||
struct graw_decoder_state { |
||||
uint32_t *buf; |
||||
uint32_t buf_total; |
||||
uint32_t buf_offset; |
||||
}; |
||||
|
||||
|
||||
void graw_decode_transfer(uint32_t *data, uint32_t ndw); |
||||
void graw_decode_get_transfer(uint32_t *data, uint32_t ndw); |
||||
#endif |
@ -1,22 +0,0 @@ |
||||
|
||||
#ifndef GRAW_IOV_H |
||||
#define GRAW_IOV_H |
||||
|
||||
/* stolen from qemu for now until later integration */ |
||||
struct virgl_iovec { |
||||
void *iov_base; |
||||
size_t iov_len; |
||||
}; |
||||
|
||||
typedef void (*IOCallback)(void *cookie, unsigned int doff, void *src, int len); |
||||
|
||||
size_t graw_iov_size(const struct virgl_iovec *iov, const unsigned int iov_cnt); |
||||
size_t graw_iov_from_buf(const struct virgl_iovec *iov, unsigned int iov_cnt, |
||||
size_t offset, const void *buf, size_t bytes); |
||||
size_t graw_iov_to_buf(const struct virgl_iovec *iov, const unsigned int iov_cnt, |
||||
size_t offset, void *buf, size_t bytes); |
||||
|
||||
size_t graw_iov_to_buf_cb(const struct virgl_iovec *iov, const unsigned int iov_cnt, |
||||
size_t offset, size_t bytes, IOCallback iocb, void *cookie); |
||||
|
||||
#endif |
@ -1,322 +0,0 @@ |
||||
#ifndef GRAW_RENDERER_H |
||||
#define GRAW_RENDERER_H |
||||
|
||||
#include "pipe/p_state.h" |
||||
#include "util/u_inlines.h" |
||||
#include "virgl_protocol.h" |
||||
#include "graw_iov.h" |
||||
#include "virgl_hw.h" |
||||
|
||||
typedef void *virgl_gl_context; |
||||
typedef void *virgl_gl_drawable; |
||||
|
||||
extern int vrend_dump_shaders; |
||||
struct grend_context; |
||||
|
||||
struct grend_resource { |
||||
struct pipe_resource base; |
||||
GLuint id; |
||||
GLenum target; |
||||
/* fb id if we need to readback this resource */ |
||||
GLuint readback_fb_id; |
||||
GLuint readback_fb_level; |
||||
GLuint readback_fb_z; |
||||
int is_front; |
||||
GLboolean renderer_flipped; |
||||
void *ptr; |
||||
GLuint handle; |
||||
|
||||
struct virgl_iovec *iov; |
||||
uint32_t num_iovs; |
||||
boolean y_0_top; |
||||
|
||||
boolean scannedout; |
||||
}; |
||||
|
||||
/* assume every format is sampler friendly */ |
||||
#define VREND_BIND_RENDER (1 << 0) |
||||
#define VREND_BIND_DEPTHSTENCIL (1 << 1) |
||||
|
||||
struct grend_format_table { |
||||
enum virgl_formats format; |
||||
GLenum internalformat; |
||||
GLenum glformat; |
||||
GLenum gltype; |
||||
uint32_t bindings; |
||||
}; |
||||
|
||||
struct grend_if_cbs { |
||||
void (*write_fence)(unsigned fence_id); |
||||
/* inform the control layer about a new scanout */ |
||||
void (*scanout_rect_info)(int scanout_id, GLuint tex_id, int x, int y, |
||||
uint32_t width, uint32_t height); |
||||
void (*scanout_resource_info)(int scanout_id, GLuint tex_id, uint32_t flags, |
||||
uint32_t stride, |
||||
uint32_t width, uint32_t height, uint32_t format); |
||||
|
||||
virgl_gl_context (*create_gl_context)(int scanout); |
||||
void (*destroy_gl_context)(virgl_gl_context ctx); |
||||
int (*make_current)(int scanout, virgl_gl_context ctx); |
||||
|
||||
void (*flush_scanout)(int scanout, int x, int y, uint32_t width, uint32_t height); |
||||
void (*inval_backing)(struct virgl_iovec *iov, uint32_t iov_cnt); |
||||
}; |
||||
void graw_renderer_init(struct grend_if_cbs *cbs); |
||||
|
||||
void grend_insert_format(struct grend_format_table *entry, uint32_t bindings); |
||||
void grend_create_vs(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
const struct pipe_shader_state *vs); |
||||
|
||||
void grend_create_fs(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
const struct pipe_shader_state *vs); |
||||
|
||||
void grend_bind_vs(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void grend_bind_fs(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void grend_bind_vs_so(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
void grend_clear(struct grend_context *ctx, |
||||
unsigned buffers, |
||||
const union pipe_color_union *color, |
||||
double depth, unsigned stencil); |
||||
|
||||
void grend_draw_vbo(struct grend_context *ctx, |
||||
const struct pipe_draw_info *info); |
||||
|
||||
void grend_set_framebuffer_state(struct grend_context *ctx, |
||||
uint32_t nr_cbufs, uint32_t surf_handle[8], |
||||
uint32_t zsurf_handle); |
||||
|
||||
void grend_flush(struct grend_context *ctx); |
||||
|
||||
|
||||
void grend_flush_frontbuffer(uint32_t res_handle); |
||||
struct grend_context *grend_create_context(int id, uint32_t nlen, const char *debug_name); |
||||
bool grend_destroy_context(struct grend_context *ctx); |
||||
void graw_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name); |
||||
void graw_renderer_context_create_internal(uint32_t handle, uint32_t nlen, const char *name); |
||||
void graw_renderer_context_destroy(uint32_t handle); |
||||
|
||||
struct graw_renderer_resource_create_args { |
||||
uint32_t handle; |
||||
enum pipe_texture_target target; |
||||
uint32_t format; |
||||
uint32_t bind; |
||||
uint32_t width; |
||||
uint32_t height; |
||||
uint32_t depth; |
||||
uint32_t array_size; |
||||
uint32_t last_level; |
||||
uint32_t nr_samples; |
||||
uint32_t flags; |
||||
}; |
||||
|
||||
void graw_renderer_resource_create(struct graw_renderer_resource_create_args *args, struct virgl_iovec *iov, uint32_t num_iovs); |
||||
|
||||
void graw_renderer_resource_unref(uint32_t handle); |
||||
|
||||
void grend_create_surface(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
uint32_t res_handle, uint32_t format, |
||||
uint32_t val0, uint32_t val1); |
||||
void grend_create_sampler_view(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
uint32_t res_handle, uint32_t format, |
||||
uint32_t val0, uint32_t val1, uint32_t swizzle_packed); |
||||
|
||||
void grend_create_so_target(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
uint32_t res_handle, |
||||
uint32_t buffer_offset, |
||||
uint32_t buffer_size); |
||||
void grend_set_streamout_targets(struct grend_context *ctx, |
||||
uint32_t append_bitmask, |
||||
uint32_t num_targets, |
||||
uint32_t *handles); |
||||
|
||||
void grend_create_vertex_elements_state(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
unsigned num_elements, |
||||
const struct pipe_vertex_element *elements); |
||||
void grend_bind_vertex_elements_state(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void grend_set_single_vbo(struct grend_context *ctx, |
||||
int index, |
||||
uint32_t stride, |
||||
uint32_t buffer_offset, |
||||
uint32_t res_handle); |
||||
void grend_set_num_vbo(struct grend_context *ctx, |
||||
int num_vbo); |
||||
|
||||
void grend_transfer_inline_write(struct grend_context *ctx, |
||||
uint32_t res_handle, |
||||
unsigned level, |
||||
unsigned usage, |
||||
const struct pipe_box *box, |
||||
const void *data, |
||||
unsigned stride, |
||||
unsigned layer_stride); |
||||
|
||||
void grend_set_viewport_state(struct grend_context *ctx, |
||||
const struct pipe_viewport_state *state); |
||||
void grend_set_num_sampler_views(struct grend_context *ctx, |
||||
uint32_t shader_type, |
||||
uint32_t start_slot, |
||||
int num_sampler_views); |
||||
void grend_set_single_sampler_view(struct grend_context *ctx, |
||||
uint32_t shader_type, |
||||
int index, |
||||
uint32_t res_handle); |
||||
|
||||
void grend_object_bind_blend(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
void grend_object_bind_dsa(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
void grend_object_bind_rasterizer(struct grend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void grend_bind_sampler_states(struct grend_context *ctx, |
||||
uint32_t shader_type, |
||||
uint32_t start_slot, |
||||
uint32_t num_states, |
||||
uint32_t *handles); |
||||
void grend_set_index_buffer(struct grend_context *ctx, |
||||
uint32_t res_handle, |
||||
uint32_t index_size, |
||||
uint32_t offset); |
||||
|
||||
void graw_renderer_transfer_write_iov(uint32_t handle,
|
||||
uint32_t ctx_id, |
||||
int level, |
||||
uint32_t stride, |
||||
uint32_t layer_stride, |
||||
struct pipe_box *box, |
||||
uint64_t offset, |
||||
struct virgl_iovec *iovec, |
||||
unsigned int iovec_cnt); |
||||
|
||||
void graw_renderer_resource_copy_region(struct grend_context *ctx, |
||||
uint32_t dst_handle, uint32_t dst_level, |
||||
uint32_t dstx, uint32_t dsty, uint32_t dstz, |
||||
uint32_t src_handle, uint32_t src_level, |
||||
const struct pipe_box *src_box); |
||||
|
||||
void graw_renderer_blit(struct grend_context *ctx, |
||||
uint32_t dst_handle, uint32_t src_handle, |
||||
const struct pipe_blit_info *info); |
||||
|
||||
void graw_renderer_transfer_send_iov(uint32_t handle, uint32_t ctx_id, |
||||
uint32_t level, uint32_t stride, |
||||
uint32_t layer_stride, |
||||
struct pipe_box *box, |
||||
uint64_t offset, struct virgl_iovec *iov, |
||||
int iovec_cnt); |
||||
void grend_set_stencil_ref(struct grend_context *ctx, struct pipe_stencil_ref *ref); |
||||
void grend_set_blend_color(struct grend_context *ctx, struct pipe_blend_color *color); |
||||
void grend_set_scissor_state(struct grend_context *ctx, struct pipe_scissor_state *ss); |
||||
|
||||
void grend_set_polygon_stipple(struct grend_context *ctx, struct pipe_poly_stipple *ps); |
||||
|
||||
void grend_set_clip_state(struct grend_context *ctx, struct pipe_clip_state *ucp); |
||||
void grend_set_sample_mask(struct grend_context *ctx, unsigned sample_mask); |
||||
|
||||
void grend_set_constants(struct grend_context *ctx, |
||||
uint32_t shader, |
||||
uint32_t index, |
||||
uint32_t num_constant, |
||||
float *data); |
||||
|
||||
void graw_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
||||
struct virgl_iovec *iov, int iovec_cnt); |
||||
|
||||
void graw_transfer_write_tex_return(struct pipe_resource *res, |
||||
struct pipe_box *box, |
||||
uint32_t level, |
||||
uint32_t dst_stride, |
||||
uint64_t offset, |
||||
struct virgl_iovec *iov, |
||||
int num_iovs, |
||||
void *myptr, int size, int invert); |
||||
|
||||
int graw_renderer_set_scanout(uint32_t res_handle, |
||||
uint32_t scanout_id, |
||||
uint32_t ctx_id, |
||||
struct pipe_box *box); |
||||
|
||||
int graw_renderer_flush_buffer(uint32_t res_handle, |
||||
uint32_t ctx_id, |
||||
struct pipe_box *box); |
||||
|
||||
void graw_renderer_fini(void); |
||||
void graw_reset_decode(void); |
||||
|
||||
void graw_decode_block_iov(struct virgl_iovec *iov, uint32_t niovs, uint32_t ctx_id, uint64_t offset, int ndw); |
||||
struct grend_context *vrend_lookup_renderer_ctx(uint32_t ctx_id); |
||||
|
||||
int graw_renderer_create_fence(int client_fence_id, uint32_t ctx_id); |
||||
|
||||
void graw_renderer_check_fences(void); |
||||
void graw_renderer_check_queries(void); |
||||
void grend_stop_current_queries(void); |
||||
|
||||
boolean grend_hw_switch_context(struct grend_context *ctx, boolean now); |
||||
void graw_renderer_object_insert(struct grend_context *ctx, void *data, |
||||
uint32_t size, uint32_t handle, enum virgl_object_type type); |
||||
void graw_renderer_object_destroy(struct grend_context *ctx, uint32_t handle); |
||||
|
||||
void grend_create_query(struct grend_context *ctx, uint32_t handle, |
||||
uint32_t query_type, uint32_t res_handle, |
||||
uint32_t offset); |
||||
|
||||
void grend_begin_query(struct grend_context *ctx, uint32_t handle); |
||||
void grend_end_query(struct grend_context *ctx, uint32_t handle); |
||||
void grend_get_query_result(struct grend_context *ctx, uint32_t handle, |
||||
uint32_t wait); |
||||
void grend_set_query_state(struct grend_context *ctx, |
||||
boolean enabled); |
||||
void grend_render_condition(struct grend_context *ctx, |
||||
uint32_t handle, |
||||
boolean condtion, |
||||
uint mode); |
||||
void grend_set_cursor_info(uint32_t cursor_handle, int x, int y); |
||||
void *graw_renderer_get_cursor_contents(uint32_t res_handle, uint32_t *width, uint32_t *height); |
||||
void grend_use_program(GLuint program_id); |
||||
void grend_blend_enable(GLboolean blend_enable); |
||||
void grend_depth_test_enable(GLboolean depth_test_enable); |
||||
void grend_bind_va(GLuint vaoid); |
||||
int graw_renderer_flush_buffer_res(struct grend_resource *res, |
||||
struct pipe_box *box); |
||||
|
||||
void graw_renderer_fill_caps(uint32_t set, uint32_t version, |
||||
union virgl_caps *caps); |
||||
|
||||
GLint64 graw_renderer_get_timestamp(void); |
||||
/* formats */ |
||||
void vrend_build_format_list(void); |
||||
|
||||
int graw_renderer_resource_attach_iov(int res_handle, struct virgl_iovec *iov, |
||||
int num_iovs); |
||||
void graw_renderer_resource_invalid_iov(int res_handle); |
||||
void graw_renderer_resource_destroy(struct grend_resource *res); |
||||
|
||||
static INLINE void |
||||
grend_resource_reference(struct grend_resource **ptr, struct grend_resource *tex) |
||||
{ |
||||
struct grend_resource *old_tex = *ptr; |
||||
|
||||
if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference)) |
||||
graw_renderer_resource_destroy(old_tex); |
||||
*ptr = tex; |
||||
} |
||||
|
||||
void graw_renderer_force_ctx_0(void); |
||||
|
||||
void graw_renderer_get_rect(int idx, struct virgl_iovec *iov, unsigned int num_iovs, |
||||
uint32_t offset, int x, int y, int width, int height); |
||||
#endif |
@ -1,40 +0,0 @@ |
||||
#ifndef GRAW_SHADER_H |
||||
#define GRAW_SHADER_H |
||||
|
||||
#include "pipe/p_state.h" |
||||
|
||||
#define SHADER_FLAG_FS_INVERT 1 |
||||
|
||||
/* need to store patching info for interpolation */ |
||||
struct vrend_interp_info { |
||||
int semantic_name; |
||||
int semantic_index; |
||||
int interpolate; |
||||
}; |
||||
|
||||
struct vrend_shader_info { |
||||
uint32_t samplers_used_mask; |
||||
int num_consts; |
||||
int num_inputs; |
||||
int num_interps; |
||||
int num_outputs; |
||||
uint32_t shadow_samp_mask; |
||||
struct pipe_stream_output_info so_info; |
||||
|
||||
struct vrend_interp_info *interpinfo; |
||||
}; |
||||
|
||||
struct vrend_shader_key { |
||||
uint32_t coord_replace; |
||||
boolean invert_fs_origin; |
||||
}; |
||||
|
||||
boolean vrend_patch_vertex_shader_interpolants(char *program, |
||||
struct vrend_shader_info *vs_info, |
||||
struct vrend_shader_info *fs_info); |
||||
|
||||
char *tgsi_convert(const struct tgsi_token *tokens, |
||||
struct vrend_shader_key *key, |
||||
struct vrend_shader_info *sinfo); |
||||
|
||||
#endif |
@ -1,426 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <time.h> |
||||
|
||||
#include <epoxy/gl.h> |
||||
|
||||
#include <sys/mman.h> |
||||
#include <sys/stat.h> |
||||
#include <fcntl.h> |
||||
#include <errno.h> |
||||
#include <unistd.h> |
||||
#include <sys/socket.h> |
||||
#include <sys/un.h> |
||||
#include <sys/eventfd.h> |
||||
#include "virtgpu_hw.h" |
||||
#include "pipe/p_state.h" |
||||
#include "util/u_format.h" |
||||
#include "util/u_math.h" |
||||
#include "graw_renderer.h" |
||||
|
||||
#include "virglrenderer.h" |
||||
#include "virgl_egl.h" |
||||
|
||||
static struct virgl_renderer_callbacks *rcbs; |
||||
|
||||
static void *dev_cookie; |
||||
extern int localrender; |
||||
static int use_egl_context; |
||||
struct virgl_egl *egl_info; |
||||
static struct grend_if_cbs virgl_cbs; |
||||
|
||||
static int graw_process_cmd(struct virtgpu_command *cmd, struct virgl_iovec *iov, |
||||
unsigned int niovs); |
||||
|
||||
int virgl_renderer_process_vcmd(void *cmd, struct virgl_iovec *iov, unsigned int niovs) |
||||
{ |
||||
struct virtgpu_command *qcmd = cmd; |
||||
int ret; |
||||
ret = graw_process_cmd(qcmd, iov, niovs); |
||||
graw_renderer_check_fences(); |
||||
return ret; |
||||
} |
||||
|
||||
static void virgl_cmd_create_resource_2d(struct virtgpu_command *cmd) |
||||
{ |
||||
struct graw_renderer_resource_create_args args; |
||||
|
||||
args.handle = cmd->u.resource_create_2d.resource_id; |
||||
args.target = 2; |
||||
args.format = cmd->u.resource_create_2d.format; |
||||
args.bind = (1 << 1); |
||||
args.width = cmd->u.resource_create_2d.width; |
||||
args.height = cmd->u.resource_create_2d.height; |
||||
args.depth = 1; |
||||
args.array_size = 1; |
||||
args.last_level = 0; |
||||
args.nr_samples = 0; |
||||
args.flags = VIRGL_RESOURCE_Y_0_TOP; |
||||
graw_renderer_resource_create(&args, NULL, 0); |
||||
} |
||||
|
||||
static void virgl_cmd_create_resource_3d(struct virtgpu_command *cmd) |
||||
{ |
||||
struct graw_renderer_resource_create_args args; |
||||
|
||||
args.handle = cmd->u.resource_create_3d.resource_id; |
||||
args.target = cmd->u.resource_create_3d.target; |
||||
args.format = cmd->u.resource_create_3d.format; |
||||
args.bind = cmd->u.resource_create_3d.bind; |
||||
args.width = cmd->u.resource_create_3d.width; |
||||
args.height = cmd->u.resource_create_3d.height; |
||||
args.depth = cmd->u.resource_create_3d.depth; |
||||
args.array_size = cmd->u.resource_create_3d.array_size; |
||||
args.last_level = cmd->u.resource_create_3d.last_level; |
||||
args.nr_samples = cmd->u.resource_create_3d.nr_samples; |
||||
args.flags = cmd->u.resource_create_3d.flags; |
||||
graw_renderer_resource_create(&args, NULL, 0); |
||||
} |
||||
|
||||
static void virgl_resource_attach_backing(struct virtgpu_resource_attach_backing *att_rb, |
||||
struct iovec *iov, |
||||
unsigned int iov_cnt) |
||||
{ |
||||
uint32_t gsize = graw_iov_size(iov, iov_cnt); |
||||
struct virgl_iovec *res_iovs; |
||||
int i; |
||||
void *data; |
||||
int ret; |
||||
|
||||
res_iovs = malloc(att_rb->nr_entries * sizeof(struct virgl_iovec)); |
||||
if (!res_iovs) |
||||
return; |
||||
|
||||
if (iov_cnt > 1) { |
||||
data = malloc(gsize); |
||||
graw_iov_to_buf(iov, iov_cnt, 0, data, gsize); |
||||
} else |
||||
data = iov[0].iov_base; |
||||
|
||||
for (i = 0; i < att_rb->nr_entries; i++) { |
||||
struct virtgpu_mem_entry *ent = ((struct virtgpu_mem_entry *)data) + i; |
||||
res_iovs[i].iov_len = ent->length; |
||||
ret = rcbs->map_iov(&res_iovs[i], ent->addr); |
||||
if (ret) { |
||||
fprintf(stderr, "failed to attach backing %d\n", att_rb->resource_id); |
||||
free(res_iovs); |
||||
res_iovs = NULL; |
||||
goto fail_free; |
||||
} |
||||
} |
||||
|
||||
ret = graw_renderer_resource_attach_iov(att_rb->resource_id, res_iovs, |
||||
att_rb->nr_entries); |
||||
goto out; |
||||
fail_free: |
||||
free(res_iovs); |
||||
out: |
||||
|
||||
if (iov_cnt > 1) |
||||
free(data); |
||||
} |
||||
|
||||
static void virgl_resource_inval_backing_iov(struct virgl_iovec *iov, uint32_t iov_cnt) |
||||
{ |
||||
int i; |
||||
for (i = 0; i < iov_cnt; i++) { |
||||
rcbs->unmap_iov(&iov[i]); |
||||
} |
||||
free(iov); |
||||
} |
||||
|
||||
static void virgl_resource_inval_backing(int resource_id) |
||||
{ |
||||
graw_renderer_resource_invalid_iov(resource_id); |
||||
} |
||||
|
||||
static int graw_process_cmd(struct virtgpu_command *cmd, struct virgl_iovec *iov, |
||||
unsigned int niovs) |
||||
{ |
||||
static int inited; |
||||
int fence_ctx_id = 0; |
||||
|
||||
graw_renderer_force_ctx_0(); |
||||
switch (cmd->type) { |
||||
case VIRTGPU_CMD_CTX_CREATE: |
||||
graw_renderer_context_create(cmd->u.ctx_create.ctx_id, cmd->u.ctx_create.nlen, |
||||
cmd->u.ctx_create.debug_name); |
||||
break; |
||||
case VIRTGPU_CMD_CTX_DESTROY: |
||||
graw_renderer_context_destroy(cmd->u.ctx_destroy.ctx_id); |
||||
break; |
||||
case VIRTGPU_CMD_RESOURCE_CREATE_2D: |
||||
virgl_cmd_create_resource_2d(cmd); |
||||
break; |
||||
case VIRTGPU_CMD_RESOURCE_CREATE_3D: |
||||
virgl_cmd_create_resource_3d(cmd); |
||||
break; |
||||
case VIRTGPU_CMD_SUBMIT_3D: |
||||
// fprintf(stderr,"cmd submit %lx %d\n", cmd->u.cmd_submit.data, cmd->u.cmd_submit.size);
|
||||
|
||||
{ |
||||
graw_decode_block_iov(iov, niovs, cmd->u.cmd_submit.ctx_id, cmd->u.cmd_submit.phy_addr, cmd->u.cmd_submit.size / 4); |
||||
fence_ctx_id = cmd->u.cmd_submit.ctx_id; |
||||
} |
||||
|
||||
break; |
||||
case VIRTGPU_CMD_TRANSFER_TO_HOST_2D: { |
||||
struct pipe_box box; |
||||
|
||||
box.x = cmd->u.transfer_to_host_2d.x; |
||||
box.y = cmd->u.transfer_to_host_2d.y; |
||||
box.z = 0; |
||||
box.width = cmd->u.transfer_to_host_2d.width; |
||||
box.height = cmd->u.transfer_to_host_2d.height; |
||||
box.depth = 1; |
||||
|
||||
// fprintf(stderr,"got transfer get %d\n", cmd->u.transfer_to_host_3d.res_handle);
|
||||
graw_renderer_transfer_write_iov(cmd->u.transfer_to_host_2d.resource_id, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
(struct pipe_box *)&box, |
||||
cmd->u.transfer_to_host_2d.offset, NULL, 0); |
||||
break; |
||||
} |
||||
case VIRTGPU_CMD_TRANSFER_TO_HOST_3D: |
||||
// fprintf(stderr,"got transfer get %d\n", cmd->u.transfer_to_host_3d.res_handle);
|
||||
graw_renderer_transfer_write_iov(cmd->u.transfer_to_host_3d.resource_id, |
||||
cmd->u.transfer_to_host_3d.ctx_id, |
||||
cmd->u.transfer_to_host_3d.level, |
||||
cmd->u.transfer_to_host_3d.stride, |
||||
cmd->u.transfer_to_host_3d.layer_stride, |
||||
(struct pipe_box *)&cmd->u.transfer_to_host_3d.box, |
||||
cmd->u.transfer_to_host_3d.data, NULL, 0); |
||||
fence_ctx_id = cmd->u.transfer_to_host_3d.ctx_id; |
||||
break; |
||||
case VIRTGPU_CMD_TRANSFER_FROM_HOST_3D: |
||||
graw_renderer_transfer_send_iov(cmd->u.transfer_from_host_3d.resource_id, |
||||
cmd->u.transfer_from_host_3d.ctx_id, |
||||
cmd->u.transfer_from_host_3d.level, |
||||
cmd->u.transfer_from_host_3d.stride, |
||||
cmd->u.transfer_from_host_3d.layer_stride, |
||||
(struct pipe_box *)&cmd->u.transfer_from_host_3d.box, |
||||
cmd->u.transfer_from_host_3d.data, NULL, 0); |
||||
fence_ctx_id = cmd->u.transfer_from_host_3d.ctx_id; |
||||
break; |
||||
|
||||
case VIRTGPU_CMD_RESOURCE_ATTACH_BACKING: |
||||
virgl_resource_attach_backing(&cmd->u.resource_attach_backing, iov, niovs); |
||||
break; |
||||
case VIRTGPU_CMD_RESOURCE_INVAL_BACKING: |
||||
virgl_resource_inval_backing(cmd->u.resource_inval_backing.resource_id); |
||||
break; |
||||
case VIRTGPU_CMD_SET_SCANOUT: { |
||||
struct pipe_box box; |
||||
box.x = cmd->u.set_scanout.x; |
||||
box.y = cmd->u.set_scanout.y; |
||||
box.z = 0; |
||||
box.width = cmd->u.set_scanout.width; |
||||
box.height = cmd->u.set_scanout.height; |
||||
box.depth = 1; |
||||
graw_renderer_set_scanout(cmd->u.set_scanout.resource_id, cmd->u.set_scanout.scanout_id, |
||||
0, &box); |
||||
break; |
||||
} |
||||
case VIRTGPU_CMD_RESOURCE_FLUSH: |
||||
{ |
||||
struct pipe_box box; |
||||
box.x = cmd->u.resource_flush.x; |
||||
box.y = cmd->u.resource_flush.y; |
||||
box.z = 0; |
||||
box.width = cmd->u.resource_flush.width; |
||||
box.height = cmd->u.resource_flush.height; |
||||
box.depth = 1; |
||||
graw_renderer_flush_buffer(cmd->u.resource_flush.resource_id, |
||||
0, &box); |
||||
break; |
||||
}
|
||||
case VIRTGPU_CMD_RESOURCE_UNREF: |
||||
graw_renderer_resource_unref(cmd->u.resource_unref.resource_id); |
||||
break; |
||||
case VIRTGPU_CMD_CTX_ATTACH_RESOURCE: |
||||
/* TODO add security */ |
||||
break; |
||||
case VIRTGPU_CMD_CTX_DETACH_RESOURCE: |
||||
/* TODO add security */ |
||||
break; |
||||
case VIRTGPU_CMD_GET_CAPS: |
||||
if (!niovs) |
||||
return 0; |
||||
|
||||
{ |
||||
struct virtgpu_response resp; |
||||
graw_renderer_fill_caps(cmd->u.get_cap.cap_set, |
||||
cmd->u.get_cap.cap_set_version, |
||||
(union virgl_caps *)&resp.u.caps); |
||||
resp.flags = 0; |
||||
resp.type = VIRTGPU_CMD_GET_CAPS; |
||||
graw_iov_from_buf(iov, niovs, 0, &resp, sizeof(struct virtgpu_response)); |
||||
} |
||||
|
||||
break; |
||||
case VIRTGPU_CMD_GET_DISPLAY_INFO: |
||||
return -1; |
||||
case 0xdeadbeef: |
||||
if (inited) { |
||||
graw_renderer_fini(); |
||||
|
||||
} |
||||
graw_renderer_init(&virgl_cbs); |
||||
inited = 1; |
||||
break; |
||||
} |
||||
|
||||
if (cmd->flags & VIRGL_COMMAND_EMIT_FENCE) |
||||
graw_renderer_create_fence(cmd->fence_id, fence_ctx_id); |
||||
return 0; |
||||
} |
||||
|
||||
void graw_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
||||
struct virgl_iovec *iov, int num_iovs) |
||||
{ |
||||
graw_iov_from_buf(iov, num_iovs, offset, data, bytes); |
||||
} |
||||
|
||||
void graw_transfer_write_tex_return(struct pipe_resource *res, |
||||
struct pipe_box *box, |
||||
uint32_t level, |
||||
uint32_t dst_stride, |
||||
uint64_t offset, |
||||
struct virgl_iovec *iov, |
||||
int num_iovs, |
||||
void *myptr, int size, int invert) |
||||
{ |
||||
int elsize = util_format_get_blocksize(res->format); |
||||
int h; |
||||
uint32_t myoffset = offset; |
||||
uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * elsize; |
||||
// uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, box->width) * elsize;
|
||||
|
||||
if (!invert && (stride == util_format_get_nblocksx(res->format, box->width) * elsize)) |
||||
graw_iov_from_buf(iov, num_iovs, offset, myptr, size); |
||||
else if (invert) { |
||||
for (h = box->height - 1; h >= 0; h--) { |
||||
void *sptr = myptr + (h * elsize * box->width); |
||||
graw_iov_from_buf(iov, num_iovs, myoffset, sptr, box->width * elsize); |
||||
myoffset += stride; |
||||
} |
||||
} else { |
||||
for (h = 0; h < box->height; h++) { |
||||
void *sptr = myptr + (h * elsize * box->width); |
||||
graw_iov_from_buf(iov, num_iovs, myoffset, sptr, box->width * elsize); |
||||
myoffset += stride; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void virgl_write_fence(uint32_t fence_id) |
||||
{ |
||||
rcbs->write_fence(dev_cookie, fence_id);
|
||||
} |
||||
|
||||
static virgl_gl_context create_gl_context(int scanout_idx) |
||||
{ |
||||
if (use_egl_context) |
||||
return virgl_egl_create_context(egl_info); |
||||
return rcbs->create_gl_context(dev_cookie, scanout_idx); |
||||
} |
||||
|
||||
static void destroy_gl_context(virgl_gl_context ctx) |
||||
{ |
||||
if (use_egl_context) |
||||
return virgl_egl_destroy_context(egl_info, ctx); |
||||
return rcbs->destroy_gl_context(dev_cookie, ctx); |
||||
} |
||||
|
||||
static int make_current(int scanout_idx, virgl_gl_context ctx) |
||||
{ |
||||
if (use_egl_context) |
||||
return virgl_egl_make_context_current(egl_info, ctx); |
||||
return rcbs->make_current(dev_cookie, scanout_idx, ctx); |
||||
} |
||||
|
||||
static void flush_scanout(int scanout_id, int x, int y, uint32_t width, uint32_t height) |
||||
{ |
||||
if (rcbs->rect_update) |
||||
rcbs->rect_update(dev_cookie, scanout_id, x, y, width, height); |
||||
} |
||||
|
||||
static void scanout_rect_info(int scanout_id, GLuint tex_id, |
||||
int x, int y, uint32_t width, |
||||
uint32_t height) |
||||
{ |
||||
if (rcbs->scanout_rect_info) |
||||
rcbs->scanout_rect_info(dev_cookie, scanout_id, tex_id, |
||||
x, y, width, height); |
||||
} |
||||
|
||||
static void scanout_resource_info(int scanout_id, GLuint tex_id, uint32_t flags, |
||||
uint32_t stride, uint32_t width, |
||||
uint32_t height, uint32_t format) |
||||
{ |
||||
if (rcbs->scanout_resource_info) |
||||
rcbs->scanout_resource_info(dev_cookie, scanout_id, tex_id, flags, |
||||
stride, width, height, virgl_egl_get_gbm_format(format)); |
||||
} |
||||
|
||||
static struct grend_if_cbs virgl_cbs = { |
||||
virgl_write_fence, |
||||
scanout_rect_info, |
||||
scanout_resource_info, |
||||
create_gl_context, |
||||
destroy_gl_context, |
||||
make_current, |
||||
flush_scanout, |
||||
virgl_resource_inval_backing_iov, |
||||
}; |
||||
|
||||
void *virgl_get_cursor_data(uint32_t resource_id, uint32_t *width, uint32_t *height) |
||||
{ |
||||
return graw_renderer_get_cursor_contents(resource_id, width, height); |
||||
} |
||||
|
||||
void virgl_renderer_set_cursor_info(uint32_t cursor_handle, int x, int y) |
||||
{ |
||||
grend_set_cursor_info(cursor_handle, x, y); |
||||
} |
||||
|
||||
void virgl_renderer_poll(void) |
||||
{ |
||||
graw_renderer_check_queries(); |
||||
graw_renderer_check_fences(); |
||||
} |
||||
|
||||
void virgl_renderer_get_rect(int idx, struct virgl_iovec *iov, unsigned int num_iovs, |
||||
uint32_t offset, int x, int y, int width, int height) |
||||
{ |
||||
graw_renderer_get_rect(idx, iov, num_iovs, offset, x, y, width, height); |
||||
|
||||
} |
||||
|
||||
int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cbs) |
||||
{ |
||||
dev_cookie = cookie; |
||||
rcbs = cbs; |
||||
localrender = 1; |
||||
|
||||
fprintf(stderr,"initied renderer %d\n", flags); |
||||
if (flags & VIRGL_RENDERER_USE_EGL) { |
||||
egl_info = virgl_egl_init(); |
||||
if (!egl_info) |
||||
return -1; |
||||
use_egl_context = 1; |
||||
} |
||||
|
||||
if (cbs->version != 1) |
||||
return -1; |
||||
graw_renderer_init(&virgl_cbs); |
||||
return 0; |
||||
} |
||||
|
||||
int virgl_renderer_get_fd_for_texture(uint32_t tex_id, int *fd) |
||||
{ |
||||
return virgl_egl_get_fd_for_texture(egl_info, tex_id, fd); |
||||
|
||||
} |
@ -0,0 +1,282 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* Copyright (C) 2014 Red Hat Inc. |
||||
* |
||||
* 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 |
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h> |
||||
#include <time.h> |
||||
|
||||
#include <epoxy/gl.h> |
||||
|
||||
#include <sys/mman.h> |
||||
#include <sys/stat.h> |
||||
#include <fcntl.h> |
||||
#include <errno.h> |
||||
#include <unistd.h> |
||||
#include <sys/socket.h> |
||||
#include <sys/un.h> |
||||
#include <sys/eventfd.h> |
||||
#include "pipe/p_state.h" |
||||
#include "util/u_format.h" |
||||
#include "util/u_math.h" |
||||
#include "vrend_renderer.h" |
||||
|
||||
#include "virglrenderer.h" |
||||
#include "virgl_egl.h" |
||||
/* new API - just wrap internal API for now */ |
||||
|
||||
int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs) |
||||
{ |
||||
return vrend_renderer_resource_create((struct vrend_renderer_resource_create_args *)args, iov, num_iovs); |
||||
} |
||||
|
||||
void virgl_renderer_resource_unref(uint32_t res_handle) |
||||
{ |
||||
vrend_renderer_resource_unref(res_handle); |
||||
} |
||||
|
||||
void virgl_renderer_fill_caps(uint32_t set, uint32_t version, |
||||
void *caps) |
||||
{ |
||||
vrend_renderer_fill_caps(set, version, (union virgl_caps *)caps); |
||||
} |
||||
|
||||
int virgl_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name) |
||||
{ |
||||
vrend_renderer_context_create(handle, nlen, name); |
||||
return 0; |
||||
} |
||||
|
||||
void virgl_renderer_context_destroy(uint32_t handle) |
||||
{ |
||||
vrend_renderer_context_destroy(handle); |
||||
} |
||||
|
||||
void virgl_renderer_submit_cmd(void *buffer, |
||||
int ctx_id, |
||||
int ndw) |
||||
{ |
||||
vrend_decode_block(ctx_id, buffer, ndw); |
||||
} |
||||
|
||||
void virgl_renderer_transfer_write_iov(uint32_t handle,
|
||||
uint32_t ctx_id, |
||||
int level, |
||||
uint32_t stride, |
||||
uint32_t layer_stride, |
||||
struct virgl_box *box, |
||||
uint64_t offset, |
||||
struct iovec *iovec, |
||||
unsigned int iovec_cnt) |
||||
{ |
||||
vrend_renderer_transfer_write_iov(handle, ctx_id, level, |
||||
stride, layer_stride, (struct pipe_box *)box, |
||||
offset, iovec, iovec_cnt); |
||||
} |
||||
|
||||
void virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id, |
||||
uint32_t level, uint32_t stride, |
||||
uint32_t layer_stride, |
||||
struct virgl_box *box, |
||||
uint64_t offset, struct iovec *iov, |
||||
int iovec_cnt) |
||||
{ |
||||
vrend_renderer_transfer_send_iov(handle, ctx_id, level, stride, |
||||
layer_stride, (struct pipe_box *)box, |
||||
offset, iov, iovec_cnt); |
||||
} |
||||
|
||||
int virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov, |
||||
int num_iovs) |
||||
{ |
||||
return vrend_renderer_resource_attach_iov(res_handle, iov, num_iovs); |
||||
} |
||||
|
||||
void virgl_renderer_resource_detach_iov(int res_handle, struct iovec **iov_p, int *num_iovs_p) |
||||
{ |
||||
return vrend_renderer_resource_detach_iov(res_handle, iov_p, num_iovs_p); |
||||
} |
||||
|
||||
int virgl_renderer_create_fence(int client_fence_id, uint32_t ctx_id) |
||||
{ |
||||
return vrend_renderer_create_fence(client_fence_id, ctx_id); |
||||
} |
||||
|
||||
void virgl_renderer_force_ctx_0(void) |
||||
{ |
||||
vrend_renderer_force_ctx_0(); |
||||
} |
||||
|
||||
void virgl_renderer_ctx_attach_resource(int ctx_id, int res_handle) |
||||
{ |
||||
vrend_renderer_attach_res_ctx(ctx_id, res_handle); |
||||
} |
||||
|
||||
void virgl_renderer_ctx_detach_resource(int ctx_id, int res_handle) |
||||
{ |
||||
vrend_renderer_detach_res_ctx(ctx_id, res_handle); |
||||
} |
||||
|
||||
int virgl_renderer_resource_get_info(int res_handle, |
||||
struct virgl_renderer_resource_info *info) |
||||
{ |
||||
int ret; |
||||
ret = vrend_renderer_resource_get_info(res_handle, (struct vrend_renderer_resource_info *)info); |
||||
info->format = virgl_egl_get_gbm_format(info->format); |
||||
return ret;
|
||||
} |
||||
|
||||
void virgl_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver, |
||||
uint32_t *max_size) |
||||
{ |
||||
vrend_renderer_get_cap_set(cap_set, max_ver, max_size); |
||||
} |
||||
|
||||
void virgl_renderer_get_rect(int resource_id, struct iovec *iov, unsigned int num_iovs, |
||||
uint32_t offset, int x, int y, int width, int height) |
||||
{ |
||||
vrend_renderer_get_rect(resource_id, iov, num_iovs, offset, x, y, width, height); |
||||
} |
||||
|
||||
|
||||
static struct virgl_renderer_callbacks *rcbs; |
||||
|
||||
static void *dev_cookie; |
||||
static int use_egl_context; |
||||
struct virgl_egl *egl_info; |
||||
static struct vrend_if_cbs virgl_cbs; |
||||
|
||||
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
||||
struct iovec *iov, int num_iovs) |
||||
{ |
||||
vrend_write_to_iovec(iov, num_iovs, offset, data, bytes); |
||||
} |
||||
|
||||
void vrend_transfer_write_tex_return(struct pipe_resource *res, |
||||
struct pipe_box *box, |
||||
uint32_t level, |
||||
uint32_t dst_stride, |
||||
uint64_t offset, |
||||
struct iovec *iov, |
||||
int num_iovs, |
||||
void *myptr, int size, int invert) |
||||
{ |
||||
int elsize = util_format_get_blocksize(res->format); |
||||
int h; |
||||
uint32_t myoffset = offset; |
||||
uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * elsize; |
||||
// uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, box->width) * elsize;
|
||||
|
||||
if (!invert && (stride == util_format_get_nblocksx(res->format, box->width) * elsize)) |
||||
vrend_write_to_iovec(iov, num_iovs, offset, myptr, size); |
||||
else if (invert) { |
||||
for (h = box->height - 1; h >= 0; h--) { |
||||
void *sptr = myptr + (h * elsize * box->width); |
||||
vrend_write_to_iovec(iov, num_iovs, myoffset, sptr, box->width * elsize); |
||||
myoffset += stride; |
||||
} |
||||
} else { |
||||
for (h = 0; h < box->height; h++) { |
||||
void *sptr = myptr + (h * elsize * box->width); |
||||
vrend_write_to_iovec(iov, num_iovs, myoffset, sptr, box->width * elsize); |
||||
myoffset += stride; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void virgl_write_fence(uint32_t fence_id) |
||||
{ |
||||
rcbs->write_fence(dev_cookie, fence_id);
|
||||
} |
||||
|
||||
static virgl_renderer_gl_context create_gl_context(int scanout_idx, struct virgl_gl_ctx_param *param) |
||||
{ |
||||
struct virgl_renderer_gl_ctx_param vparam; |
||||
if (use_egl_context) |
||||
return virgl_egl_create_context(egl_info, param); |
||||
vparam.version = 1; |
||||
vparam.shared = param->shared; |
||||
vparam.major_ver = param->major_ver; |
||||
vparam.minor_ver = param->minor_ver; |
||||
return rcbs->create_gl_context(dev_cookie, scanout_idx, &vparam); |
||||
} |
||||
|
||||
static void destroy_gl_context(virgl_renderer_gl_context ctx) |
||||
{ |
||||
if (use_egl_context) |
||||
return virgl_egl_destroy_context(egl_info, ctx); |
||||
return rcbs->destroy_gl_context(dev_cookie, ctx); |
||||
} |
||||
|
||||
static int make_current(int scanout_idx, virgl_renderer_gl_context ctx) |
||||
{ |
||||
if (use_egl_context) |
||||
return virgl_egl_make_context_current(egl_info, ctx); |
||||
return rcbs->make_current(dev_cookie, scanout_idx, ctx); |
||||
} |
||||
|
||||
static struct vrend_if_cbs virgl_cbs = { |
||||
virgl_write_fence, |
||||
create_gl_context, |
||||
destroy_gl_context, |
||||
make_current, |
||||
}; |
||||
|
||||
void *virgl_renderer_get_cursor_data(uint32_t resource_id, uint32_t *width, uint32_t *height) |
||||
{ |
||||
return vrend_renderer_get_cursor_contents(resource_id, width, height); |
||||
} |
||||
|
||||
void virgl_renderer_poll(void) |
||||
{ |
||||
virgl_renderer_force_ctx_0(); |
||||
vrend_renderer_check_queries(); |
||||
vrend_renderer_check_fences(); |
||||
} |
||||
|
||||
int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cbs) |
||||
{ |
||||
dev_cookie = cookie; |
||||
rcbs = cbs; |
||||
|
||||
if (flags & VIRGL_RENDERER_USE_EGL) { |
||||
egl_info = virgl_egl_init(); |
||||
if (!egl_info) |
||||
return -1; |
||||
use_egl_context = 1; |
||||
} |
||||
|
||||
if (cbs->version != 1) |
||||
return -1; |
||||
vrend_renderer_init(&virgl_cbs); |
||||
return 0; |
||||
} |
||||
|
||||
int virgl_renderer_get_fd_for_texture(uint32_t tex_id, int *fd) |
||||
{ |
||||
return virgl_egl_get_fd_for_texture(egl_info, tex_id, fd); |
||||
} |
||||
|
||||
void virgl_renderer_reset(void) |
||||
{ |
||||
vrend_renderer_reset(); |
||||
} |
@ -0,0 +1,563 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* Copyright (C) 2014 Red Hat Inc. |
||||
* |
||||
* 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 |
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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. |
||||
* |
||||
**************************************************************************/ |
||||
|
||||
/* gallium blitter implementation in GL */ |
||||
/* for when we can't use glBlitFramebuffer */ |
||||
#include <epoxy/gl.h> |
||||
|
||||
#include <stdio.h> |
||||
#include "pipe/p_shader_tokens.h" |
||||
|
||||
#include "pipe/p_context.h" |
||||
#include "pipe/p_defines.h" |
||||
#include "pipe/p_screen.h" |
||||
#include "pipe/p_state.h" |
||||
#include "util/u_inlines.h" |
||||
#include "util/u_memory.h" |
||||
#include "util/u_dual_blend.h" |
||||
|
||||
#include "util/u_double_list.h" |
||||
#include "util/u_format.h" |
||||
#include "util/u_texture.h" |
||||
#include "tgsi/tgsi_parse.h" |
||||
|
||||
#include "vrend_object.h" |
||||
#include "vrend_shader.h" |
||||
|
||||
#include "vrend_renderer.h" |
||||
|
||||
#include "vrend_blitter.h" |
||||
|
||||
struct vrend_blitter_ctx { |
||||
virgl_gl_context gl_context; |
||||
bool initialised; |
||||
|
||||
GLuint vaoid; |
||||
|
||||
GLuint vs; |
||||
GLuint vs_pos_only; |
||||
GLuint fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; |
||||
GLuint fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES]; |
||||
GLuint fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; |
||||
GLuint fb_id; |
||||
|
||||
unsigned dst_width; |
||||
unsigned dst_height; |
||||
|
||||
GLuint vbo_id; |
||||
GLfloat vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ |
||||
}; |
||||
|
||||
static struct vrend_blitter_ctx vrend_blit_ctx; |
||||
|
||||
static bool build_and_check(GLuint id, const char *buf) |
||||
{ |
||||
GLint param; |
||||
glShaderSource(id, 1, (const char **)&buf, NULL); |
||||
glCompileShader(id); |
||||
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, ¶m); |
||||
if (param == GL_FALSE) { |
||||
char infolog[65536]; |
||||
int len; |
||||
glGetShaderInfoLog(id, 65536, &len, infolog); |
||||
fprintf(stderr,"shader failed to compile\n%s\n", infolog); |
||||
fprintf(stderr,"GLSL:\n%s\n", buf); |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static bool blit_build_vs_passthrough(struct vrend_blitter_ctx *blit_ctx) |
||||
{ |
||||
blit_ctx->vs = glCreateShader(GL_VERTEX_SHADER); |
||||
|
||||
if (!build_and_check(blit_ctx->vs, vs_passthrough)) { |
||||
glDeleteShader(blit_ctx->vs); |
||||
blit_ctx->vs = 0; |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) |
||||
{ |
||||
GLuint fs_id; |
||||
char shader_buf[4096]; |
||||
int is_shad; |
||||
const char *twm; |
||||
|
||||
switch (tgsi_tex_target) { |
||||
case TGSI_TEXTURE_1D: |
||||
case TGSI_TEXTURE_BUFFER: |
||||
twm = ".x"; |
||||
break; |
||||
case TGSI_TEXTURE_1D_ARRAY: |
||||
case TGSI_TEXTURE_2D: |
||||
case TGSI_TEXTURE_RECT: |
||||
case TGSI_TEXTURE_2D_MSAA: |
||||
default: |
||||
twm = ".xy"; |
||||
break; |
||||
case TGSI_TEXTURE_SHADOW1D: |
||||
case TGSI_TEXTURE_SHADOW2D: |
||||
case TGSI_TEXTURE_SHADOW1D_ARRAY: |
||||
case TGSI_TEXTURE_SHADOWRECT: |
||||
case TGSI_TEXTURE_3D: |
||||
case TGSI_TEXTURE_CUBE: |
||||
case TGSI_TEXTURE_2D_ARRAY: |
||||
case TGSI_TEXTURE_2D_ARRAY_MSAA: |
||||
twm = ".xyz"; |
||||
break; |
||||
case TGSI_TEXTURE_SHADOWCUBE: |
||||
case TGSI_TEXTURE_SHADOW2D_ARRAY: |
||||
case TGSI_TEXTURE_SHADOWCUBE_ARRAY: |
||||
case TGSI_TEXTURE_CUBE_ARRAY: |
||||
twm = ""; |
||||
break; |
||||
} |
||||
|
||||
snprintf(shader_buf, 4096, fs_texfetch_col, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm, ""); |
||||
|
||||
fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||
|
||||
if (!build_and_check(fs_id, shader_buf)) { |
||||
glDeleteShader(fs_id); |
||||
return 0; |
||||
} |
||||
|
||||
return fs_id; |
||||
} |
||||
|
||||
static GLuint blit_build_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) |
||||
{ |
||||
GLuint fs_id; |
||||
char shader_buf[4096]; |
||||
int is_shad; |
||||
const char *twm; |
||||
|
||||
switch (tgsi_tex_target) { |
||||
case TGSI_TEXTURE_1D: |
||||
case TGSI_TEXTURE_BUFFER: |
||||
twm = ".x"; |
||||
break; |
||||
case TGSI_TEXTURE_1D_ARRAY: |
||||
case TGSI_TEXTURE_2D: |
||||
case TGSI_TEXTURE_RECT: |
||||
case TGSI_TEXTURE_2D_MSAA: |
||||
default: |
||||
twm = ".xy"; |
||||
break; |
||||
case TGSI_TEXTURE_SHADOW1D: |
||||
case TGSI_TEXTURE_SHADOW2D: |
||||
case TGSI_TEXTURE_SHADOW1D_ARRAY: |
||||
case TGSI_TEXTURE_SHADOWRECT: |
||||
case TGSI_TEXTURE_3D: |
||||
case TGSI_TEXTURE_CUBE: |
||||
case TGSI_TEXTURE_2D_ARRAY: |
||||
case TGSI_TEXTURE_2D_ARRAY_MSAA: |
||||
twm = ".xyz"; |
||||
break; |
||||
case TGSI_TEXTURE_SHADOWCUBE: |
||||
case TGSI_TEXTURE_SHADOW2D_ARRAY: |
||||
case TGSI_TEXTURE_SHADOWCUBE_ARRAY: |
||||
case TGSI_TEXTURE_CUBE_ARRAY: |
||||
twm = ""; |
||||
break; |
||||
} |
||||
|
||||
snprintf(shader_buf, 4096, fs_texfetch_ds, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm); |
||||
|
||||
fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||
|
||||
if (!build_and_check(fs_id, shader_buf)) { |
||||
glDeleteShader(fs_id); |
||||
return 0; |
||||
} |
||||
|
||||
return fs_id; |
||||
} |
||||
|
||||
static GLuint blit_build_frag_blit_msaa_depth(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) |
||||
{ |
||||
GLuint fs_id; |
||||
char shader_buf[4096]; |
||||
int is_shad; |
||||
const char *twm; |
||||
|
||||
switch (tgsi_tex_target) { |
||||
case TGSI_TEXTURE_2D_MSAA: |
||||
twm = ".xy"; |
||||
break; |
||||
case TGSI_TEXTURE_2D_ARRAY_MSAA: |
||||
twm = ".xyz"; |
||||
break; |
||||
default: |
||||
return 0; |
||||
} |
||||
|
||||
snprintf(shader_buf, 4096, fs_texfetch_ds_msaa, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm); |
||||
|
||||
fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||
|
||||
if (!build_and_check(fs_id, shader_buf)) { |
||||
glDeleteShader(fs_id); |
||||
return 0; |
||||
} |
||||
|
||||
return fs_id; |
||||
} |
||||
|
||||
static GLuint blit_get_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples) |
||||
{ |
||||
assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES); |
||||
|
||||
if (nr_samples > 1) { |
||||
GLuint *shader = &blit_ctx->fs_texfetch_depth_msaa[pipe_tex_target]; |
||||
|
||||
if (!*shader) { |
||||
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, nr_samples); |
||||
|
||||
*shader = blit_build_frag_blit_msaa_depth(blit_ctx, tgsi_tex); |
||||
} |
||||
return *shader; |
||||
|
||||
} else { |
||||
GLuint *shader = &blit_ctx->fs_texfetch_depth[pipe_tex_target]; |
||||
|
||||
if (!*shader) { |
||||
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, 0); |
||||
|
||||
*shader = blit_build_frag_tex_writedepth(blit_ctx, tgsi_tex); |
||||
} |
||||
return *shader; |
||||
} |
||||
} |
||||
|
||||
static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples) |
||||
{ |
||||
assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES); |
||||
|
||||
if (nr_samples > 1) { |
||||
return 0; |
||||
} else { |
||||
GLuint *shader = &blit_ctx->fs_texfetch_col[pipe_tex_target]; |
||||
|
||||
if (!*shader) { |
||||
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, 0); |
||||
|
||||
*shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex); |
||||
} |
||||
return *shader; |
||||
} |
||||
} |
||||
|
||||
static void vrend_renderer_init_blit_ctx(struct vrend_blitter_ctx *blit_ctx) |
||||
{ |
||||
struct virgl_gl_ctx_param ctx_params; |
||||
int i; |
||||
if (blit_ctx->initialised) { |
||||
vrend_clicbs->make_current(0, blit_ctx->gl_context); |
||||
return; |
||||
} |
||||
|
||||
ctx_params.shared = true; |
||||
ctx_params.major_ver = VREND_GL_VER_MAJOR; |
||||
ctx_params.minor_ver = VREND_GL_VER_MINOR; |
||||
blit_ctx->gl_context = vrend_clicbs->create_gl_context(0, &ctx_params); |
||||
|
||||
vrend_clicbs->make_current(0, blit_ctx->gl_context); |
||||
glGenVertexArrays(1, &blit_ctx->vaoid); |
||||
glGenFramebuffers(1, &blit_ctx->fb_id); |
||||
|
||||
glGenBuffers(1, &blit_ctx->vbo_id); |
||||
blit_build_vs_passthrough(blit_ctx); |
||||
|
||||
for (i = 0; i < 4; i++) |
||||
blit_ctx->vertices[i][0][3] = 1; /*v.w*/ |
||||
glBindVertexArray(blit_ctx->vaoid); |
||||
glBindBuffer(GL_ARRAY_BUFFER, blit_ctx->vbo_id); |
||||
} |
||||
|
||||
static inline GLenum convert_mag_filter(unsigned int filter) |
||||
{ |
||||
if (filter == PIPE_TEX_FILTER_NEAREST) |
||||
return GL_NEAREST; |
||||
return GL_LINEAR; |
||||
} |
||||
|
||||
static void blitter_set_dst_dim(struct vrend_blitter_ctx *blit_ctx, |
||||
unsigned width, unsigned height) |
||||
{ |
||||
blit_ctx->dst_width = width; |
||||
blit_ctx->dst_height = height; |
||||
} |
||||
|
||||
static void blitter_set_rectangle(struct vrend_blitter_ctx *blit_ctx, |
||||
int x1, int y1, int x2, int y2, |
||||
float depth) |
||||
{ |
||||
int i; |
||||
|
||||
/* set vertex positions */ |
||||
blit_ctx->vertices[0][0][0] = (float)x1 / blit_ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ |
||||
blit_ctx->vertices[0][0][1] = (float)y1 / blit_ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ |
||||
|
||||
blit_ctx->vertices[1][0][0] = (float)x2 / blit_ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ |
||||
blit_ctx->vertices[1][0][1] = (float)y1 / blit_ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ |
||||
|
||||
blit_ctx->vertices[2][0][0] = (float)x2 / blit_ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ |
||||
blit_ctx->vertices[2][0][1] = (float)y2 / blit_ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ |
||||
|
||||
blit_ctx->vertices[3][0][0] = (float)x1 / blit_ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ |
||||
blit_ctx->vertices[3][0][1] = (float)y2 / blit_ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ |
||||
|
||||
for (i = 0; i < 4; i++) |
||||
blit_ctx->vertices[i][0][2] = depth; /*z*/ |
||||
|
||||
glViewport(0, 0, blit_ctx->dst_width, blit_ctx->dst_height); |
||||
} |
||||
|
||||
static void get_texcoords(struct vrend_resource *src_res, |
||||
int src_level, |
||||
int x1, int y1, int x2, int y2, |
||||
float out[4]) |
||||
{ |
||||
boolean normalized = src_res->base.target != PIPE_TEXTURE_RECT && |
||||
src_res->base.nr_samples <= 1; |
||||
|
||||
if (normalized) { |
||||
out[0] = x1 / (float)u_minify(src_res->base.width0, src_level); |
||||
out[1] = y1 / (float)u_minify(src_res->base.height0, src_level); |
||||
out[2] = x2 / (float)u_minify(src_res->base.width0, src_level); |
||||
out[3] = y2 / (float)u_minify(src_res->base.height0, src_level); |
||||
} else { |
||||
out[0] = (float) x1; |
||||
out[1] = (float) y1; |
||||
out[2] = (float) x2; |
||||
out[3] = (float) y2; |
||||
} |
||||
} |
||||
static void set_texcoords_in_vertices(const float coord[4], |
||||
float *out, unsigned stride) |
||||
{ |
||||
out[0] = coord[0]; /*t0.s*/ |
||||
out[1] = coord[1]; /*t0.t*/ |
||||
out += stride; |
||||
out[0] = coord[2]; /*t1.s*/ |
||||
out[1] = coord[1]; /*t1.t*/ |
||||
out += stride; |
||||
out[0] = coord[2]; /*t2.s*/ |
||||
out[1] = coord[3]; /*t2.t*/ |
||||
out += stride; |
||||
out[0] = coord[0]; /*t3.s*/ |
||||
out[1] = coord[3]; /*t3.t*/ |
||||
} |
||||
|
||||
static void blitter_set_texcoords(struct vrend_blitter_ctx *blit_ctx, |
||||
struct vrend_resource *src_res, |
||||
int level, |
||||
float layer, unsigned sample, |
||||
int x1, int y1, int x2, int y2) |
||||
{ |
||||
float coord[4]; |
||||
float face_coord[4][2]; |
||||
int i; |
||||
get_texcoords(src_res, level, x1, y1, x2, y2, coord); |
||||
|
||||
if (src_res->base.target == PIPE_TEXTURE_CUBE || |
||||
src_res->base.target == PIPE_TEXTURE_CUBE_ARRAY) { |
||||
set_texcoords_in_vertices(coord, &face_coord[0][0], 2); |
||||
util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, |
||||
/* pointer, stride in floats */ |
||||
&face_coord[0][0], 2, |
||||
&blit_ctx->vertices[0][1][0], 8, |
||||
FALSE); |
||||
} else { |
||||
set_texcoords_in_vertices(coord, &blit_ctx->vertices[0][1][0], 8); |
||||
} |
||||
|
||||
switch (src_res->base.target) { |
||||
case PIPE_TEXTURE_3D: |
||||
{ |
||||
float r = layer / (float)u_minify(src_res->base.depth0, |
||||
level); |
||||
for (i = 0; i < 4; i++) |
||||
blit_ctx->vertices[i][1][2] = r; /*r*/ |
||||
} |
||||
break; |
||||
|
||||
case PIPE_TEXTURE_1D_ARRAY: |
||||
for (i = 0; i < 4; i++) |
||||
blit_ctx->vertices[i][1][1] = (float) layer; /*t*/ |
||||
break; |
||||
|
||||
case PIPE_TEXTURE_2D_ARRAY: |
||||
for (i = 0; i < 4; i++) { |
||||
blit_ctx->vertices[i][1][2] = (float) layer; /*r*/ |
||||
blit_ctx->vertices[i][1][3] = (float) sample; /*q*/ |
||||
} |
||||
break; |
||||
case PIPE_TEXTURE_CUBE_ARRAY: |
||||
for (i = 0; i < 4; i++) |
||||
blit_ctx->vertices[i][1][3] = (float) ((unsigned)layer / 6); /*w*/ |
||||
break; |
||||
case PIPE_TEXTURE_2D: |
||||
for (i = 0; i < 4; i++) { |
||||
blit_ctx->vertices[i][1][3] = (float) sample; /*r*/ |
||||
} |
||||
break; |
||||
default:; |
||||
} |
||||
} |
||||
#if 0 |
||||
static void set_dsa_keep_depth_stencil(void) |
||||
{ |
||||
glDisable(GL_STENCIL_TEST); |
||||
glDisable(GL_DEPTH_TEST); |
||||
glDepthMask(GL_FALSE); |
||||
} |
||||
#endif |
||||
|
||||
static void set_dsa_write_depth_keep_stencil(void) |
||||
{ |
||||
glDisable(GL_STENCIL_TEST); |
||||
glEnable(GL_DEPTH_TEST); |
||||
glDepthFunc(GL_ALWAYS); |
||||
glDepthMask(GL_TRUE); |
||||
} |
||||
|
||||
/* implement blitting using OpenGL. */ |
||||
void vrend_renderer_blit_gl(struct vrend_context *ctx, |
||||
struct vrend_resource *src_res, |
||||
struct vrend_resource *dst_res, |
||||
const struct pipe_blit_info *info) |
||||
{ |
||||
struct vrend_blitter_ctx *blit_ctx = &vrend_blit_ctx; |
||||
GLuint prog_id; |
||||
GLuint fs_id; |
||||
GLint lret; |
||||
GLenum filter; |
||||
GLuint pos_loc, tc_loc; |
||||
GLuint samp_loc; |
||||
boolean has_depth, has_stencil; |
||||
bool blit_stencil, blit_depth; |
||||
int dst_z; |
||||
const struct util_format_description *src_desc = |
||||
util_format_description(src_res->base.format); |
||||
const struct util_format_description *dst_desc = |
||||
util_format_description(dst_res->base.format); |
||||
|
||||
has_depth = util_format_has_depth(src_desc) && |
||||
util_format_has_depth(dst_desc); |
||||
has_stencil = util_format_has_stencil(src_desc) && |
||||
util_format_has_stencil(dst_desc); |
||||
|
||||
blit_depth = has_depth && (info->mask & PIPE_MASK_Z); |
||||
blit_stencil = has_stencil && (info->mask & PIPE_MASK_S) & 0; |
||||
|
||||
filter = convert_mag_filter(info->filter); |
||||
vrend_renderer_init_blit_ctx(blit_ctx); |
||||
|
||||
blitter_set_dst_dim(blit_ctx, |
||||
u_minify(dst_res->base.width0, info->dst.level), |
||||
u_minify(dst_res->base.height0, info->dst.level)); |
||||
|
||||
blitter_set_rectangle(blit_ctx, info->dst.box.x, info->dst.box.y, |
||||
info->dst.box.x + info->dst.box.width, |
||||
info->dst.box.y + info->dst.box.height, 0); |
||||
|
||||
|
||||
prog_id = glCreateProgram(); |
||||
glAttachShader(prog_id, blit_ctx->vs); |
||||
|
||||
if (blit_depth || blit_stencil) |
||||
fs_id = blit_get_frag_tex_writedepth(blit_ctx, src_res->base.target, src_res->base.nr_samples); |
||||
else |
||||
fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target, src_res->base.nr_samples); |
||||
glAttachShader(prog_id, fs_id); |
||||
|
||||
glLinkProgram(prog_id); |
||||
glGetProgramiv(prog_id, GL_LINK_STATUS, &lret); |
||||
if (lret == GL_FALSE) { |
||||
char infolog[65536]; |
||||
int len; |
||||
glGetProgramInfoLog(prog_id, 65536, &len, infolog); |
||||
fprintf(stderr,"got error linking\n%s\n", infolog); |
||||
/* dump shaders */ |
||||
glDeleteProgram(prog_id); |
||||
return; |
||||
} |
||||
|
||||
glUseProgram(prog_id); |
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, blit_ctx->fb_id); |
||||
vrend_fb_bind_texture(dst_res, 0, info->dst.level, info->dst.box.z); |
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); |
||||
|
||||
glBindTexture(src_res->target, src_res->id); |
||||
|
||||
glTexParameteri(src_res->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
||||
glTexParameteri(src_res->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
||||
glTexParameteri(src_res->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); |
||||
|
||||
glTexParameteri(src_res->target, GL_TEXTURE_BASE_LEVEL, info->src.level); |
||||
glTexParameteri(src_res->target, GL_TEXTURE_MAX_LEVEL, info->src.level); |
||||
glTexParameterf(src_res->target, GL_TEXTURE_MAG_FILTER, filter); |
||||
glTexParameterf(src_res->target, GL_TEXTURE_MIN_FILTER, filter); |
||||
pos_loc = glGetAttribLocation(prog_id, "arg0"); |
||||
tc_loc = glGetAttribLocation(prog_id, "arg1"); |
||||
samp_loc = glGetUniformLocation(prog_id, "samp"); |
||||
|
||||
glUniform1i(samp_loc, 0); |
||||
|
||||
glVertexAttribPointer(pos_loc, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); |
||||
glVertexAttribPointer(tc_loc, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(4 * sizeof(float))); |
||||
|
||||
glEnableVertexAttribArray(pos_loc); |
||||
glEnableVertexAttribArray(tc_loc); |
||||
|
||||
set_dsa_write_depth_keep_stencil(); |
||||
|
||||
for (dst_z = 0; dst_z < info->dst.box.depth; dst_z++) { |
||||
float dst2src_scale = info->src.box.depth / (float)info->dst.box.depth; |
||||
float dst_offset = ((info->src.box.depth - 1) - |
||||
(info->dst.box.depth - 1) * dst2src_scale) * 0.5; |
||||
float src_z = (dst_z + dst_offset) * dst2src_scale; |
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, blit_ctx->fb_id); |
||||
vrend_fb_bind_texture(dst_res, 0, info->dst.level, dst_z); |
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); |
||||
blitter_set_texcoords(blit_ctx, src_res, info->src.level, |
||||
info->src.box.z + src_z, 0, |
||||
info->src.box.x, info->src.box.y, |
||||
info->src.box.x + info->src.box.width, |
||||
info->src.box.y + info->src.box.height); |
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(blit_ctx->vertices), blit_ctx->vertices, GL_STATIC_DRAW); |
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
||||
} |
||||
} |
@ -0,0 +1,45 @@ |
||||
#ifndef VREND_BLITTER |
||||
#define VREND_BLITTER |
||||
|
||||
/* shaders for blitting */ |
||||
|
||||
static const char *vs_passthrough = { |
||||
"#version 130\n" |
||||
"in vec4 arg0;\n" |
||||
"in vec4 arg1;\n" |
||||
"out vec4 tc;\n" |
||||
"void main() {\n" |
||||
" gl_Position = arg0;\n" |
||||
" tc = arg1;\n" |
||||
"}\n" |
||||
}; |
||||
|
||||
static const char *fs_texfetch_col = { |
||||
"#version 130\n" |
||||
"uniform sampler%s samp;\n" |
||||
"in vec4 tc;\n" |
||||
"void main() {\n" |
||||
" gl_FragColor = texture(samp, tc%s)%s;\n" |
||||
"}\n" |
||||
}; |
||||
|
||||
static const char *fs_texfetch_ds = { |
||||
"#version 130\n" |
||||
"uniform sampler%s samp;\n" |
||||
"in vec4 tc;\n" |
||||
"void main() {\n" |
||||
" gl_FragDepth = float(texture(samp, tc%s).x);\n" |
||||
"}\n" |
||||
}; |
||||
|
||||
static const char *fs_texfetch_ds_msaa = { |
||||
"#version 130\n" |
||||
"#extension GL_ARB_texture_multisample : enable\n" |
||||
"uniform sampler%s samp;\n" |
||||
"in vec4 tc;\n" |
||||
"void main() {\n" |
||||
" gl_FragDepth = float(texelFetch(samp, tc%s, tc.z).x);\n" |
||||
"}\n" |
||||
}; |
||||
|
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* Copyright (C) 2014 Red Hat Inc. |
||||
* |
||||
* 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 |
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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 VREND_IOV_H |
||||
#define VREND_IOV_H |
||||
|
||||
#include <sys/uio.h> |
||||
|
||||
typedef void (*iov_cb)(void *cookie, unsigned int doff, void *src, int len); |
||||
|
||||
size_t vrend_get_iovec_size(const struct iovec *iov, int iovlen); |
||||
size_t vrend_read_from_iovec(const struct iovec *iov, int iov_cnt, |
||||
size_t offset, char *buf, size_t bytes); |
||||
size_t vrend_write_to_iovec(const struct iovec *iov, int iov_cnt, |
||||
size_t offset, const char *buf, size_t bytes); |
||||
|
||||
size_t vrend_read_from_iovec_cb(const struct iovec *iov, int iov_cnt, |
||||
size_t offset, size_t bytes, iov_cb iocb, void *cookie); |
||||
|
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,391 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* Copyright (C) 2014 Red Hat Inc. |
||||
* |
||||
* 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 |
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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 VREND_RENDERER_H |
||||
#define VREND_RENDERER_H |
||||
|
||||
#include "pipe/p_state.h" |
||||
#include "util/u_inlines.h" |
||||
#include "virgl_protocol.h" |
||||
#include "vrend_iov.h" |
||||
#include "virgl_hw.h" |
||||
|
||||
typedef void *virgl_gl_context; |
||||
typedef void *virgl_gl_drawable; |
||||
|
||||
struct virgl_gl_ctx_param { |
||||
bool shared; |
||||
int major_ver; |
||||
int minor_ver; |
||||
}; |
||||
|
||||
extern int vrend_dump_shaders; |
||||
struct vrend_context; |
||||
|
||||
struct vrend_resource { |
||||
struct pipe_resource base; |
||||
GLuint id; |
||||
GLenum target; |
||||
/* fb id if we need to readback this resource */ |
||||
GLuint readback_fb_id; |
||||
GLuint readback_fb_level; |
||||
GLuint readback_fb_z; |
||||
void *ptr; |
||||
GLuint handle; |
||||
|
||||
struct iovec *iov; |
||||
uint32_t num_iovs; |
||||
boolean y_0_top; |
||||
|
||||
boolean scannedout; |
||||
GLuint tbo_tex_id;/* tbos have two ids to track */ |
||||
}; |
||||
|
||||
/* assume every format is sampler friendly */ |
||||
#define VREND_BIND_SAMPLER (1 << 0) |
||||
#define VREND_BIND_RENDER (1 << 1) |
||||
#define VREND_BIND_DEPTHSTENCIL (1 << 2) |
||||
|
||||
#define VREND_BIND_NEED_SWIZZLE (1 << 28) |
||||
|
||||
struct vrend_format_table { |
||||
enum virgl_formats format; |
||||
GLenum internalformat; |
||||
GLenum glformat; |
||||
GLenum gltype; |
||||
uint32_t bindings; |
||||
int flags; |
||||
uint8_t swizzle[4]; |
||||
}; |
||||
|
||||
struct vrend_if_cbs { |
||||
void (*write_fence)(unsigned fence_id); |
||||
|
||||
virgl_gl_context (*create_gl_context)(int scanout, struct virgl_gl_ctx_param *params); |
||||
void (*destroy_gl_context)(virgl_gl_context ctx); |
||||
int (*make_current)(int scanout, virgl_gl_context ctx); |
||||
}; |
||||
void vrend_renderer_init(struct vrend_if_cbs *cbs); |
||||
|
||||
void vrend_insert_format(struct vrend_format_table *entry, uint32_t bindings); |
||||
void vrend_insert_format_swizzle(int override_format, struct vrend_format_table *entry, uint32_t bindings, uint8_t swizzle[4]); |
||||
int vrend_create_shader(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
const struct pipe_shader_state *vs, |
||||
int type); |
||||
|
||||
void vrend_bind_vs(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void vrend_bind_gs(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void vrend_bind_fs(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void vrend_bind_vs_so(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
void vrend_clear(struct vrend_context *ctx, |
||||
unsigned buffers, |
||||
const union pipe_color_union *color, |
||||
double depth, unsigned stencil); |
||||
|
||||
void vrend_draw_vbo(struct vrend_context *ctx, |
||||
const struct pipe_draw_info *info); |
||||
|
||||
void vrend_set_framebuffer_state(struct vrend_context *ctx, |
||||
uint32_t nr_cbufs, uint32_t surf_handle[8], |
||||
uint32_t zsurf_handle); |
||||
|
||||
void vrend_flush(struct vrend_context *ctx); |
||||
|
||||
|
||||
void vrend_flush_frontbuffer(uint32_t res_handle); |
||||
struct vrend_context *vrend_create_context(int id, uint32_t nlen, const char *debug_name); |
||||
bool vrend_destroy_context(struct vrend_context *ctx); |
||||
void vrend_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name); |
||||
void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen, const char *name); |
||||
void vrend_renderer_context_destroy(uint32_t handle); |
||||
|
||||
struct vrend_renderer_resource_create_args { |
||||
uint32_t handle; |
||||
enum pipe_texture_target target; |
||||
uint32_t format; |
||||
uint32_t bind; |
||||
uint32_t width; |
||||
uint32_t height; |
||||
uint32_t depth; |
||||
uint32_t array_size; |
||||
uint32_t last_level; |
||||
uint32_t nr_samples; |
||||
uint32_t flags; |
||||
}; |
||||
|
||||
int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs); |
||||
|
||||
void vrend_renderer_resource_unref(uint32_t handle); |
||||
|
||||
int vrend_create_surface(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
uint32_t res_handle, uint32_t format, |
||||
uint32_t val0, uint32_t val1); |
||||
int vrend_create_sampler_view(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
uint32_t res_handle, uint32_t format, |
||||
uint32_t val0, uint32_t val1, uint32_t swizzle_packed); |
||||
|
||||
int vrend_create_sampler_state(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
struct pipe_sampler_state *templ); |
||||
|
||||
int vrend_create_so_target(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
uint32_t res_handle, |
||||
uint32_t buffer_offset, |
||||
uint32_t buffer_size); |
||||
|
||||
void vrend_set_streamout_targets(struct vrend_context *ctx, |
||||
uint32_t append_bitmask, |
||||
uint32_t num_targets, |
||||
uint32_t *handles); |
||||
|
||||
int vrend_create_vertex_elements_state(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
unsigned num_elements, |
||||
const struct pipe_vertex_element *elements); |
||||
void vrend_bind_vertex_elements_state(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void vrend_set_single_vbo(struct vrend_context *ctx, |
||||
int index, |
||||
uint32_t stride, |
||||
uint32_t buffer_offset, |
||||
uint32_t res_handle); |
||||
void vrend_set_num_vbo(struct vrend_context *ctx, |
||||
int num_vbo); |
||||
|
||||
void vrend_transfer_inline_write(struct vrend_context *ctx, |
||||
uint32_t res_handle, |
||||
unsigned level, |
||||
unsigned usage, |
||||
const struct pipe_box *box, |
||||
const void *data, |
||||
unsigned stride, |
||||
unsigned layer_stride); |
||||
|
||||
void vrend_set_viewport_state(struct vrend_context *ctx, |
||||
const struct pipe_viewport_state *state); |
||||
void vrend_set_num_sampler_views(struct vrend_context *ctx, |
||||
uint32_t shader_type, |
||||
uint32_t start_slot, |
||||
int num_sampler_views); |
||||
void vrend_set_single_sampler_view(struct vrend_context *ctx, |
||||
uint32_t shader_type, |
||||
int index, |
||||
uint32_t res_handle); |
||||
|
||||
void vrend_object_bind_blend(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
void vrend_object_bind_dsa(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
void vrend_object_bind_rasterizer(struct vrend_context *ctx, |
||||
uint32_t handle); |
||||
|
||||
void vrend_bind_sampler_states(struct vrend_context *ctx, |
||||
uint32_t shader_type, |
||||
uint32_t start_slot, |
||||
uint32_t num_states, |
||||
uint32_t *handles); |
||||
void vrend_set_index_buffer(struct vrend_context *ctx, |
||||
uint32_t res_handle, |
||||
uint32_t index_size, |
||||
uint32_t offset); |
||||
|
||||
void vrend_renderer_transfer_write_iov(uint32_t handle,
|
||||
uint32_t ctx_id, |
||||
int level, |
||||
uint32_t stride, |
||||
uint32_t layer_stride, |
||||
struct pipe_box *box, |
||||
uint64_t offset, |
||||
struct iovec *iovec, |
||||
unsigned int iovec_cnt); |
||||
|
||||
void vrend_renderer_resource_copy_region(struct vrend_context *ctx, |
||||
uint32_t dst_handle, uint32_t dst_level, |
||||
uint32_t dstx, uint32_t dsty, uint32_t dstz, |
||||
uint32_t src_handle, uint32_t src_level, |
||||
const struct pipe_box *src_box); |
||||
|
||||
void vrend_renderer_blit(struct vrend_context *ctx, |
||||
uint32_t dst_handle, uint32_t src_handle, |
||||
const struct pipe_blit_info *info); |
||||
|
||||
void vrend_renderer_transfer_send_iov(uint32_t handle, uint32_t ctx_id, |
||||
uint32_t level, uint32_t stride, |
||||
uint32_t layer_stride, |
||||
struct pipe_box *box, |
||||
uint64_t offset, struct iovec *iov, |
||||
int iovec_cnt); |
||||
void vrend_set_stencil_ref(struct vrend_context *ctx, struct pipe_stencil_ref *ref); |
||||
void vrend_set_blend_color(struct vrend_context *ctx, struct pipe_blend_color *color); |
||||
void vrend_set_scissor_state(struct vrend_context *ctx, struct pipe_scissor_state *ss); |
||||
|
||||
void vrend_set_polygon_stipple(struct vrend_context *ctx, struct pipe_poly_stipple *ps); |
||||
|
||||
void vrend_set_clip_state(struct vrend_context *ctx, struct pipe_clip_state *ucp); |
||||
void vrend_set_sample_mask(struct vrend_context *ctx, unsigned sample_mask); |
||||
|
||||
void vrend_set_constants(struct vrend_context *ctx, |
||||
uint32_t shader, |
||||
uint32_t index, |
||||
uint32_t num_constant, |
||||
float *data); |
||||
|
||||
void vrend_set_uniform_buffer(struct vrend_context *ctx, uint32_t shader, |
||||
uint32_t index, uint32_t offset, uint32_t length, |
||||
uint32_t res_handle); |
||||
|
||||
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
||||
struct iovec *iov, int iovec_cnt); |
||||
|
||||
void vrend_transfer_write_tex_return(struct pipe_resource *res, |
||||
struct pipe_box *box, |
||||
uint32_t level, |
||||
uint32_t dst_stride, |
||||
uint64_t offset, |
||||
struct iovec *iov, |
||||
int num_iovs, |
||||
void *myptr, int size, int invert); |
||||
|
||||
void vrend_renderer_fini(void); |
||||
|
||||
void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw); |
||||
struct vrend_context *vrend_lookup_renderer_ctx(uint32_t ctx_id); |
||||
|
||||
int vrend_renderer_create_fence(int client_fence_id, uint32_t ctx_id); |
||||
|
||||
void vrend_renderer_check_fences(void); |
||||
void vrend_renderer_check_queries(void); |
||||
void vrend_stop_current_queries(void); |
||||
|
||||
boolean vrend_hw_switch_context(struct vrend_context *ctx, boolean now); |
||||
uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data, |
||||
uint32_t size, uint32_t handle, enum virgl_object_type type); |
||||
void vrend_renderer_object_destroy(struct vrend_context *ctx, uint32_t handle); |
||||
|
||||
int vrend_create_query(struct vrend_context *ctx, uint32_t handle, |
||||
uint32_t query_type, uint32_t res_handle, |
||||
uint32_t offset); |
||||
|
||||
void vrend_begin_query(struct vrend_context *ctx, uint32_t handle); |
||||
void vrend_end_query(struct vrend_context *ctx, uint32_t handle); |
||||
void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle, |
||||
uint32_t wait); |
||||
void vrend_render_condition(struct vrend_context *ctx, |
||||
uint32_t handle, |
||||
boolean condtion, |
||||
uint mode); |
||||
void *vrend_renderer_get_cursor_contents(uint32_t res_handle, uint32_t *width, uint32_t *height); |
||||
void vrend_use_program(GLuint program_id); |
||||
void vrend_blend_enable(GLboolean blend_enable); |
||||
void vrend_depth_test_enable(GLboolean depth_test_enable); |
||||
void vrend_bind_va(GLuint vaoid); |
||||
int vrend_renderer_flush_buffer_res(struct vrend_resource *res, |
||||
struct pipe_box *box); |
||||
|
||||
void vrend_renderer_fill_caps(uint32_t set, uint32_t version, |
||||
union virgl_caps *caps); |
||||
|
||||
GLint64 vrend_renderer_get_timestamp(void); |
||||
/* formats */ |
||||
void vrend_build_format_list(void); |
||||
|
||||
int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov, |
||||
int num_iovs); |
||||
void vrend_renderer_resource_detach_iov(int res_handle, |
||||
struct iovec **iov_p, |
||||
int *num_iovs_p); |
||||
void vrend_renderer_resource_destroy(struct vrend_resource *res); |
||||
|
||||
static INLINE void |
||||
vrend_resource_reference(struct vrend_resource **ptr, struct vrend_resource *tex) |
||||
{ |
||||
struct vrend_resource *old_tex = *ptr; |
||||
|
||||
if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference)) |
||||
vrend_renderer_resource_destroy(old_tex); |
||||
*ptr = tex; |
||||
} |
||||
|
||||
void vrend_renderer_force_ctx_0(void); |
||||
|
||||
void vrend_renderer_get_rect(int resource_id, struct iovec *iov, unsigned int num_iovs, |
||||
uint32_t offset, int x, int y, int width, int height); |
||||
void vrend_renderer_attach_res_ctx(int ctx_id, int resource_id); |
||||
void vrend_renderer_detach_res_ctx(int ctx_id, int resource_id); |
||||
|
||||
|
||||
struct vrend_renderer_resource_info { |
||||
uint32_t handle; |
||||
uint32_t format; |
||||
uint32_t width; |
||||
uint32_t height; |
||||
uint32_t depth; |
||||
uint32_t flags; |
||||
uint32_t tex_id; |
||||
uint32_t stride; |
||||
}; |
||||
|
||||
int vrend_renderer_resource_get_info(int res_handle, |
||||
struct vrend_renderer_resource_info *info); |
||||
|
||||
#define VREND_CAP_SET 1 |
||||
|
||||
void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver, |
||||
uint32_t *max_size); |
||||
|
||||
void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id); |
||||
void vrend_renderer_destroy_sub_ctx(struct vrend_context *ctx, int sub_ctx_id); |
||||
void vrend_renderer_set_sub_ctx(struct vrend_context *ctx, int sub_ctx_id); |
||||
void vrend_report_buffer_error(struct vrend_context *ctx, int cmd); |
||||
|
||||
void vrend_fb_bind_texture(struct vrend_resource *res, |
||||
int idx, |
||||
uint32_t level, uint32_t layer); |
||||
bool vrend_is_ds_format(enum virgl_formats format); |
||||
const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad); |
||||
/* blitter interface */ |
||||
void vrend_renderer_blit_gl(struct vrend_context *ctx, |
||||
struct vrend_resource *src_res, |
||||
struct vrend_resource *dst_res, |
||||
const struct pipe_blit_info *info); |
||||
|
||||
void vrend_renderer_reset(void); |
||||
void vrend_decode_reset(void); |
||||
#define VREND_GL_VER_MAJOR 3 |
||||
#define VREND_GL_VER_MINOR 1 |
||||
|
||||
extern struct vrend_if_cbs *vrend_clicbs; |
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,82 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* Copyright (C) 2014 Red Hat Inc. |
||||
* |
||||
* 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 |
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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 VREND_SHADER_H |
||||
#define VREND_SHADER_H |
||||
|
||||
#include "pipe/p_state.h" |
||||
|
||||
/* need to store patching info for interpolation */ |
||||
struct vrend_interp_info { |
||||
int semantic_name; |
||||
int semantic_index; |
||||
int interpolate; |
||||
}; |
||||
|
||||
struct vrend_shader_info { |
||||
uint32_t samplers_used_mask; |
||||
int num_consts; |
||||
int num_inputs; |
||||
int num_interps; |
||||
int num_outputs; |
||||
int num_ubos; |
||||
int num_ucp; |
||||
int glsl_ver; |
||||
uint32_t shadow_samp_mask; |
||||
struct pipe_stream_output_info so_info; |
||||
|
||||
struct vrend_interp_info *interpinfo; |
||||
int gs_out_prim; |
||||
char **so_names; |
||||
}; |
||||
|
||||
struct vrend_shader_key { |
||||
uint32_t coord_replace; |
||||
boolean invert_fs_origin; |
||||
boolean pstipple_tex; |
||||
boolean add_alpha_test; |
||||
boolean color_two_side; |
||||
uint8_t alpha_test; |
||||
uint8_t clip_plane_enable; |
||||
float alpha_ref_val; |
||||
boolean gs_present; |
||||
boolean flatshade; |
||||
}; |
||||
|
||||
struct vrend_shader_cfg { |
||||
int glsl_version; |
||||
bool use_core_profile; |
||||
}; |
||||
|
||||
boolean vrend_patch_vertex_shader_interpolants(char *program, |
||||
struct vrend_shader_info *vs_info, |
||||
struct vrend_shader_info *fs_info, |
||||
bool is_gs, bool flatshade); |
||||
|
||||
char *vrend_convert_shader(struct vrend_shader_cfg *cfg, |
||||
const struct tgsi_token *tokens, |
||||
struct vrend_shader_key *key, |
||||
struct vrend_shader_info *sinfo); |
||||
const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad); |
||||
#endif |
Loading…
Reference in new issue